* [5/5] powerpc: PA Semi PWRficient MAINTAINER entry
From: Olof Johansson @ 2006-09-05 17:30 UTC (permalink / raw)
To: paulus, anton; +Cc: linuxppc-dev
In-Reply-To: <20060904175742.5472a6fa@localhost.localdomain>
Maintainer entry for PWRficient
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: merge/MAINTAINERS
===================================================================
--- merge.orig/MAINTAINERS
+++ merge/MAINTAINERS
@@ -1777,6 +1777,13 @@ W: http://www.penguinppc.org/
L: linuxppc-embedded@ozlabs.org
S: Maintained
+LINUX FOR POWERPC PA SEMI PWRFICIENT
+P: Olof Johansson
+M: olof@lixom.net
+W: http://www.pasemi.com/
+L: linuxppc-dev@ozlabs.org
+S: Supported
+
LLC (802.2)
P: Arnaldo Carvalho de Melo
M: acme@conectiva.com.
^ permalink raw reply
* [4/5] powerpc: PA Semi PWRficient platform support
From: Olof Johansson @ 2006-09-05 17:29 UTC (permalink / raw)
To: paulus, anton; +Cc: linuxppc-dev
In-Reply-To: <20060904175742.5472a6fa@localhost.localdomain>
Base patch for PA6T and PA6T-1682M. This introduces the
arch/powerpc/platform/pasemi directory, together with basic
implementations for various setup.
Much of this was based on other platform code, i.e. Maple, etc.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: merge/arch/powerpc/Kconfig
===================================================================
--- merge.orig/arch/powerpc/Kconfig
+++ merge/arch/powerpc/Kconfig
@@ -413,6 +409,17 @@ config PPC_MAPLE
This option enables support for the Maple 970FX Evaluation Board.
For more informations, refer to <http://www.970eval.com>
+config PPC_PASEMI
+ depends on PPC_MULTIPLATFORM && PPC64
+ bool "PA Semi SoC-based platforms"
+ default n
+ select MPIC
+ select PPC_UDBG_16550
+ select GENERIC_TBSYNC
+ help
+ This option enables support for PA Semi's PWRficient line
+ of SoC processors, including PA6T-1682M
+
config PPC_CELL
bool
default n
Index: merge/arch/powerpc/platforms/Makefile
===================================================================
--- merge.orig/arch/powerpc/platforms/Makefile
+++ merge/arch/powerpc/platforms/Makefile
@@ -13,5 +13,6 @@ obj-$(CONFIG_PPC_86xx) += 86xx/
obj-$(CONFIG_PPC_PSERIES) += pseries/
obj-$(CONFIG_PPC_ISERIES) += iseries/
obj-$(CONFIG_PPC_MAPLE) += maple/
+obj-$(CONFIG_PPC_PASEMI) += pasemi/
obj-$(CONFIG_PPC_CELL) += cell/
obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
Index: merge/arch/powerpc/platforms/pasemi/Makefile
===================================================================
--- /dev/null
+++ merge/arch/powerpc/platforms/pasemi/Makefile
@@ -0,0 +1 @@
+obj-y += setup.o pci.o time.o
Index: merge/arch/powerpc/platforms/pasemi/pci.c
===================================================================
--- /dev/null
+++ merge/arch/powerpc/platforms/pasemi/pci.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2006 PA Semi, Inc
+ *
+ * Authors: Kip Walker, PA Semi
+ * Olof Johansson, PA Semi
+ *
+ * Maintained by: Olof Johansson <olof@lixom.net>
+ *
+ * Based on arch/powerpc/platforms/maple/pci.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/iommu.h>
+
+#include <asm/ppc-pci.h>
+#include <asm/udbg.h>
+
+#define PA_PXP_CFA(bus, devfn, off) (((bus) << 20) | ((devfn) << 12) | (off))
+
+static unsigned long pa_pxp_cfg_addr(struct pci_controller* hose,
+ u8 bus, u8 devfn, int offset)
+{
+ return ((unsigned long)hose->cfg_data) + PA_PXP_CFA(bus, devfn, offset);
+}
+
+static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 *val)
+{
+ struct pci_controller *hose;
+ unsigned long addr;
+
+ hose = pci_bus_to_host(bus);
+ if (!hose)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ *val = in_8((u8 *)addr);
+ break;
+ case 2:
+ *val = in_le16((u16 *)addr);
+ break;
+ default:
+ *val = in_le32((u32 *)addr);
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 val)
+{
+ struct pci_controller *hose;
+ unsigned long addr;
+
+ hose = pci_bus_to_host(bus);
+ if (!hose)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ out_8((u8 *)addr, val);
+ (void) in_8((u8 *)addr);
+ break;
+ case 2:
+ out_le16((u16 *)addr, val);
+ (void) in_le16((u16 *)addr);
+ break;
+ default:
+ out_le32((u32 *)addr, val);
+ (void) in_le32((u32 *)addr);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pa_pxp_ops =
+{
+ pa_pxp_read_config,
+ pa_pxp_write_config
+};
+
+static void __init setup_pa_pxp(struct pci_controller* hose)
+{
+ hose->ops = &pa_pxp_ops;
+ hose->cfg_data = ioremap(0xe0000000, 0x1000000);
+}
+
+static int __init add_bridge(struct device_node *dev)
+{
+ int len;
+ struct pci_controller *hose;
+ int *bus_range;
+ struct property *of_prop;
+
+ pr_debug("Adding PCI host bridge %s\n", dev->full_name);
+
+ bus_range = (int *) get_property(dev, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
+ dev->full_name);
+ }
+
+ hose = pcibios_alloc_controller(dev);
+ if (hose == NULL)
+ return -ENOMEM;
+
+ hose->first_busno = bus_range ? bus_range[0] : 0;
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+ of_prop = alloc_bootmem(sizeof(struct property) +
+ sizeof(hose->global_number));
+ if (of_prop) {
+ memset(of_prop, 0, sizeof(struct property));
+ of_prop->name = "linux,pci-domain";
+ of_prop->length = sizeof(hose->global_number);
+ of_prop->value = (unsigned char *)&of_prop[1];
+ memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number));
+ prom_add_property(dev, of_prop);
+ }
+
+ if (device_is_compatible(dev, "pa-pxp"))
+ setup_pa_pxp(hose);
+
+ printk(KERN_INFO "Found PA-PXP PCI host bridge. Firmware bus number: %d->%d\n",
+ hose->first_busno, hose->last_busno);
+
+ /* Interpret the "ranges" property */
+ /* This also maps the I/O region and sets isa_io/mem_base */
+ pci_process_bridge_OF_ranges(hose, dev, 1);
+ pci_setup_phb_io(hose, 1);
+
+ return 0;
+}
+
+
+void __init pas_pcibios_fixup(void)
+{
+ struct pci_dev *dev = NULL;
+
+ for_each_pci_dev(dev)
+ pci_read_irq_line(dev);
+}
+
+static void __init pas_fixup_phb_resources(void)
+{
+ struct pci_controller *hose, *tmp;
+
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+ unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
+ hose->io_resource.start += offset;
+ hose->io_resource.end += offset;
+ printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
+ hose->global_number,
+ hose->io_resource.start, hose->io_resource.end);
+ }
+}
+
+
+void __init pas_pci_init(void)
+{
+ struct device_node *np, *root;
+
+ root = of_find_node_by_path("/");
+ if (root == NULL) {
+ printk(KERN_CRIT "pas_pci_init: can't find root "
+ "of device tree\n");
+ return;
+ }
+
+ for (np = NULL; (np = of_get_next_child(root, np)) != NULL;)
+ if (np->name && !strcmp(np->name, "pxp") && !add_bridge(np))
+ of_node_get(np);
+
+ of_node_put(root);
+
+ pas_fixup_phb_resources();
+
+ /* Setup the linkage between OF nodes and PHBs */
+ pci_devs_phb_init();
+
+ /* Use the common resource allocation mechanism */
+ pci_probe_only = 1;
+}
Index: merge/arch/powerpc/platforms/pasemi/setup.c
===================================================================
--- /dev/null
+++ merge/arch/powerpc/platforms/pasemi/setup.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2006 PA Semi, Inc
+ *
+ * Authors: Kip Walker, PA Semi
+ * Olof Johansson, PA Semi
+ *
+ * Maintained by: Olof Johansson <olof@lixom.net>
+ *
+ * Based on arch/powerpc/platforms/maple/setup.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#undef DEBUG
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/major.h>
+#include <linux/initrd.h>
+#include <linux/vt_kern.h>
+#include <linux/console.h>
+#include <linux/ide.h>
+#include <linux/pci.h>
+#include <linux/adb.h>
+#include <linux/cuda.h>
+#include <linux/pmu.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/serial.h>
+#include <linux/smp.h>
+
+#include <asm/processor.h>
+#include <asm/sections.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+#include <asm/iommu.h>
+#include <asm/machdep.h>
+#include <asm/dma.h>
+#include <asm/cputable.h>
+#include <asm/time.h>
+#include <asm/of_device.h>
+#include <asm/lmb.h>
+#include <asm/mpic.h>
+#include <asm/smp.h>
+#include <asm/udbg.h>
+#include <asm/serial.h>
+
+extern int pas_set_rtc_time(struct rtc_time *tm);
+extern void pas_get_rtc_time(struct rtc_time *tm);
+extern unsigned long pas_get_boot_time(void);
+extern void pas_pci_init(void);
+extern void pas_pcibios_fixup(void);
+
+static void pas_restart(char *cmd)
+{
+ printk("restart unimplemented, looping...\n");
+ for (;;) ;
+}
+
+static void pas_power_off(void)
+{
+ printk("power off unimplemented, looping...\n");
+ for (;;) ;
+}
+
+static void pas_halt(void)
+{
+ pas_power_off();
+}
+
+#ifdef CONFIG_SMP
+struct smp_ops_t pas_smp_ops = {
+ .probe = smp_mpic_probe,
+ .message_pass = smp_mpic_message_pass,
+ .kick_cpu = smp_generic_kick_cpu,
+ .setup_cpu = smp_mpic_setup_cpu,
+ .give_timebase = smp_generic_give_timebase,
+ .take_timebase = smp_generic_take_timebase,
+};
+#endif /* CONFIG_SMP */
+
+void __init pas_setup_arch(void)
+{
+ /* init to some ~sane value until calibrate_delay() runs */
+ loops_per_jiffy = 50000000;
+
+ /* Setup SMP callback */
+#ifdef CONFIG_SMP
+ smp_ops = &pas_smp_ops;
+#endif
+ /* Lookup PCI hosts */
+ pas_pci_init();
+
+#ifdef CONFIG_DUMMY_CONSOLE
+ conswitchp = &dummy_con;
+#endif
+
+ printk(KERN_DEBUG "Using default idle loop\n");
+}
+
+static void iommu_dev_setup_null(struct pci_dev *dev) { }
+static void iommu_bus_setup_null(struct pci_bus *bus) { }
+
+static void __init pas_init_early(void)
+{
+ /* No iommu code yet */
+ ppc_md.iommu_dev_setup = iommu_dev_setup_null;
+ ppc_md.iommu_bus_setup = iommu_bus_setup_null;
+ pci_direct_iommu_init();
+}
+
+/* No legacy IO on our parts */
+static int pas_check_legacy_ioport(unsigned int baseport)
+{
+ return -ENODEV;
+}
+
+static __init void pas_init_IRQ(void)
+{
+ struct device_node *np = NULL;
+ struct device_node *root, *mpic_node = NULL;
+ unsigned long openpic_addr = 0;
+ const unsigned int *opprop;
+ int naddr, opplen;
+ struct mpic *mpic;
+
+ np = of_find_node_by_type(np, "open-pic");
+ if (!np) {
+ printk(KERN_ERR "No interrupt controller in device tree.\n");
+ return;
+ }
+ mpic_node = of_node_get(np);
+
+ /* Find address list in /platform-open-pic */
+ root = of_find_node_by_path("/");
+ naddr = prom_n_addr_cells(root);
+ opprop = get_property(root, "platform-open-pic", &opplen);
+ if (opprop != 0) {
+ openpic_addr = of_read_number(opprop, naddr);
+ printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
+ }
+ of_node_put(root);
+
+ mpic = mpic_alloc(mpic_node, openpic_addr, MPIC_PRIMARY, 0, 0,
+ " PAS-OPIC ");
+ BUG_ON(mpic == NULL);
+
+ mpic_assign_isu(mpic, 0, openpic_addr + 0x10000);
+ mpic_init(mpic);
+ of_node_put(mpic_node);
+ of_node_put(root);
+}
+
+static void __init pas_progress(char *s, unsigned short hex)
+{
+ printk("[%04x] : %s\n", hex, s ? s : "");
+}
+
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init pas_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (!of_flat_dt_is_compatible(root, "PA6T-1682M"))
+ return 0;
+
+ hpte_init_native();
+
+ return 1;
+}
+
+define_machine(pas) {
+ .name = "PA Semi PA6T-1682M",
+ .probe = pas_probe,
+ .setup_arch = pas_setup_arch,
+ .init_early = pas_init_early,
+ .init_IRQ = pas_init_IRQ,
+ .get_irq = mpic_get_irq,
+ .pcibios_fixup = pas_pcibios_fixup,
+ .restart = pas_restart,
+ .power_off = pas_power_off,
+ .halt = pas_halt,
+ .get_boot_time = pas_get_boot_time,
+ .set_rtc_time = pas_set_rtc_time,
+ .get_rtc_time = pas_get_rtc_time,
+ .calibrate_decr = generic_calibrate_decr,
+ .check_legacy_ioport = pas_check_legacy_ioport,
+ .progress = pas_progress,
+};
Index: merge/arch/powerpc/platforms/pasemi/time.c
===================================================================
--- /dev/null
+++ merge/arch/powerpc/platforms/pasemi/time.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006 PA Semi, Inc
+ *
+ * Maintained by: Olof Johansson <olof@lixom.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#undef DEBUG
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/bcd.h>
+
+#include <asm/time.h>
+
+void pas_get_rtc_time(struct rtc_time *tm)
+{
+}
+
+int pas_set_rtc_time(struct rtc_time *tm)
+{
+ return -ENODEV;
+}
+
+unsigned long __init pas_get_boot_time(void)
+{
+#if 0
+ struct rtc_time tm;
+
+ pas_get_rtc_time(&tm);
+
+ return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+#else
+ /* Let's just return a fake date right now */
+ return mktime(2006, 1, 1, 12, 0, 0);
+#endif
+}
^ permalink raw reply
* [4/5] powerpc: PA Semi PWRficient platform support
From: Olof Johansson @ 2006-09-05 17:28 UTC (permalink / raw)
To: paulus, anton; +Cc: linuxppc-dev
In-Reply-To: <20060904175742.5472a6fa@localhost.localdomain>
Base patch for PA6T and PA6T-1682M. This introduces the
arch/powerpc/platform/pasemi directory, together with basic
implementations for various setup.
Much of this was based on other platform code, i.e. Maple, etc.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: merge/arch/powerpc/Kconfig
===================================================================
--- merge.orig/arch/powerpc/Kconfig
+++ merge/arch/powerpc/Kconfig
@@ -413,6 +409,17 @@ config PPC_MAPLE
This option enables support for the Maple 970FX Evaluation Board.
For more informations, refer to <http://www.970eval.com>
+config PPC_PASEMI
+ depends on PPC_MULTIPLATFORM && PPC64
+ bool "PA Semi SoC-based platforms"
+ default n
+ select MPIC
+ select PPC_UDBG_16550
+ select GENERIC_TBSYNC
+ help
+ This option enables support for PA Semi's PWRficient line
+ of SoC processors, including PA6T-1682M
+
config PPC_CELL
bool
default n
Index: merge/arch/powerpc/platforms/Makefile
===================================================================
--- merge.orig/arch/powerpc/platforms/Makefile
+++ merge/arch/powerpc/platforms/Makefile
@@ -13,5 +13,6 @@ obj-$(CONFIG_PPC_86xx) += 86xx/
obj-$(CONFIG_PPC_PSERIES) += pseries/
obj-$(CONFIG_PPC_ISERIES) += iseries/
obj-$(CONFIG_PPC_MAPLE) += maple/
+obj-$(CONFIG_PPC_PASEMI) += pasemi/
obj-$(CONFIG_PPC_CELL) += cell/
obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
Index: merge/arch/powerpc/platforms/pasemi/Makefile
===================================================================
--- /dev/null
+++ merge/arch/powerpc/platforms/pasemi/Makefile
@@ -0,0 +1 @@
+obj-y += setup.o pci.o time.o
Index: merge/arch/powerpc/platforms/pasemi/pci.c
===================================================================
--- /dev/null
+++ merge/arch/powerpc/platforms/pasemi/pci.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2006 PA Semi, Inc
+ *
+ * Authors: Kip Walker, PA Semi
+ * Olof Johansson, PA Semi
+ *
+ * Maintained by: Olof Johansson <olof@lixom.net>
+ *
+ * Based on arch/powerpc/platforms/maple/pci.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+#include <asm/iommu.h>
+
+#include <asm/ppc-pci.h>
+#include <asm/udbg.h>
+
+#define PA_PXP_CFA(bus, devfn, off) (((bus) << 20) | ((devfn) << 12) | (off))
+
+static unsigned long pa_pxp_cfg_addr(struct pci_controller* hose,
+ u8 bus, u8 devfn, int offset)
+{
+ return ((unsigned long)hose->cfg_data) + PA_PXP_CFA(bus, devfn, offset);
+}
+
+static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 *val)
+{
+ struct pci_controller *hose;
+ unsigned long addr;
+
+ hose = pci_bus_to_host(bus);
+ if (!hose)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ *val = in_8((u8 *)addr);
+ break;
+ case 2:
+ *val = in_le16((u16 *)addr);
+ break;
+ default:
+ *val = in_le32((u32 *)addr);
+ break;
+ }
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn,
+ int offset, int len, u32 val)
+{
+ struct pci_controller *hose;
+ unsigned long addr;
+
+ hose = pci_bus_to_host(bus);
+ if (!hose)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
+
+ /*
+ * Note: the caller has already checked that offset is
+ * suitably aligned and that len is 1, 2 or 4.
+ */
+ switch (len) {
+ case 1:
+ out_8((u8 *)addr, val);
+ (void) in_8((u8 *)addr);
+ break;
+ case 2:
+ out_le16((u16 *)addr, val);
+ (void) in_le16((u16 *)addr);
+ break;
+ default:
+ out_le32((u32 *)addr, val);
+ (void) in_le32((u32 *)addr);
+ break;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops pa_pxp_ops =
+{
+ pa_pxp_read_config,
+ pa_pxp_write_config
+};
+
+static void __init setup_pa_pxp(struct pci_controller* hose)
+{
+ hose->ops = &pa_pxp_ops;
+ hose->cfg_data = ioremap(0xe0000000, 0x1000000);
+}
+
+static int __init add_bridge(struct device_node *dev)
+{
+ int len;
+ struct pci_controller *hose;
+ int *bus_range;
+ struct property *of_prop;
+
+ pr_debug("Adding PCI host bridge %s\n", dev->full_name);
+
+ bus_range = (int *) get_property(dev, "bus-range", &len);
+ if (bus_range == NULL || len < 2 * sizeof(int)) {
+ printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
+ dev->full_name);
+ }
+
+ hose = pcibios_alloc_controller(dev);
+ if (hose == NULL)
+ return -ENOMEM;
+
+ hose->first_busno = bus_range ? bus_range[0] : 0;
+ hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+ of_prop = alloc_bootmem(sizeof(struct property) +
+ sizeof(hose->global_number));
+ if (of_prop) {
+ memset(of_prop, 0, sizeof(struct property));
+ of_prop->name = "linux,pci-domain";
+ of_prop->length = sizeof(hose->global_number);
+ of_prop->value = (unsigned char *)&of_prop[1];
+ memcpy(of_prop->value, &hose->global_number, sizeof(hose->global_number));
+ prom_add_property(dev, of_prop);
+ }
+
+ if (device_is_compatible(dev, "pa-pxp"))
+ setup_pa_pxp(hose);
+
+ printk(KERN_INFO "Found PA-PXP PCI host bridge. Firmware bus number: %d->%d\n",
+ hose->first_busno, hose->last_busno);
+
+ /* Interpret the "ranges" property */
+ /* This also maps the I/O region and sets isa_io/mem_base */
+ pci_process_bridge_OF_ranges(hose, dev, 1);
+ pci_setup_phb_io(hose, 1);
+
+ return 0;
+}
+
+
+void __init pas_pcibios_fixup(void)
+{
+ struct pci_dev *dev = NULL;
+
+ for_each_pci_dev(dev)
+ pci_read_irq_line(dev);
+}
+
+static void __init pas_fixup_phb_resources(void)
+{
+ struct pci_controller *hose, *tmp;
+
+ list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
+ unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
+ hose->io_resource.start += offset;
+ hose->io_resource.end += offset;
+ printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
+ hose->global_number,
+ hose->io_resource.start, hose->io_resource.end);
+ }
+}
+
+
+void __init pas_pci_init(void)
+{
+ struct device_node *np, *root;
+
+ root = of_find_node_by_path("/");
+ if (root == NULL) {
+ printk(KERN_CRIT "pas_pci_init: can't find root "
+ "of device tree\n");
+ return;
+ }
+
+ for (np = NULL; (np = of_get_next_child(root, np)) != NULL;)
+ if (np->name && !strcmp(np->name, "pxp") && !add_bridge(np))
+ of_node_get(np);
+
+ of_node_put(root);
+
+ pas_fixup_phb_resources();
+
+ /* Setup the linkage between OF nodes and PHBs */
+ pci_devs_phb_init();
+
+ /* Use the common resource allocation mechanism */
+ pci_probe_only = 1;
+}
Index: merge/arch/powerpc/platforms/pasemi/setup.c
===================================================================
--- /dev/null
+++ merge/arch/powerpc/platforms/pasemi/setup.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2006 PA Semi, Inc
+ *
+ * Authors: Kip Walker, PA Semi
+ * Olof Johansson, PA Semi
+ *
+ * Maintained by: Olof Johansson <olof@lixom.net>
+ *
+ * Based on arch/powerpc/platforms/maple/setup.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#undef DEBUG
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/major.h>
+#include <linux/initrd.h>
+#include <linux/vt_kern.h>
+#include <linux/console.h>
+#include <linux/ide.h>
+#include <linux/pci.h>
+#include <linux/adb.h>
+#include <linux/cuda.h>
+#include <linux/pmu.h>
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/serial.h>
+#include <linux/smp.h>
+
+#include <asm/processor.h>
+#include <asm/sections.h>
+#include <asm/prom.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+#include <asm/iommu.h>
+#include <asm/machdep.h>
+#include <asm/dma.h>
+#include <asm/cputable.h>
+#include <asm/time.h>
+#include <asm/of_device.h>
+#include <asm/lmb.h>
+#include <asm/mpic.h>
+#include <asm/smp.h>
+#include <asm/udbg.h>
+#include <asm/serial.h>
+
+extern int pas_set_rtc_time(struct rtc_time *tm);
+extern void pas_get_rtc_time(struct rtc_time *tm);
+extern unsigned long pas_get_boot_time(void);
+extern void pas_pci_init(void);
+extern void pas_pcibios_fixup(void);
+
+static void pas_restart(char *cmd)
+{
+ printk("restart unimplemented, looping...\n");
+ for (;;) ;
+}
+
+static void pas_power_off(void)
+{
+ printk("power off unimplemented, looping...\n");
+ for (;;) ;
+}
+
+static void pas_halt(void)
+{
+ pas_power_off();
+}
+
+#ifdef CONFIG_SMP
+struct smp_ops_t pas_smp_ops = {
+ .probe = smp_mpic_probe,
+ .message_pass = smp_mpic_message_pass,
+ .kick_cpu = smp_generic_kick_cpu,
+ .setup_cpu = smp_mpic_setup_cpu,
+ .give_timebase = smp_generic_give_timebase,
+ .take_timebase = smp_generic_take_timebase,
+};
+#endif /* CONFIG_SMP */
+
+void __init pas_setup_arch(void)
+{
+ /* init to some ~sane value until calibrate_delay() runs */
+ loops_per_jiffy = 50000000;
+
+ /* Setup SMP callback */
+#ifdef CONFIG_SMP
+ smp_ops = &pas_smp_ops;
+#endif
+ /* Lookup PCI hosts */
+ pas_pci_init();
+
+#ifdef CONFIG_DUMMY_CONSOLE
+ conswitchp = &dummy_con;
+#endif
+
+ printk(KERN_DEBUG "Using default idle loop\n");
+}
+
+static void iommu_dev_setup_null(struct pci_dev *dev) { }
+static void iommu_bus_setup_null(struct pci_bus *bus) { }
+
+static void __init pas_init_early(void)
+{
+ /* No iommu code yet */
+ ppc_md.iommu_dev_setup = iommu_dev_setup_null;
+ ppc_md.iommu_bus_setup = iommu_bus_setup_null;
+ pci_direct_iommu_init();
+}
+
+/* No legacy IO on our parts */
+static int pas_check_legacy_ioport(unsigned int baseport)
+{
+ return -ENODEV;
+}
+
+static __init void pas_init_IRQ(void)
+{
+ struct device_node *np = NULL;
+ struct device_node *root, *mpic_node = NULL;
+ unsigned long openpic_addr = 0;
+ const unsigned int *opprop;
+ int naddr, opplen;
+ struct mpic *mpic;
+
+ np = of_find_node_by_type(np, "open-pic");
+ if (!np) {
+ printk(KERN_ERR "No interrupt controller in device tree.\n");
+ return;
+ }
+ mpic_node = of_node_get(np);
+
+ /* Find address list in /platform-open-pic */
+ root = of_find_node_by_path("/");
+ naddr = prom_n_addr_cells(root);
+ opprop = get_property(root, "platform-open-pic", &opplen);
+ if (opprop != 0) {
+ openpic_addr = of_read_number(opprop, naddr);
+ printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
+ }
+ of_node_put(root);
+
+ mpic = mpic_alloc(mpic_node, openpic_addr, MPIC_PRIMARY, 0, 0,
+ " PAS-OPIC ");
+ BUG_ON(mpic == NULL);
+
+ mpic_assign_isu(mpic, 0, openpic_addr + 0x10000);
+ mpic_init(mpic);
+ of_node_put(mpic_node);
+ of_node_put(root);
+}
+
+static void __init pas_progress(char *s, unsigned short hex)
+{
+ printk("[%04x] : %s\n", hex, s ? s : "");
+}
+
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init pas_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (!of_flat_dt_is_compatible(root, "PA6T-1682M"))
+ return 0;
+
+ hpte_init_native();
+
+ return 1;
+}
+
+define_machine(pas) {
+ .name = "PA Semi PA6T-1682M",
+ .probe = pas_probe,
+ .setup_arch = pas_setup_arch,
+ .init_early = pas_init_early,
+ .init_IRQ = pas_init_IRQ,
+ .get_irq = mpic_get_irq,
+ .pcibios_fixup = pas_pcibios_fixup,
+ .restart = pas_restart,
+ .power_off = pas_power_off,
+ .halt = pas_halt,
+ .get_boot_time = pas_get_boot_time,
+ .set_rtc_time = pas_set_rtc_time,
+ .get_rtc_time = pas_get_rtc_time,
+ .calibrate_decr = generic_calibrate_decr,
+ .check_legacy_ioport = pas_check_legacy_ioport,
+ .progress = pas_progress,
+};
Index: merge/arch/powerpc/platforms/pasemi/time.c
===================================================================
--- /dev/null
+++ merge/arch/powerpc/platforms/pasemi/time.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2006 PA Semi, Inc
+ *
+ * Maintained by: Olof Johansson <olof@lixom.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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
+ */
+
+#undef DEBUG
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/bcd.h>
+
+#include <asm/time.h>
+
+void pas_get_rtc_time(struct rtc_time *tm)
+{
+}
+
+int pas_set_rtc_time(struct rtc_time *tm)
+{
+ return -ENODEV;
+}
+
+unsigned long __init pas_get_boot_time(void)
+{
+#if 0
+ struct rtc_time tm;
+
+ pas_get_rtc_time(&tm);
+
+ return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+#else
+ /* Let's just return a fake date right now */
+ return mktime(2006, 1, 1, 12, 0, 0);
+#endif
+}
^ permalink raw reply
* [3/5] powerpc: PA6T cputable entry, PVR value
From: Olof Johansson @ 2006-09-05 17:28 UTC (permalink / raw)
To: paulus, anton; +Cc: linuxppc-dev
In-Reply-To: <20060904175742.5472a6fa@localhost.localdomain>
Introduce PWRficient PA6T cputable entry and feature bits.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: merge/arch/powerpc/kernel/cputable.c
===================================================================
--- merge.orig/arch/powerpc/kernel/cputable.c
+++ merge/arch/powerpc/kernel/cputable.c
@@ -58,6 +58,9 @@ extern void __restore_cpu_ppc970(void);
#define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\
PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
PPC_FEATURE_TRUE_LE)
+#define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
+ PPC_FEATURE_TRUE_LE | \
+ PPC_FEATURE_HAS_ALTIVEC_COMP)
#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
PPC_FEATURE_BOOKE)
@@ -286,6 +289,17 @@ struct cpu_spec cpu_specs[] = {
.dcache_bsize = 128,
.platform = "ppc-cell-be",
},
+ { /* PA Semi PA6T */
+ .pvr_mask = 0x7fff0000,
+ .pvr_value = 0x00900000,
+ .cpu_name = "PA6T",
+ .cpu_features = CPU_FTRS_PA6T,
+ .cpu_user_features = COMMON_USER_PA6T,
+ .icache_bsize = 64,
+ .dcache_bsize = 64,
+ .num_pmcs = 6,
+ .platform = "pa6t",
+ },
{ /* default match */
.pvr_mask = 0x00000000,
.pvr_value = 0x00000000,
Index: merge/include/asm-powerpc/reg.h
===================================================================
--- merge.orig/include/asm-powerpc/reg.h
+++ merge/include/asm-powerpc/reg.h
@@ -592,6 +592,8 @@
#define PV_630p 0x0041
#define PV_970MP 0x0044
#define PV_BE 0x0070
+#define PV_PA6T 0x0090
+
/*
* Number of entries in the SLB. If this ever changes we should handle
Index: merge/include/asm-powerpc/cputable.h
===================================================================
--- merge.orig/include/asm-powerpc/cputable.h
+++ merge/include/asm-powerpc/cputable.h
@@ -23,6 +23,7 @@
#define PPC_FEATURE_SMT 0x00004000
#define PPC_FEATURE_ICACHE_SNOOP 0x00002000
#define PPC_FEATURE_ARCH_2_05 0x00001000
+#define PPC_FEATURE_PA6T 0x00000800
#define PPC_FEATURE_TRUE_LE 0x00000002
#define PPC_FEATURE_PPC_LE 0x00000001
@@ -332,6 +333,10 @@ extern void do_cpu_ftr_fixups(unsigned l
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE)
+#define CPU_FTRS_PA6T (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
+ CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
+ CPU_FTR_PURR | CPU_FTR_REAL_LE)
#define CPU_FTRS_COMPATIBLE (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2)
#endif
@@ -340,7 +345,7 @@ extern void do_cpu_ftr_fixups(unsigned l
#define CPU_FTRS_POSSIBLE \
(CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \
CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 | \
- CPU_FTRS_CELL | CPU_FTR_CI_LARGE_PAGE)
+ CPU_FTRS_CELL | CPU_FTRS_PA6T)
#else
enum {
CPU_FTRS_POSSIBLE =
@@ -379,7 +384,7 @@ enum {
#define CPU_FTRS_ALWAYS \
(CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & \
CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_POWER6 & \
- CPU_FTRS_CELL & CPU_FTRS_POSSIBLE)
+ CPU_FTRS_CELL & CPU_FTRS_PA6T & CPU_FTRS_POSSIBLE)
#else
enum {
CPU_FTRS_ALWAYS =
^ permalink raw reply
* [2/5] powerpc: Divorce CPU_FTR_CTRL from CPU_FTR_PPCAS_ARCH_V2_BASE
From: Olof Johansson @ 2006-09-05 17:27 UTC (permalink / raw)
To: paulus, anton; +Cc: linuxppc-dev
In-Reply-To: <20060904175742.5472a6fa@localhost.localdomain>
The performance monitor implementation (including CTRL register behaviour)
is just included in PPC v2 as an example, it's not truly part of the base.
It's actually a somewhat misleading feature, but I'll leave that be for
now: The precense of the register is not what the feature bit is used
for, but instead it's used to determine if it contains the runlatch
bit for idle reporting of the performance monitor. For alternative
implementations, the register might still exist but the bit might have
different meaning (or no meaning at all).
For now, split it off and don't include it in CPU_FTR_PPCAS_ARCH_V2_BASE.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: merge/include/asm-powerpc/cputable.h
===================================================================
--- merge.orig/include/asm-powerpc/cputable.h
+++ merge/include/asm-powerpc/cputable.h
@@ -148,7 +148,7 @@ extern void do_cpu_ftr_fixups(unsigned l
#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \
CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \
- CPU_FTR_NODSISRALIGN | CPU_FTR_CTRL)
+ CPU_FTR_NODSISRALIGN)
/* iSeries doesn't support large pages */
#ifdef CONFIG_PPC_ISERIES
@@ -313,24 +313,25 @@ extern void do_cpu_ftr_fixups(unsigned l
CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | \
CPU_FTR_MMCRA | CPU_FTR_CTRL)
#define CPU_FTRS_POWER4 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
- CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_MMCRA)
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
+ CPU_FTR_MMCRA)
#define CPU_FTRS_PPC970 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
- CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA)
#define CPU_FTRS_POWER5 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
- CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR)
#define CPU_FTRS_POWER6 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
- CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_REAL_LE)
#define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
- CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
- CPU_FTR_CTRL | CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE)
+ CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE)
#define CPU_FTRS_COMPATIBLE (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2)
#endif
^ permalink raw reply
* [1/5] powerpc: Reduce default cacheline size to 64 bytes
From: Olof Johansson @ 2006-09-05 17:26 UTC (permalink / raw)
To: paulus, anton; +Cc: linuxppc-dev
In-Reply-To: <20060904175742.5472a6fa@localhost.localdomain>
Reduce default cacheline size on 64-bit powerpc from 128 bytes to 64.
This is the architected minimum. In most cases we'll still end up using
cache line information from the device tree, but defaults are used during
early boot and doing a few dcbst/icbi's too many there won't do any harm.
Signed-off-by: Olof Johansson <olof@lixom.net>
Index: merge/arch/powerpc/kernel/setup_64.c
===================================================================
--- merge.orig/arch/powerpc/kernel/setup_64.c
+++ merge/arch/powerpc/kernel/setup_64.c
@@ -78,10 +78,10 @@ u64 ppc64_pft_size;
* before we've read this from the device tree.
*/
struct ppc64_caches ppc64_caches = {
- .dline_size = 0x80,
- .log_dline_size = 7,
- .iline_size = 0x80,
- .log_iline_size = 7
+ .dline_size = 0x40,
+ .log_dline_size = 6,
+ .iline_size = 0x40,
+ .log_iline_size = 6
};
EXPORT_SYMBOL_GPL(ppc64_caches);
Index: merge/arch/powerpc/kernel/head_64.S
===================================================================
--- merge.orig/arch/powerpc/kernel/head_64.S
+++ merge/arch/powerpc/kernel/head_64.S
@@ -1748,7 +1748,7 @@ _STATIC(__after_prom_start)
_GLOBAL(copy_and_flush)
addi r5,r5,-8
addi r6,r6,-8
-4: li r0,16 /* Use the least common */
+4: li r0,8 /* Use the smallest common */
/* denominator cache line */
/* size. This results in */
/* extra cache line flushes */
^ permalink raw reply
* [0/5] powerpc: PA Semi PWRficient patches
From: Olof Johansson @ 2006-09-05 17:26 UTC (permalink / raw)
To: paulus, anton; +Cc: linuxppc-dev
Hi,
The following series of patches introduces basic support for PA Semi's
PA6T core, and the base platform support for PWRficient PA6T-1682M.
It is split up in 5 separate patches:
1. Reduce default cacheline size to 64 bytes
2. Divorce CPU_FTR_CTRL from CPU_FTR_PPCAS_ARCH_V2_BASE
3. Cpu table entry, PVR value
4. Basic arch/powerpc/platforms/pasemi contents
5. MAINTAINER entry
-Olof
^ permalink raw reply
* Re: [POWERPC] merge iSeries i/o operations with the rest
From: Linas Vepstas @ 2006-09-05 16:41 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: ppc-dev, paulus
In-Reply-To: <20060905120817.e52857ee.sfr@canb.auug.org.au>
On Tue, Sep 05, 2006 at 12:08:17PM +1000, Stephen Rothwell wrote:
> @@ -273,25 +234,30 @@ #define iobarrier_w() eieio()
> * These routines do not perform EEH-related I/O address translation,
> * and should not be used directly by device drivers. Use inb/readb
> * instead.
> + *
> + * For some of these, we force the target/source register to be
> + * r0 to ease decoding on iSeries.
???
Why?
> static inline int in_8(const volatile unsigned char __iomem *addr)
> {
> - int ret;
> + register unsigned int ret __asm__("r0");
Such as here .. why is this being forced ??
> - __asm__ __volatile__("lbz%U1%X1 %0,%1; twi 0,%0,0; isync"
> - : "=r" (ret) : "m" (*addr));
> + __asm__ __volatile__("lbzx %0,0,%1; twi 0,%0,0; isync"
> + : "=r" (ret) : "r" (addr));
Why make this change? The old code allows the compiler to optimize
better than the new code. One might argue that, in the grand scheme of
things, i/o is very slow, so a few cycles here doesn't matter much.
But still, I don't understand why this change is needed.
> +static inline void memset_io(volatile void __iomem *addr, int c,
> + unsigned long n)
> +{
> + if (firmware_has_feature(FW_FEATURE_ISERIES))
> + iSeries_memset_io(addr, c, n);
> + else
> + eeh_memset_io(addr, c, n);
> +}
!! I think it would be much better to have this be a compile-time
check rather than a run-time check. No only does it save cycles,
but it makes the iSeries kernel smaller (by not needing eeh code
in it) and the p-series code smaller (by not compiling iseries
code into it.
--linas
^ permalink raw reply
* Yosemite board w/ppc440ep NETDEV WATCHDOG: eth0: transmit timed out
From: Michael Alievsky @ 2006-09-05 16:14 UTC (permalink / raw)
To: linuxppc-embedded
Hi Rocky,
We have experienced absolutely the same problem with the Yosemite board.
The problem is releated to the simultanious recieve on both Ethernet ports.
Did you get more information about the problem?
Regards,
Michael Alievsky
^ permalink raw reply
* Re: [U-Boot-Users] OT: Re: Status of OF in TQM8540 and linux-2.6.17.11
From: Wolfgang Denk @ 2006-09-05 15:39 UTC (permalink / raw)
To: Vitaly Bordug; +Cc: linuxppc-embedded
In-Reply-To: <20060905190608.082331bc@vitb.ru.mvista.com>
In message <20060905190608.082331bc@vitb.ru.mvista.com> you wrote:
>
> Clemens Koller <clemens.koller@anagramm.de> wrote:
...
> > According to TQC, the latest "working" kernel was a 2.6.15-git from your
> > (denx) tree. I get the details from Mr. Becher@TQC and see how far I can get.
[TQ provides obsolete information.]
> The upper defines need to reside in the board-specific code for tqm as well as for other boards
> utilizing such scheme (see platforms/85xx/mpc85xx_ads_common.h for instance).
Thanks for pointing out.
Clemens, plese try again (commit id cd4ebbc9b95434977e5f182b9a22d7d1de0748ce)
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
"Where shall I begin, please your Majesty?" he asked. "Begin at the
beginning," the King said, gravely, "and go on till you come to the
end: then stop." - Alice's Adventures in Wonderland, Lewis Carroll
^ permalink raw reply
* Re: [2.6.19 PATCH 1/7] ehea: interface to network stack
From: Thomas Klein @ 2006-09-05 15:09 UTC (permalink / raw)
To: Francois Romieu
Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel,
Christoph Raisch, linux-ppc, Marcus Eder
In-Reply-To: <20060904201606.GA24386@electric-eye.fr.zoreil.com>
Hi Francois,
thanks for your review and your comments. See below our answers.
Regards
Thomas
Francois Romieu wrote:
>> + cb2 = kzalloc(H_CB_ALIGNMENT, GFP_KERNEL);
>> + if (!cb2) {
>> + ehea_error("no mem for cb2");
>> + goto kzalloc_failed;
>
> It's better when the label tell what it does than where it comes from.
> If it's numbered too, one can check them without going back and forth.
>> + stats->tx_packets = cb2->txucp + cb2->txmcp + cb2->txbcp;
>> + stats->multicast = cb2->rxmcp;
>> + stats->rx_errors = cb2->rxuerr;
>> + stats->rx_bytes = cb2->rxo;
>> + stats->tx_bytes = cb2->txo;
>> + stats->rx_packets = rx_packets;
>> +
>> +hcall_failed:
>> + kfree(cb2);
>
> Tab was turned into spaces.
Fixed.
>> +static inline int ehea_refill_rq1(struct ehea_port_res *pr, int index,
>
> Avoid inline ?
Inline declaration was removed from this one and several other functions.
>> + for (i = 0; i < nr_of_wqes; i++) {
>> + if (!skb_arr_rq1[index]) {
>> + skb_arr_rq1[index] = dev_alloc_skb(EHEA_LL_PKT_SIZE);
>
> netdev_alloc_skb ?
Agreed & done.
>
>> +
>> + if (!skb_arr_rq1[index]) {
>> + ehea_error("no mem for skb/%d wqes filled", i);
>> + ret = -ENOMEM;
>
> The caller does not check the returned value.
Agreed. fn returns void now.
>> + if (!skb_arr_rq1[i]) {
>> + ehea_error("no mem for skb/%d skbs filled.", i);
>> + ret = -ENOMEM;
>> + goto exit0;
>
> s/exit0/out/
Goto target naming was reworked throughout the whole driver and basically
uses the style used by Dave M. and Jeff G. in the Tigon3 driver.
>> +static inline int ehea_check_cqe(struct ehea_cqe *cqe, int *rq_num)
>> +{
>> + *rq_num = (cqe->type & EHEA_CQE_TYPE_RQ) >> 5;
>> + if ((cqe->status & EHEA_CQE_STAT_ERR_MASK) == 0)
>> + return 0;
>> + if (((cqe->status & EHEA_CQE_STAT_ERR_TCP) != 0)
>> + && (cqe->header_length == 0))
>
> && on the previous line please.
Changed at all occurences.
>> +static inline struct sk_buff *get_skb_by_index(struct sk_buff **skb_array,
>> + int arr_len,
>> + struct ehea_cqe *cqe)
>> +{
>> + int skb_index = EHEA_BMASK_GET(EHEA_WR_ID_INDEX, cqe->wr_id);
>> + struct sk_buff *skb;
>> + void *pref;
>> + int x;
>> +
>> + x = skb_index + 1;
>> + x &= (arr_len - 1);
>> +
>> + pref = (void*)skb_array[x];
>
> Useless cast.
Agreed -> removed.
>> + if (unlikely(!skb)) {
>> + if (netif_msg_rx_err(port))
>> + ehea_error("LL rq1: skb=NULL");
>> + skb = dev_alloc_skb(EHEA_LL_PKT_SIZE);
>
> Tab/space
Fixed.
>> +irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param, struct pt_regs * regs)
>
> static ?
Agreed.
>> +int ehea_sense_port_attr(struct ehea_port *port)
>
> static ?
No -> used in ehea_ethtool.c
>> + } else {
>> + if (hret == H_AUTHORITY)
>> + {
>
> Misplaced curly brace.
Fixed.
>
>> + ehea_info("Hypervisor denied setting port speed. Either"
>> + " this partition is not authorized to set "
>> + "port speed or another partition has modified"
>> + " port speed first.");
>> + ret = -EPERM;
>> + } else
>> + {
>
> Misplaced curly brace.
Fixed.
>
>> + ret = -EIO;
>> + ehea_error("Failed setting port speed");
>> + }
>> + }
>> + netif_carrier_on(port->netdev);
>> +exit0:
>> + kfree(cb4);
>
> cb4 is NULL. Not wrong per se but I'd rather move the label one line down.
Agreed.
>> +void ehea_neq_tasklet(unsigned long data)
>
> static ?
Agreed.
>> +irqreturn_t ehea_interrupt_neq(int irq, void *param, struct pt_regs *regs)
>
> static ?
Agreed.
>> +{
>> + struct ehea_adapter *adapter = (struct ehea_adapter*)param;
>
> Useless cast.
Fixed.
>> +static int ehea_fill_port_res(struct ehea_port_res *pr)
>> +{
>> + int ret;
>> + struct ehea_qp_init_attr *init_attr = &pr->qp->init_attr;
>> +
>> + /* RQ 1 */
>> + ret = ehea_init_fill_rq1(pr, init_attr->act_nr_rwqes_rq1
>> + - init_attr->act_nr_rwqes_rq2
>> + - init_attr->act_nr_rwqes_rq3 - 1);
>> + /* RQ 2 */
>
> Useless comment.
Removed.
>> + for (k = 0; k < i; k++) {
>> + u32 ist = port->port_res[k].recv_eq->attr.ist1;
>> + ibmebus_free_irq(NULL, ist, &port->port_res[k]);
>> + }
>> + goto failure;
>
> Poor label (and bloaty release practice too: remove k, reuse "i" below
> and more importantly release the things in allocation-reversed order).
Somehow I don't get your point concerning the usage of 'k'. We need another
iterator as the for loops using 'k' use 'i' as their terminating condition.
>
>> + }
>> + if (netif_msg_ifup(port))
>> + ehea_info("irq_handle 0x%X for funct ehea_recv_int %d "
>> + "registered", pr->recv_eq->attr.ist1, i);
>> + }
>> +
>> + snprintf(port->int_aff_name, EHEA_IRQ_NAME_SIZE - 1,
>> + "%s-aff", dev->name);
>> + ret = ibmebus_request_irq(NULL, port->qp_eq->attr.ist1,
>> + ehea_qp_aff_irq_handler,
>> + SA_INTERRUPT, port->int_aff_name, port);
>> + if (ret) {
>> + ehea_error("failed registering irq for qp_aff_irq_handler:"
>> + " ist=%X", port->qp_eq->attr.ist1);
>> + goto failure2;
>> + }
>> + if (netif_msg_ifup(port))
>> + ehea_info("irq_handle 0x%X for function qp_aff_irq_handler "
>> + "registered", port->qp_eq->attr.ist1);
>> +
>> + for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
>> + pr = &port->port_res[i];
>> + snprintf(pr->int_send_name, EHEA_IRQ_NAME_SIZE - 1,
>> + "%s-send%d", dev->name, i);
>> + ret = ibmebus_request_irq(NULL, pr->send_eq->attr.ist1,
>> + ehea_send_irq_handler,
>> + SA_INTERRUPT, pr->int_send_name,
>> + pr);
>> + if (ret) {
>> + ehea_error("failed registering irq for ehea_send"
>> + " port_res_nr:%d, ist=%X", i,
>> + pr->send_eq->attr.ist1);
>> + for (k = 0; k < i; k++) {
>> + u32 ist = port->port_res[k].send_eq->attr.ist1;
>> + ibmebus_free_irq(NULL, ist, &port->port_res[i]);
>> + }
>> + goto failure3;
>> + }
>> + if (netif_msg_ifup(port))
>> + ehea_info("irq_handle 0x%X for function ehea_send_int "
>> + "%d registered", pr->send_eq->attr.ist1, i);
>> + }
>> + return ret;
>> +failure3:
>> + for (i = 0; i < port->num_def_qps; i++)
>> + ibmebus_free_irq(NULL, port->port_res[i].recv_eq->attr.ist1,
>> + &port->port_res[i]);
>
> Compare with:
> u32 ist = port->port_res[k].recv_eq->attr.ist1;
> ibmebus_free_irq(NULL, ist, &port->port_res[k]);
>
> It was the first loop above. :o/
Agreed, that's slightly prettier.
>> + /* send */
>> + for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
>> + ibmebus_free_irq(NULL, port->port_res[i].send_eq->attr.ist1,
>> + &port->port_res[i]);
>
> Please add a local 'struct shnortz *foo = port->port_res + i;'
Agreed & done.
>> + cb0->port_rc = EHEA_BMASK_SET(PXLY_RC_VALID, 1)
>> + | EHEA_BMASK_SET(PXLY_RC_IP_CHKSUM, 1)
>> + | EHEA_BMASK_SET(PXLY_RC_TCP_UDP_CHKSUM, 1)
>> + | EHEA_BMASK_SET(PXLY_RC_VLAN_XTRACT, 1)
>
> Tab/space
Fixed.
>> +static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr,
>> + struct port_res_cfg *pr_cfg, int queue_token)
>> +{
>> + struct ehea_adapter *adapter = port->adapter;
>> + struct ehea_qp_init_attr *init_attr = NULL;
>
> Useless initialization.
init_attr must be initialized as there are goto statements which may
pass the init_attr = kzalloc() statement and jump to ehea_init_port_res_err
where we want to kfree() init_attr without having to care for its state.
>> + pr->send_eq = ehea_create_eq(adapter, eq_type, EHEA_MAX_ENTRIES_EQ, 0);
>> + if (!pr->send_eq) {
>> + ehea_error("create_eq failed (send_eq)");
>> + ret = -EIO;
>> + goto ehea_init_port_res_err;
>
> Should factor 'ret = -EIO' before the sequence.
Ok, done.
>> + if (!ret) {
>> + ehea_destroy_cq(pr->send_cq);
>> + ehea_destroy_cq(pr->recv_cq);
>> + ehea_destroy_eq(pr->send_eq);
>> + ehea_destroy_eq(pr->recv_eq);
>> +
>> + for (i = 0; i < pr->rq1_skba.len; i++)
>> + if (pr->rq1_skba.arr[i])
>> + dev_kfree_skb(pr->rq1_skba.arr[i]);
>> +
>> + for (i = 0; i < pr->rq2_skba.len; i++)
>> + if (pr->rq2_skba.arr[i])
>> + dev_kfree_skb(pr->rq2_skba.arr[i]);
>> +
>> + for (i = 0; i < pr->rq3_skba.len; i++)
>> + if (pr->rq3_skba.arr[i])
>> + dev_kfree_skb(pr->rq3_skba.arr[i]);
>> +
>> + for (i = 0; i < pr->sq_skba.len; i++)
>> + if (pr->sq_skba.arr[i])
>> + dev_kfree_skb(pr->sq_skba.arr[i]);
>
> Feels like a 0..4 loop is missing above.
The send queue and the receive queues are not related to eachother
in any way. Thus using a joint array for them isn't appropriate.
>> +static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
>> +{
>> + struct ehea_port *port = netdev_priv(dev);
>> + struct ehea_port_res *pr;
>> + struct ehea_swqe *swqe;
>> + unsigned long flags;
>> + u32 lkey;
>> + int swqe_index;
>> +
>> + pr = &port->port_res[0];
>
> Initialization and declaration can happen at the same time.
Agreed.
>> + if (unlikely(atomic_read(&pr->swqe_avail) <= 1)) {
>> + spin_lock_irqsave(&pr->netif_queue, flags);
>> + if (unlikely(atomic_read(&pr->swqe_avail) <= 1)) {
>> + netif_stop_queue(dev);
>> + pr->queue_stopped = 1;
>> + spin_unlock_irqrestore(&pr->netif_queue, flags);
>> + return NETDEV_TX_BUSY;
>
> 1 - this is considered a severe bug. You should stop queueing before it
> happens.
> 2 - don't mix spinlocked sections and stealth return.
Fixed.
>> +port_res_setup_failed:
>> + for(k = 0; k < i; k++) {
>> + ehea_clean_port_res(port, &port->port_res[k]);
>
> Useless k ?
No, i is used as terminating condition and may not be reused as iterator
in this loop.
>> +int ehea_up(struct net_device *dev)
>> +int ehea_open(struct net_device *dev)
>
> static
Agreed.
>> +{
>> + int ret;
>> + struct ehea_port *port = netdev_priv(dev);
>> +
>> + down(&port->port_lock);
>> +
>> + if (netif_msg_ifup(port))
>> + ehea_info("enabling port %s", dev->name);
>> + ret = ehea_up(dev);
>
> Broken indent.
Fixed.
>> + dev->open = ehea_open;
>> + dev->poll = ehea_poll;
>> + dev->weight = 64;
>> + dev->stop = ehea_stop;
>> + dev->hard_start_xmit = ehea_start_xmit;
>> + dev->get_stats = ehea_get_stats;
>> + dev->set_multicast_list = ehea_set_multicast_list;
>> + dev->set_mac_address = ehea_set_mac_addr;
>> + dev->change_mtu = ehea_change_mtu;
>> + dev->vlan_rx_register = ehea_vlan_rx_register;
>> + dev->vlan_rx_add_vid = ehea_vlan_rx_add_vid;
>> + dev->vlan_rx_kill_vid = ehea_vlan_rx_kill_vid;
>> + dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
>> + | NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_TX
>> + | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER
>> + | NETIF_F_LLTX;
>> + dev->tx_timeout = &ehea_tx_watchdog;
>> + dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
>> +
>> + INIT_WORK(&port->reset_task,
>> + (void (*)(void *)) ehea_reset_port, dev);
>
> Why not modify ehea_reset_port ?
Done.
>> + ehea_set_ethtool_ops(dev);
>
> This function does not appear in the current patch.
It appears in [2.6.19 PATCH 4/7] ehea: ethtool interface
>> +int check_module_parm(void)
>
> static
Agreed.
>> + if ((rq1_entries < EHEA_MIN_ENTRIES_QP)
>> + || (rq1_entries > EHEA_MAX_ENTRIES_RQ1)) {
>
> || is misplaced.
Changed at all occurences.
>> +static struct of_device_id ehea_device_table[] = {
>> + {
>> + .name = "lhea",
>> + .compatible = "IBM,lhea",
>> + },
>
> Indent seems strange.
Fixed.
>> + printk("IBM eHEA ethernet device driver (Release %s)\n", DRV_VERSION);
>
> Missing KERN_XYZ
KERN_INFO set.
^ permalink raw reply
* On the transfer of data from the uart.c driver to the tty layer...
From: Alejandro C @ 2006-09-05 14:56 UTC (permalink / raw)
To: linuxppc-dev
Hi all,
I'm working on a the uart.c driver to add support for SCCs in HDLC mode. The
application I'm going to run on top will be sending Ethernet packets
encapsulated in the data field of an HDLC frame. The idea was to make the
buffer big enough so that a whole Eth. packet (max 1518 octects) could fit
in just one buffer. I let the CPM interrupt on a frame basis and the problem
I've come across is that the receive buffer in the struct tty_struct, where
the tty layer collects the data from the driver
(tty_struct.tty_flip_buffer.char_buf), is only 1024 bytes
(2*TTY_FLIPBUF_SIZE). The easiest at this stage would be to make those
buffers larger, but I don't know what sort of impact this might have... Any
tips?
Any ideas on how to solve it in another fashion?
Help will be highly appreciated.
Regards,
Alejandro
_________________________________________________________________
Acepta el reto MSN Premium: Correos más divertidos con fotos y textos
increíbles en MSN Premium. Descárgalo y pruébalo 2 meses gratis.
http://join.msn.com?XAPID=1697&DI=1055&HL=Footer_mailsenviados_correosmasdivertidos
^ permalink raw reply
* Re: OT: Re: [U-Boot-Users] Status of OF in TQM8540 and linux-2.6.17.11
From: Vitaly Bordug @ 2006-09-05 15:06 UTC (permalink / raw)
To: Clemens Koller; +Cc: u-boot-users, ppcembed, Mailing List
In-Reply-To: <44FD7B96.80405@anagramm.de>
On Tue, 05 Sep 2006 15:28:54 +0200
Clemens Koller <clemens.koller@anagramm.de> wrote:
> Hello, Wolfgang!
>
> -> moving from u-boot-users to linuxppc-embedded
>
> Wolfgang Denk wrote:
> > In message <44FD5BD4.9090406@anagramm.de> you wrote:
> >
> >>Now I try to boot a current linux kernel - the vanilla 2.6.17.11
> >>with the default tqm8540 config but it doesn't show any sign of life
> >
> > Please use the kernel from our repo instead; see
> > http://www.denx.de/cgi-bin/gitweb.cgi?p=linux-2.6-denx.git
>
> Okay, the compilation after a make TQM8540_defconfig fails:
>
> clemens@ecam:~/git/linux-2.6-denx$ make uImage
> CHK include/linux/version.h
> CHK include/linux/utsrelease.h
> SYMLINK include/asm -> include/asm-ppc
> CHK include/linux/compile.h
> CC arch/ppc/syslib/mpc85xx_devices.o
> In file included from arch/ppc/syslib/mpc85xx_devices.c:23:
> include/asm/cpm2.h:1193:1: warning: "FCC2_MEM_OFFSET" redefined
> include/asm/cpm2.h:1192:1: warning: this is the location of the previous definition
> arch/ppc/syslib/mpc85xx_devices.c:99: error: `F1_RXCLK' undeclared here (not in a function)
> arch/ppc/syslib/mpc85xx_devices.c:99: error: `F1_TXCLK' undeclared here (not in a function)
> arch/ppc/syslib/mpc85xx_devices.c:99: error: initializer element is not constant
> arch/ppc/syslib/mpc85xx_devices.c:99: error: (near initialization for `mpc85xx_fcc1_pdata.clk_route')
> arch/ppc/syslib/mpc85xx_devices.c:100: error: initializer element is not constant
> arch/ppc/syslib/mpc85xx_devices.c:100: error: (near initialization for `mpc85xx_fcc1_pdata.clk_trx')
> arch/ppc/syslib/mpc85xx_devices.c:117: error: `F2_RXCLK' undeclared here (not in a function)
> arch/ppc/syslib/mpc85xx_devices.c:117: error: `F2_TXCLK' undeclared here (not in a function)
> arch/ppc/syslib/mpc85xx_devices.c:117: error: initializer element is not constant
> arch/ppc/syslib/mpc85xx_devices.c:117: error: (near initialization for `mpc85xx_fcc2_pdata.clk_route')
> arch/ppc/syslib/mpc85xx_devices.c:118: error: initializer element is not constant
> arch/ppc/syslib/mpc85xx_devices.c:118: error: (near initialization for `mpc85xx_fcc2_pdata.clk_trx')
> arch/ppc/syslib/mpc85xx_devices.c:135: error: `F3_RXCLK' undeclared here (not in a function)
> arch/ppc/syslib/mpc85xx_devices.c:135: error: `F3_TXCLK' undeclared here (not in a function)
> arch/ppc/syslib/mpc85xx_devices.c:135: error: initializer element is not constant
> arch/ppc/syslib/mpc85xx_devices.c:135: error: (near initialization for `mpc85xx_fcc3_pdata.clk_route')
> arch/ppc/syslib/mpc85xx_devices.c:136: error: initializer element is not constant
> arch/ppc/syslib/mpc85xx_devices.c:136: error: (near initialization for `mpc85xx_fcc3_pdata.clk_trx')
> arch/ppc/syslib/mpc85xx_devices.c:138: error: `FCC3_MEM_OFFSET' undeclared here (not in a function)
> arch/ppc/syslib/mpc85xx_devices.c:138: error: initializer element is not constant
> arch/ppc/syslib/mpc85xx_devices.c:138: error: (near initialization for `mpc85xx_fcc3_pdata.mem_offset')
> make[1]: *** [arch/ppc/syslib/mpc85xx_devices.o] Error 1
> make: *** [arch/ppc/syslib] Error 2
>
> >>Are there any tips&tricks to consider regarding that point?
> >
> > Yes, use a working kernel. Not all our patches have been accepted
> > upstream, and we have some lag with re-submissions.
>
> According to TQC, the latest "working" kernel was a 2.6.15-git from your
> (denx) tree. I get the details from Mr. Becher@TQC and see how far I can get.
>
> Okay, let's move over to linux-ppc-embedded. (xposting)
The upper defines need to reside in the board-specific code for tqm as well as for other boards
utilizing such scheme (see platforms/85xx/mpc85xx_ads_common.h for instance).
Fix for FCC3_MEM_OFFSET was part of my patch series (as a typo fix), I'll submit it separately since
it's a notable bugfix should be in the mainstream.
--
Sincerely,
Vitaly
^ permalink raw reply
* OT: Re: [U-Boot-Users] Status of OF in TQM8540 and linux-2.6.17.11
From: Clemens Koller @ 2006-09-05 13:28 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: u-boot-users, ppcembed Mailing List
In-Reply-To: <20060905121957.CF13F353A15@atlas.denx.de>
Hello, Wolfgang!
-> moving from u-boot-users to linuxppc-embedded
Wolfgang Denk wrote:
> In message <44FD5BD4.9090406@anagramm.de> you wrote:
>
>>Now I try to boot a current linux kernel - the vanilla 2.6.17.11
>>with the default tqm8540 config but it doesn't show any sign of life
>
> Please use the kernel from our repo instead; see
> http://www.denx.de/cgi-bin/gitweb.cgi?p=linux-2.6-denx.git
Okay, the compilation after a make TQM8540_defconfig fails:
clemens@ecam:~/git/linux-2.6-denx$ make uImage
CHK include/linux/version.h
CHK include/linux/utsrelease.h
SYMLINK include/asm -> include/asm-ppc
CHK include/linux/compile.h
CC arch/ppc/syslib/mpc85xx_devices.o
In file included from arch/ppc/syslib/mpc85xx_devices.c:23:
include/asm/cpm2.h:1193:1: warning: "FCC2_MEM_OFFSET" redefined
include/asm/cpm2.h:1192:1: warning: this is the location of the previous definition
arch/ppc/syslib/mpc85xx_devices.c:99: error: `F1_RXCLK' undeclared here (not in a function)
arch/ppc/syslib/mpc85xx_devices.c:99: error: `F1_TXCLK' undeclared here (not in a function)
arch/ppc/syslib/mpc85xx_devices.c:99: error: initializer element is not constant
arch/ppc/syslib/mpc85xx_devices.c:99: error: (near initialization for `mpc85xx_fcc1_pdata.clk_route')
arch/ppc/syslib/mpc85xx_devices.c:100: error: initializer element is not constant
arch/ppc/syslib/mpc85xx_devices.c:100: error: (near initialization for `mpc85xx_fcc1_pdata.clk_trx')
arch/ppc/syslib/mpc85xx_devices.c:117: error: `F2_RXCLK' undeclared here (not in a function)
arch/ppc/syslib/mpc85xx_devices.c:117: error: `F2_TXCLK' undeclared here (not in a function)
arch/ppc/syslib/mpc85xx_devices.c:117: error: initializer element is not constant
arch/ppc/syslib/mpc85xx_devices.c:117: error: (near initialization for `mpc85xx_fcc2_pdata.clk_route')
arch/ppc/syslib/mpc85xx_devices.c:118: error: initializer element is not constant
arch/ppc/syslib/mpc85xx_devices.c:118: error: (near initialization for `mpc85xx_fcc2_pdata.clk_trx')
arch/ppc/syslib/mpc85xx_devices.c:135: error: `F3_RXCLK' undeclared here (not in a function)
arch/ppc/syslib/mpc85xx_devices.c:135: error: `F3_TXCLK' undeclared here (not in a function)
arch/ppc/syslib/mpc85xx_devices.c:135: error: initializer element is not constant
arch/ppc/syslib/mpc85xx_devices.c:135: error: (near initialization for `mpc85xx_fcc3_pdata.clk_route')
arch/ppc/syslib/mpc85xx_devices.c:136: error: initializer element is not constant
arch/ppc/syslib/mpc85xx_devices.c:136: error: (near initialization for `mpc85xx_fcc3_pdata.clk_trx')
arch/ppc/syslib/mpc85xx_devices.c:138: error: `FCC3_MEM_OFFSET' undeclared here (not in a function)
arch/ppc/syslib/mpc85xx_devices.c:138: error: initializer element is not constant
arch/ppc/syslib/mpc85xx_devices.c:138: error: (near initialization for `mpc85xx_fcc3_pdata.mem_offset')
make[1]: *** [arch/ppc/syslib/mpc85xx_devices.o] Error 1
make: *** [arch/ppc/syslib] Error 2
>>Are there any tips&tricks to consider regarding that point?
>
> Yes, use a working kernel. Not all our patches have been accepted
> upstream, and we have some lag with re-submissions.
According to TQC, the latest "working" kernel was a 2.6.15-git from your
(denx) tree. I get the details from Mr. Becher@TQC and see how far I can get.
Okay, let's move over to linux-ppc-embedded. (xposting)
Best greets,
Clemens Koller
_______________________________
R&D Imaging Devices
Anagramm GmbH
Rupert-Mayer-Str. 45/1
81379 Muenchen
Germany
http://www.anagramm.de
Phone: +49-89-741518-50
Fax: +49-89-741518-19
^ permalink raw reply
* Re: MPC5200B - FEC Error
From: Parav Pandit @ 2006-09-05 12:53 UTC (permalink / raw)
To: Ram Prasad H L, linuxppc-embedded
In-Reply-To: <000201c6d0b4$b6d08f50$4129320a@telxsi.com>
[-- Attachment #1: Type: text/plain, Size: 3263 bytes --]
Hi Ram Prasad,
Are you using the BEST COMM APIs in your driver?
I believe FEC driver needs some rework. Driver tries reinit the device in the interrupt handler itself from where your mpx5xxx_fec_reinit is called.
fec_reinit() calls fec_open() in the interrupt halder!
Also,
We did somewhat but is not complete yet.
If we closely look, I think, typical sequence is init() followed by open().
In case of reinit(), we missed something or miss to reconfigure something (Mostly the Tx, Rx queue) before we make call to open() similar to init().
Welll, on top of this, I am refering to 2.6.13 code base.
Regards,
Parav Pandit
Ram Prasad H L <hlrprasad@tataelxsi.co.in> wrote:
hi all,
this is Ramprasad, and we are using freescale's Lite5200B
using MPC5200B as core, for one of our applications.
The board is booted with u-boot-1.2.2 and linux kernel 2.4.25.
I'm finding a very peculiar problem with the board when I
run my application which extensively uses the FEC for receiving
video and audio streams from network. The application runs fine for
some time say 2-3 hrs and suddenly i'm getting the following error
and the OS starts rebooting.
The error log looks somewhat like this:
NIP: C0124ECC XER: 00000000 LR: C0125028 SP: C01B6270 REGS: c01b61c0 TRAP:
0300 Not tainted
MSR: 00001032 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DAR: 000000F0, DSISR: 20000000
TASK = c01b4470[0] 'swapper' Last syscall: 120
last math c228a000 last altivec 00000000
GPR00: 000000F0 C01B6270 C01B4470 00001032 00001032 00000006 C0C11034
C3C61CC0
GPR08: 0000003F 00000000 C01CE9F8 C01CEAD0 00000002 1012A714 03FBA000
00000000
GPR16: 00000001 00000001 FFFFFFFF 007FFF00 00001032 C3F93000 C0210000
00000000
GPR24: C3C06012 00000045 C01E0000 C0BE1320 0000054E C01CE9E0 C01CEA08
C3CA9A20
Call backtrace:
C0125528 C011AF0C C0006CD8 C0006D98 C0005C40 C00072C8 C00072E4
C0003918 C01CF5B8 000035F0
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
panic: Aiee, killing interrupt handler!
In interrupt handler - not syncing
<0>Rebooting in 180 seconds..<4>MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
Can anyone tell me what is the reason to face such
an error? and how can we avoid this error? any pointers
for overcoming it will be really helpfull as I'm stuck with
this problem since long time.
thanks and regards,
Ramprasad H L
_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded
---------------------------------
Yahoo! Messenger with Voice. Make PC-to-Phone Calls to the US (and 30+ countries) for 2¢/min or less.
[-- Attachment #2: Type: text/html, Size: 3976 bytes --]
^ permalink raw reply
* Re: MAC driver issues
From: Alex Zeffertt @ 2006-09-05 8:33 UTC (permalink / raw)
To: David H. Lynch Jr.; +Cc: linuxppc-embedded
In-Reply-To: <44FCA93E.1000009@dlasys.net>
Hi David,
I think in order to get any help from this list you need to be more specific
about how this problem relates to PowerPCs.
You also need to say exactly what "never gets handed off to the ARP protocol"
means.
FWIW, in my experience the hardware independent parts of the networking stack are
very stable and the problem is almost always with the drivers, or with the IP
configuration (e.g. two interfaces on the same subnet).
Alex
David H. Lynch Jr. wrote:
> I am trying to get a network driver working.
>
> It sends - I can capture the output with Etherreal and it looks good.
> It receives - I can dump the received packets when the come in and they
> look ok to me.
>
>
> BUT,
> If I try to ping another host, first Linux sends and ARP broadcast,
> the appropriate client sends an ARP response.
> Etherreal is happy with both.
> My driver gets the response - The driver says the packet lenght is
> 64 bytes, which includes something like 14 bytes of padding at the end.
> But the actual packet looks perfect exactly like what etherreal says
> it should (and what I get when I capture a received ARP packet in
> another driver).
> At the end of the recive interrupt the skb is passed to Linux with
> the netif_rc(ndev) function. This returns SUCCESS.
>
> However, the paket never gets handed of to the ARP protocol - I put
> some debugging in there and I never see it, while if I switch to a
> different NIC
> driver nearly the identical ARP packet gets processed by arp inside
> Linux.
>
> I have tried to chase this down, but I can't follow what is going
> on inside of all the /net/core/dev.c etc.
>
> Has anyone seen something similar to this ?
>
> Does anyone have a clue where I can find some info on trying to
> follow something through netif_rx to see where things are going off the
> rails ?
>
>
>
^ permalink raw reply
* MPC5200B - FEC Error
From: Ram Prasad H L @ 2006-09-05 6:30 UTC (permalink / raw)
To: linuxppc-embedded
hi all,
this is Ramprasad, and we are using freescale's Lite5200B
using MPC5200B as core, for one of our applications.
The board is booted with u-boot-1.2.2 and linux kernel 2.4.25.
I'm finding a very peculiar problem with the board when I
run my application which extensively uses the FEC for receiving
video and audio streams from network. The application runs fine for
some time say 2-3 hrs and suddenly i'm getting the following error
and the OS starts rebooting.
The error log looks somewhat like this:
NIP: C0124ECC XER: 00000000 LR: C0125028 SP: C01B6270 REGS: c01b61c0 TRAP:
0300 Not tainted
MSR: 00001032 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DAR: 000000F0, DSISR: 20000000
TASK = c01b4470[0] 'swapper' Last syscall: 120
last math c228a000 last altivec 00000000
GPR00: 000000F0 C01B6270 C01B4470 00001032 00001032 00000006 C0C11034
C3C61CC0
GPR08: 0000003F 00000000 C01CE9F8 C01CEAD0 00000002 1012A714 03FBA000
00000000
GPR16: 00000001 00000001 FFFFFFFF 007FFF00 00001032 C3F93000 C0210000
00000000
GPR24: C3C06012 00000045 C01E0000 C0BE1320 0000054E C01CE9E0 C01CEA08
C3CA9A20
Call backtrace:
C0125528 C011AF0C C0006CD8 C0006D98 C0005C40 C00072C8 C00072E4
C0003918 C01CF5B8 000035F0
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
panic: Aiee, killing interrupt handler!
In interrupt handler - not syncing
<0>Rebooting in 180 seconds..<4>MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
MPC5xxx_FEC_IEVENT_RFIFO_ERROR
mpc5xxx_fec_reinit
Can anyone tell me what is the reason to face such
an error? and how can we avoid this error? any pointers
for overcoming it will be really helpfull as I'm stuck with
this problem since long time.
thanks and regards,
Ramprasad H L
^ permalink raw reply
* Re: [POWERPC] merge iSeries i/o operations with the rest
From: Stephen Rothwell @ 2006-09-05 5:39 UTC (permalink / raw)
To: David Woodhouse; +Cc: ppc-dev, paulus
In-Reply-To: <1157432871.2413.9.camel@shinybook.infradead.org>
Hi David,
On Mon, 04 Sep 2006 22:07:50 -0700 David Woodhouse <dwmw2@infradead.org> wrote:
>
> On Tue, 2006-09-05 at 12:08 +1000, Stephen Rothwell wrote:
> > The low level i/o operations are now handled in iSeires by taking a
> > trap when we access the (inaccessible) io memory region and calling
> > the Hypervisor from the trap code.
>
> There was some discussion of the possibility of using the 'alternatives'
> mechanism to patch the I/O instructions at run-time when we find we've
> booted on iSeries -- just turning each one into a jump to a trampoline
> which does the appropriate hypervisor calls, thus avoiding the overhead
> of the trap each time.
>
> Was that approach not viable, or not noticeably less of a performance
> hit on iSeries?
It has not been tried, yet, as I need to hone my PPC assembler skills :-)
If the performance on iSeries is unacceptably worse (we need to get some
more testing done), then it would probably be worth while doing as you
suggested (or, equivalently, patching on first trap). This patch just
gets us along the way and may prove sufficient.
Note that the overhead of the trapping may not be as much as expected
since all i/o on iSeries has to be done with Hypervisor calls.
I have another version coming that modifies the inline assembler much
less, but may make the runtime patching approach slightly harder.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
^ permalink raw reply
* Re: [POWERPC] merge iSeries i/o operations with the rest
From: David Woodhouse @ 2006-09-05 5:07 UTC (permalink / raw)
To: Stephen Rothwell; +Cc: ppc-dev, paulus
In-Reply-To: <20060905120817.e52857ee.sfr@canb.auug.org.au>
On Tue, 2006-09-05 at 12:08 +1000, Stephen Rothwell wrote:
> The low level i/o operations are now handled in iSeires by taking a
> trap when we access the (inaccessible) io memory region and calling
> the Hypervisor from the trap code.
There was some discussion of the possibility of using the 'alternatives'
mechanism to patch the I/O instructions at run-time when we find we've
booted on iSeries -- just turning each one into a jump to a trampoline
which does the appropriate hypervisor calls, thus avoiding the overhead
of the trap each time.
Was that approach not viable, or not noticeably less of a performance
hit on iSeries?
--
dwmw2
^ permalink raw reply
* Re: [PATCH] Unwire set/get_robust_list
From: David Woodhouse @ 2006-09-05 4:53 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <17660.48525.873588.173047@cargo.ozlabs.ibm.com>
On Tue, 2006-09-05 at 09:58 +1000, Paul Mackerras wrote:
> Don't we need an access_ok() test in there? Otherwise, looks fine to
> me.
Oops, good point. Like this then...
Do we actually need the memory clobber, btw? We're not using this for
locking in kernel space.
[PATCH] Implement PowerPC futex_atomic_cmpxchg_inatomic().
The sys_[gs]et_robust_list() syscalls were wired up on PowerPC but
didn't work correctly because futex_atomic_cmpxchg_inatomic() wasn't
implemented. Implement it, based on __cmpxchg_u32()
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
diff --git a/include/asm-powerpc/futex.h b/include/asm-powerpc/futex.h
index f1b3c00..936422e 100644
--- a/include/asm-powerpc/futex.h
+++ b/include/asm-powerpc/futex.h
@@ -84,7 +84,33 @@ static inline int futex_atomic_op_inuser
static inline int
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
{
- return -ENOSYS;
+ int prev;
+
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+ return -EFAULT;
+
+ __asm__ __volatile__ (
+ LWSYNC_ON_SMP
+"1: lwarx %0,0,%2 # futex_atomic_cmpxchg_inatomic\n\
+ cmpw 0,%0,%3\n\
+ bne- 3f\n"
+ PPC405_ERR77(0,%2)
+"2: stwcx. %4,0,%2\n\
+ bne- 1b\n"
+ ISYNC_ON_SMP
+"3: .section .fixup,\"ax\"\n\
+4: li %0,%5\n\
+ b 3b\n\
+ .previous\n\
+ .section __ex_table,\"a\"\n\
+ .align 3\n\
+ " PPC_LONG "1b,4b,2b,4b\n\
+ .previous" \
+ : "=&r" (prev), "+m" (*uaddr)
+ : "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT)
+ : "cc", "memory");
+
+ return prev;
}
#endif /* __KERNEL__ */
--
dwmw2
^ permalink raw reply related
* Re: pci error recovery procedure
From: Zhang, Yanmin @ 2006-09-05 2:32 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Yanmin Zhang, LKML, Rajesh Shah, linuxppc-dev, linux-pci maillist
In-Reply-To: <1157360592.22705.46.camel@localhost.localdomain>
On Mon, 2006-09-04 at 17:03, Benjamin Herrenschmidt wrote:
> > As you know, all functions of a device share the same bus number and 5 bit dev number.
> > They just have different 3 bit function number. We could deduce if functions are in the same
> > device (slot).
>
> Until you have a P2P bridge ...
> > Thanks. Now I understand why you specified mmio_enabled and slot_reset. They are just
> > to map to pSeries platform hardware operation steps. I know little about pSeries hardware,
> > but is it possible to merge such hardware steps from software point of view?
>
> One of the ideas we had when defining those steps is to be precise
> enough to let drivers who _can_ deal with those fine grained pSeries
> step implement them, but also have the fallback to slot reset whenever
> possible.
>
> Now, if in practice, after actually implementing this in a number of
> drivers, we see that slot reset is the only ever used path, then we
> might want to simplify things a bit. I didn't want to impose that
> restriction in the initial design though.
Thanks for your explanation. Now it's the time to delete mmio_enabled
and merge slot_reset with resume.
>
> It's my understanding that doing no slot reset (hardware reset) but just
> re-enabling MMIO, DMA and clearing pending error status in the PCI
> config space is, as far as the driver is concerned, almost functionally
> equivalent to a PCIe link reset. That is, the link reset might not (or
> will not) actually reset the hardware beyond the PCIe link layer.
I agree.
>
> Thus we could simplify the split between link reset / hard reset. The
> former is an attempt at recovery with only resetting the PCI path to the
> device, which on PCIe becomes a link reset, and on old PCI, just
> clearing of the various error bits along the path (and on pSeries,
> re-enabling MMIO and DMA access). However, there is still the problem
> that if you do that, on pSeries at least, you really want to 1- enable
> MMIO, 2- soft reset the card using MMIO, that is make sure all pending
> DMA is stopped, and 3- re-enable DMA. While if we collapse that into a
> single 'link reset' type of operation, we'll end up re-enabling MMIO and
> DMA before the driver has a chance to stop pending DMA's
Is it the exclusive reason to have multi-steps?
1) Here link reset and hard reset are hardware operations, not the
link_reset and slot_reset callback in pci_error_handlers.
2) Callback error_detected will notify drivers there is PCI errors. Drivers
shouldn't do any I/O in error_detected.
3) If both the link and slot are reset after all error_detected are called,
the device should go back to initial status and all DMA should be stopped
automatically. Why does the driver still need a chance to stop DMA? The
error_detected of the drivers in the latest kernel who support err handlers
always returns PCI_ERS_RESULT_NEED_RESET. They are typical examples.
> and thus
> increase the chance that we crap out due to a pending DMA on the chip.
>
> Ben.
Above discussion is only about if mmio_enabled is needed.
As for slot_reset, I think it could be merged with resume, because platforms
do nothing between calling slot_reset and resume. Any comment?
Yanmin
^ permalink raw reply
* [POWERPC] merge iSeries i/o operations with the rest
From: Stephen Rothwell @ 2006-09-05 2:08 UTC (permalink / raw)
To: paulus; +Cc: ppc-dev
The low level i/o operations are now handled in iSeires by taking a
trap when we access the (inaccessible) io memory region and calling
the Hypervisor from the trap code. To accomplish this the inline
assembler code for mos of the operations is simplified to ease decoding
and emulation.
The memset_io/memcpy_(to,from)io routines just do a firmware feature
check as it will compile out in the non combined build case and in the
combined build, the extra check is a relatively small overhead.
The remainder of the routines are not used in the drivers for any
currently supported hardware on legacy iSeries, so juts use the eeh
versions (they used to BUG or were not even implemented).
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
arch/powerpc/mm/fault.c | 8 ++
arch/powerpc/platforms/iseries/pci.c | 140 +++++++++++++++++++-----------
include/asm-powerpc/io.h | 109 +++++++++++------------
include/asm-powerpc/iseries/iseries_io.h | 27 ------
include/asm-powerpc/ppc-pci.h | 11 ++
5 files changed, 159 insertions(+), 136 deletions(-)
This has been built for iSeries and pSeries and booted on iSeries. It
has a measurable performance impact on iSeries for the only real device I
have (a PCnet32 ethernet card - iperf throughput is reduced by about
4-5%). I have not booted this on pSeries much less tried to measure any
performance difference.
Comments welcome.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 78a0d59..e8add2b 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -38,6 +38,8 @@ #include <asm/uaccess.h>
#include <asm/tlbflush.h>
#include <asm/kdebug.h>
#include <asm/siginfo.h>
+#include <asm/firmware.h>
+#include <asm/ppc-pci.h>
#ifdef CONFIG_KPROBES
ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
@@ -185,8 +187,12 @@ #endif /* CONFIG_4xx || CONFIG_BOOKE */
}
/* On a kernel SLB miss we can only check for a valid exception entry */
- if (!user_mode(regs) && (address >= TASK_SIZE))
+ if (!user_mode(regs) && (address >= TASK_SIZE)) {
+ if (firmware_has_feature(FW_FEATURE_ISERIES) &&
+ iseries_handle_io_fault(regs, address))
+ return 0;
return SIGSEGV;
+ }
#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
if (error_code & DSISR_DABRMATCH) {
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index f4d427a..04b50d9 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -26,6 +26,7 @@ #include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>
#include <linux/pci.h>
+#include <linux/ptrace.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -38,6 +39,7 @@ #include <asm/abs_addr.h>
#include <asm/iseries/hv_call_xm.h>
#include <asm/iseries/mf.h>
#include <asm/iseries/iommu.h>
+#include <asm/iseries/iseries_io.h>
#include <asm/ppc-pci.h>
@@ -270,46 +272,6 @@ void pcibios_fixup_resources(struct pci_
}
/*
- * I/0 Memory copy MUST use mmio commands on iSeries
- * To do; For performance, include the hv call directly
- */
-void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count)
-{
- u8 ByteValue = c;
- long NumberOfBytes = Count;
-
- while (NumberOfBytes > 0) {
- iSeries_Write_Byte(ByteValue, dest++);
- -- NumberOfBytes;
- }
-}
-EXPORT_SYMBOL(iSeries_memset_io);
-
-void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count)
-{
- char *src = source;
- long NumberOfBytes = count;
-
- while (NumberOfBytes > 0) {
- iSeries_Write_Byte(*src++, dest++);
- -- NumberOfBytes;
- }
-}
-EXPORT_SYMBOL(iSeries_memcpy_toio);
-
-void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count)
-{
- char *dst = dest;
- long NumberOfBytes = count;
-
- while (NumberOfBytes > 0) {
- *dst++ = iSeries_Read_Byte(src++);
- -- NumberOfBytes;
- }
-}
-EXPORT_SYMBOL(iSeries_memcpy_fromio);
-
-/*
* Look down the chain to find the matching Device Device
*/
static struct device_node *find_Device_Node(int bus, int devfn)
@@ -491,7 +453,7 @@ static inline struct device_node *xlate_
* iSeries_Read_Word = Read Word (16 bit)
* iSeries_Read_Long = Read Long (32 bit)
*/
-u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
+static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -518,9 +480,8 @@ u8 iSeries_Read_Byte(const volatile void
return (u8)ret.value;
}
-EXPORT_SYMBOL(iSeries_Read_Byte);
-u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
+static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -548,9 +509,8 @@ u16 iSeries_Read_Word(const volatile voi
return swab16((u16)ret.value);
}
-EXPORT_SYMBOL(iSeries_Read_Word);
-u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
+static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -578,7 +538,6 @@ u32 iSeries_Read_Long(const volatile voi
return swab32((u32)ret.value);
}
-EXPORT_SYMBOL(iSeries_Read_Long);
/*
* Write MM I/O Instructions for the iSeries
@@ -587,7 +546,7 @@ EXPORT_SYMBOL(iSeries_Read_Long);
* iSeries_Write_Word = Write Word(16 bit)
* iSeries_Write_Long = Write Long(32 bit)
*/
-void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
+static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -612,9 +571,8 @@ void iSeries_Write_Byte(u8 data, volatil
rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
} while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
}
-EXPORT_SYMBOL(iSeries_Write_Byte);
-void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
+static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -639,9 +597,8 @@ void iSeries_Write_Word(u16 data, volati
rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
} while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
}
-EXPORT_SYMBOL(iSeries_Write_Word);
-void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
+static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
{
u64 BarOffset;
u64 dsa;
@@ -666,4 +623,83 @@ void iSeries_Write_Long(u32 data, volati
rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
} while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
}
-EXPORT_SYMBOL(iSeries_Write_Long);
+
+/*
+ * I/0 Memory copy MUST use mmio commands on iSeries
+ * To do; For performance, include the hv call directly
+ */
+void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count)
+{
+ u8 ByteValue = c;
+ long NumberOfBytes = Count;
+
+ while (NumberOfBytes > 0) {
+ iSeries_Write_Byte(ByteValue, dest++);
+ -- NumberOfBytes;
+ }
+}
+EXPORT_SYMBOL(iSeries_memset_io);
+
+void iSeries_memcpy_toio(volatile void __iomem *dest, const void *source,
+ size_t count)
+{
+ const char *src = source;
+ long NumberOfBytes = count;
+
+ while (NumberOfBytes > 0) {
+ iSeries_Write_Byte(*src++, dest++);
+ -- NumberOfBytes;
+ }
+}
+EXPORT_SYMBOL(iSeries_memcpy_toio);
+
+void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count)
+{
+ char *dst = dest;
+ long NumberOfBytes = count;
+
+ while (NumberOfBytes > 0) {
+ *dst++ = iSeries_Read_Byte(src++);
+ -- NumberOfBytes;
+ }
+}
+EXPORT_SYMBOL(iSeries_memcpy_fromio);
+
+int iseries_handle_io_fault(struct pt_regs *regs, unsigned long address)
+{
+ u32 instr;
+
+ /* is the address in out i/o range? */
+ if ((address < BASE_IO_MEMORY) || (address >= max_io_memory))
+ return 0;
+ /* we are only called for kernel mode faults */
+ instr = *(u32 *)regs->nip;
+ /* Is the major opcode 31 and target/source r0? */
+ if ((instr & 0xffe00000) != 0x7C000000)
+ return 0;
+
+ switch ((instr >> 1) & 0x3ff) {
+ case 87:
+ regs->gpr[0] = iSeries_Read_Byte((void __iomem *)address);
+ break;
+ case 215:
+ iSeries_Write_Byte(regs->gpr[0], (void __iomem *)address);
+ break;
+ case 790:
+ regs->gpr[0] = iSeries_Read_Word((void __iomem *)address);
+ break;
+ case 918:
+ iSeries_Write_Word(regs->gpr[0], (void __iomem *)address);
+ break;
+ case 534:
+ regs->gpr[0] = iSeries_Read_Long((void __iomem *)address);
+ break;
+ case 662:
+ iSeries_Write_Long(regs->gpr[0], (void __iomem *)address);
+ break;
+ default:
+ return 0;
+ }
+ regs->nip += 4;
+ return 1;
+}
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index 36c4c34..5420fac 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -19,11 +19,10 @@ #else
#include <linux/compiler.h>
#include <asm/page.h>
#include <asm/byteorder.h>
-#ifdef CONFIG_PPC_ISERIES
#include <asm/iseries/iseries_io.h>
-#endif
#include <asm/synch.h>
#include <asm/delay.h>
+#include <asm/firmware.h>
#include <asm-generic/iomap.h>
@@ -41,44 +40,10 @@ #define SLOW_DOWN_IO
extern unsigned long isa_io_base;
extern unsigned long pci_io_base;
-#ifdef CONFIG_PPC_ISERIES
-/* __raw_* accessors aren't supported on iSeries */
-#define __raw_readb(addr) { BUG(); 0; }
-#define __raw_readw(addr) { BUG(); 0; }
-#define __raw_readl(addr) { BUG(); 0; }
-#define __raw_readq(addr) { BUG(); 0; }
-#define __raw_writeb(v, addr) { BUG(); 0; }
-#define __raw_writew(v, addr) { BUG(); 0; }
-#define __raw_writel(v, addr) { BUG(); 0; }
-#define __raw_writeq(v, addr) { BUG(); 0; }
-#define readb(addr) iSeries_Read_Byte(addr)
-#define readw(addr) iSeries_Read_Word(addr)
-#define readl(addr) iSeries_Read_Long(addr)
-#define writeb(data, addr) iSeries_Write_Byte((data),(addr))
-#define writew(data, addr) iSeries_Write_Word((data),(addr))
-#define writel(data, addr) iSeries_Write_Long((data),(addr))
-#define memset_io(a,b,c) iSeries_memset_io((a),(b),(c))
-#define memcpy_fromio(a,b,c) iSeries_memcpy_fromio((a), (b), (c))
-#define memcpy_toio(a,b,c) iSeries_memcpy_toio((a), (b), (c))
-
-#define inb(addr) readb(((void __iomem *)(long)(addr)))
-#define inw(addr) readw(((void __iomem *)(long)(addr)))
-#define inl(addr) readl(((void __iomem *)(long)(addr)))
-#define outb(data,addr) writeb(data,((void __iomem *)(long)(addr)))
-#define outw(data,addr) writew(data,((void __iomem *)(long)(addr)))
-#define outl(data,addr) writel(data,((void __iomem *)(long)(addr)))
/*
- * The *_ns versions below don't do byte-swapping.
- * Neither do the standard versions now, these are just here
- * for older code.
+ * __raw_* accessors aren't supported on iSeries so
+ * these used to BUG() on iSeries, but that is not really necessary.
*/
-#define insb(port, buf, ns) _insb((u8 __iomem *)((port)+pci_io_base), (buf), (ns))
-#define insw(port, buf, ns) _insw_ns((u8 __iomem *)((port)+pci_io_base), (buf), (ns))
-#define insl(port, buf, nl) _insl_ns((u8 __iomem *)((port)+pci_io_base), (buf), (nl))
-#define insw_ns(port, buf, ns) _insw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
-#define insl_ns(port, buf, nl) _insl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
-#else
-
static inline unsigned char __raw_readb(const volatile void __iomem *addr)
{
return *(volatile unsigned char __force *)addr;
@@ -111,6 +76,7 @@ static inline void __raw_writeq(unsigned
{
*(volatile unsigned long __force *)addr = v;
}
+
#define readb(addr) eeh_readb(addr)
#define readw(addr) eeh_readw(addr)
#define readl(addr) eeh_readl(addr)
@@ -119,9 +85,6 @@ #define writeb(data, addr) eeh_writeb((d
#define writew(data, addr) eeh_writew((data), (addr))
#define writel(data, addr) eeh_writel((data), (addr))
#define writeq(data, addr) eeh_writeq((data), (addr))
-#define memset_io(a,b,c) eeh_memset_io((a),(b),(c))
-#define memcpy_fromio(a,b,c) eeh_memcpy_fromio((a),(b),(c))
-#define memcpy_toio(a,b,c) eeh_memcpy_toio((a),(b),(c))
#define inb(port) eeh_inb((unsigned long)port)
#define outb(val, port) eeh_outb(val, (unsigned long)port)
#define inw(port) eeh_inw((unsigned long)port)
@@ -140,8 +103,6 @@ #define insl(port, buf, nl) eeh_insl_ns(
#define insw_ns(port, buf, ns) eeh_insw_ns((port), (buf), (ns))
#define insl_ns(port, buf, nl) eeh_insl_ns((port), (buf), (nl))
-#endif
-
#define outsb(port, buf, ns) _outsb((u8 __iomem *)((port)+pci_io_base), (buf), (ns))
#define outsw(port, buf, ns) _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
#define outsl(port, buf, nl) _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
@@ -273,25 +234,30 @@ #define iobarrier_w() eieio()
* These routines do not perform EEH-related I/O address translation,
* and should not be used directly by device drivers. Use inb/readb
* instead.
+ *
+ * For some of these, we force the target/source register to be
+ * r0 to ease decoding on iSeries.
*/
static inline int in_8(const volatile unsigned char __iomem *addr)
{
- int ret;
+ register unsigned int ret __asm__("r0");
- __asm__ __volatile__("lbz%U1%X1 %0,%1; twi 0,%0,0; isync"
- : "=r" (ret) : "m" (*addr));
+ __asm__ __volatile__("lbzx %0,0,%1; twi 0,%0,0; isync"
+ : "=r" (ret) : "r" (addr));
return ret;
}
static inline void out_8(volatile unsigned char __iomem *addr, int val)
{
- __asm__ __volatile__("stb%U0%X0 %1,%0; sync"
- : "=m" (*addr) : "r" (val));
+ register unsigned int rval __asm__("r0") = val;
+
+ __asm__ __volatile__("stbx %0,0,%1; sync"
+ : : "r" (rval), "r" (addr));
}
static inline int in_le16(const volatile unsigned short __iomem *addr)
{
- int ret;
+ register unsigned int ret __asm__("r0");
__asm__ __volatile__("lhbrx %0,0,%1; twi 0,%0,0; isync"
: "=r" (ret) : "r" (addr), "m" (*addr));
@@ -309,8 +275,10 @@ static inline int in_be16(const volatile
static inline void out_le16(volatile unsigned short __iomem *addr, int val)
{
- __asm__ __volatile__("sthbrx %1,0,%2; sync"
- : "=m" (*addr) : "r" (val), "r" (addr));
+ register unsigned int rval __asm__("r0") = val;
+
+ __asm__ __volatile__("sthbrx %0,0,%1; sync"
+ : : "r" (rval), "r" (addr));
}
static inline void out_be16(volatile unsigned short __iomem *addr, int val)
@@ -321,7 +289,7 @@ static inline void out_be16(volatile uns
static inline unsigned in_le32(const volatile unsigned __iomem *addr)
{
- unsigned ret;
+ register unsigned int ret __asm__("r0");
__asm__ __volatile__("lwbrx %0,0,%1; twi 0,%0,0; isync"
: "=r" (ret) : "r" (addr), "m" (*addr));
@@ -339,8 +307,10 @@ static inline unsigned in_be32(const vol
static inline void out_le32(volatile unsigned __iomem *addr, int val)
{
- __asm__ __volatile__("stwbrx %1,0,%2; sync" : "=m" (*addr)
- : "r" (val), "r" (addr));
+ register unsigned int rval __asm__("r0") = val;
+
+ __asm__ __volatile__("stwbrx %1,0,%2; sync"
+ : "=m" (*addr) : "r" (rval), "r" (addr));
}
static inline void out_be32(volatile unsigned __iomem *addr, int val)
@@ -399,9 +369,34 @@ static inline void out_be64(volatile uns
__asm__ __volatile__("std%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val));
}
-#ifndef CONFIG_PPC_ISERIES
#include <asm/eeh.h>
-#endif
+
+static inline void memset_io(volatile void __iomem *addr, int c,
+ unsigned long n)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ iSeries_memset_io(addr, c, n);
+ else
+ eeh_memset_io(addr, c, n);
+}
+
+static inline void memcpy_fromio(void *dest, const volatile void __iomem *src,
+ unsigned long n)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ iSeries_memcpy_fromio(dest, src, n);
+ else
+ eeh_memcpy_fromio(dest, src, n);
+}
+
+static inline void memcpy_toio(volatile void __iomem *dest, const void *src,
+ unsigned long n)
+{
+ if (firmware_has_feature(FW_FEATURE_ISERIES))
+ iSeries_memcpy_toio(dest, src, n);
+ else
+ eeh_memcpy_toio(dest, src, n);
+}
/**
* check_signature - find BIOS signatures
@@ -417,7 +412,6 @@ static inline int check_signature(const
const unsigned char *signature, int length)
{
int retval = 0;
-#ifndef CONFIG_PPC_ISERIES
do {
if (readb(io_addr) != *signature)
goto out;
@@ -427,7 +421,6 @@ #ifndef CONFIG_PPC_ISERIES
} while (length);
retval = 1;
out:
-#endif
return retval;
}
diff --git a/include/asm-powerpc/iseries/iseries_io.h b/include/asm-powerpc/iseries/iseries_io.h
index f29009b..1b61c51 100644
--- a/include/asm-powerpc/iseries/iseries_io.h
+++ b/include/asm-powerpc/iseries/iseries_io.h
@@ -1,9 +1,5 @@
#ifndef _ASM_POWERPC_ISERIES_ISERIES_IO_H
#define _ASM_POWERPC_ISERIES_ISERIES_IO_H
-
-
-#ifdef CONFIG_PPC_ISERIES
-#include <linux/types.h>
/*
* Created by Allan Trautman on Thu Dec 28 2000.
*
@@ -30,31 +26,12 @@ #include <linux/types.h>
* Created December 28, 2000
* End Change Activity
*/
-
-#ifdef CONFIG_PCI
-extern u8 iSeries_Read_Byte(const volatile void __iomem * IoAddress);
-extern u16 iSeries_Read_Word(const volatile void __iomem * IoAddress);
-extern u32 iSeries_Read_Long(const volatile void __iomem * IoAddress);
-extern void iSeries_Write_Byte(u8 IoData, volatile void __iomem * IoAddress);
-extern void iSeries_Write_Word(u16 IoData, volatile void __iomem * IoAddress);
-extern void iSeries_Write_Long(u32 IoData, volatile void __iomem * IoAddress);
+#include <linux/types.h>
extern void iSeries_memset_io(volatile void __iomem *dest, char x, size_t n);
-extern void iSeries_memcpy_toio(volatile void __iomem *dest, void *source,
+extern void iSeries_memcpy_toio(volatile void __iomem *dest, const void *source,
size_t n);
extern void iSeries_memcpy_fromio(void *dest,
const volatile void __iomem *source, size_t n);
-#else
-static inline u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
-{
- return 0xff;
-}
-
-static inline void iSeries_Write_Byte(u8 IoData,
- volatile void __iomem *IoAddress)
-{
-}
-#endif /* CONFIG_PCI */
-#endif /* CONFIG_PPC_ISERIES */
#endif /* _ASM_POWERPC_ISERIES_ISERIES_IO_H */
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
index cf79bc7..db153ab 100644
--- a/include/asm-powerpc/ppc-pci.h
+++ b/include/asm-powerpc/ppc-pci.h
@@ -51,6 +51,17 @@ extern void pSeries_irq_bus_setup(struct
extern unsigned long pci_probe_only;
+/* From platforms/iseries/pci.c */
+#if defined(CONFIG_PPC_ISERIES) && defined(CONFIG_PCI)
+extern int iseries_handle_io_fault(struct pt_regs *regs, unsigned long address);
+#else
+static inline int iseries_handle_io_fault(struct pt_regs *regs,
+ unsigned long address)
+{
+ return 0;
+}
+#endif
+
/* ---- EEH internal-use-only related routines ---- */
#ifdef CONFIG_EEH
--
1.4.1.1
^ permalink raw reply related
* Re: [PATCH] Unwire set/get_robust_list
From: Paul Mackerras @ 2006-09-04 23:58 UTC (permalink / raw)
To: David Woodhouse; +Cc: linuxppc-dev
In-Reply-To: <1157409148.2473.209.camel@shinybook.infradead.org>
David Woodhouse writes:
> Something like this?
Don't we need an access_ok() test in there? Otherwise, looks fine to
me.
Thanks,
Paul.
^ permalink raw reply
* Re: [PATCH] Unwire set/get_robust_list
From: Andreas Schwab @ 2006-09-04 23:29 UTC (permalink / raw)
To: David Woodhouse; +Cc: linuxppc-dev
In-Reply-To: <1157409148.2473.209.camel@shinybook.infradead.org>
David Woodhouse <dwmw2@infradead.org> writes:
> On Mon, 2006-09-04 at 21:27 +0200, Andreas Schwab wrote:
>> The syscalls set/get_robust_list must not be wired up until
>> futex_atomic_cmpxchg_inatomic is implemented. Otherwise the kernel will
>> hang in handle_futex_death.
>
> Something like this?
>
> Untested-but-otherwise-Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Thanks, sucessfully tested on 32bit (with the nptl testsuite of glibc).
Will do some 64bit testing tomorrow.
Andreas.
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
^ permalink raw reply
* MAC driver issues
From: David H. Lynch Jr. @ 2006-09-04 22:31 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <Pine.LNX.4.60.0609042336020.5921@poirot.grange>
I am trying to get a network driver working.
It sends - I can capture the output with Etherreal and it looks good.
It receives - I can dump the received packets when the come in and they
look ok to me.
BUT,
If I try to ping another host, first Linux sends and ARP broadcast,
the appropriate client sends an ARP response.
Etherreal is happy with both.
My driver gets the response - The driver says the packet lenght is
64 bytes, which includes something like 14 bytes of padding at the end.
But the actual packet looks perfect exactly like what etherreal says
it should (and what I get when I capture a received ARP packet in
another driver).
At the end of the recive interrupt the skb is passed to Linux with
the netif_rc(ndev) function. This returns SUCCESS.
However, the paket never gets handed of to the ARP protocol - I put
some debugging in there and I never see it, while if I switch to a
different NIC
driver nearly the identical ARP packet gets processed by arp inside
Linux.
I have tried to chase this down, but I can't follow what is going
on inside of all the /net/core/dev.c etc.
Has anyone seen something similar to this ?
Does anyone have a clue where I can find some info on trying to
follow something through netif_rx to see where things are going off the
rails ?
--
Dave Lynch DLA Systems
Software Development: Embedded Linux
717.627.3770 dhlii@dlasys.net http://www.dlasys.net
fax: 1.253.369.9244 Cell: 1.717.587.7774
Over 25 years' experience in platforms, languages, and technologies too numerous to list.
"Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction."
Albert Einstein
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox