* Re: [PATCH] pasemi_mac: ethtool set settings support
From: David Miller @ 2009-10-12 11:25 UTC (permalink / raw)
To: olof; +Cc: linuxppc-dev, jgarzik, netdev
In-Reply-To: <20091006161123.GC29195@lixom.net>
From: Olof Johansson <olof@lixom.net>
Date: Tue, 6 Oct 2009 11:11:23 -0500
> On Mon, Oct 05, 2009 at 05:31:24PM +0400, Valentine Barshak wrote:
>> Add ethtool set settings to pasemi_mac_ethtool.
>>
>> Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com>
>
> Acked-by: Olof Johansson <olof@lixom.net>
Applied to net-next-2.6, thanks.
^ permalink raw reply
* Re: [v8 PATCH 1/8]: cpuidle: cleanup drivers/cpuidle/cpuidle.c
From: Balbir Singh @ 2009-10-12 11:36 UTC (permalink / raw)
To: Arun R Bharadwaj
Cc: linux-arch, Peter Zijlstra, linux-kernel, linux-acpi, Ingo Molnar,
linuxppc-dev, Arjan van de Ven
In-Reply-To: <20091008094942.GB20595@linux.vnet.ibm.com>
* Arun R B <arun@linux.vnet.ibm.com> [2009-10-08 15:19:42]:
> * Arun R Bharadwaj <arun@linux.vnet.ibm.com> [2009-10-08 15:18:28]:
>
> This patch cleans up drivers/cpuidle/cpuidle.c
> Earlier cpuidle assumed pm_idle as the default idle loop. Break that
> assumption and make it more generic. cpuidle_idle_call() which is the
> main idle loop of cpuidle is to be called by architectures which have
> registered to cpuidle.
>
> Remove routines cpuidle_install/uninstall_idle_handler() which are not
> needed anymore.
>
>
[snip]
/**
> - * cpuidle_install_idle_handler - installs the cpuidle idle loop handler
> - */
> -void cpuidle_install_idle_handler(void)
> -{
> - if (enabled_devices && (pm_idle != cpuidle_idle_call)) {
> - /* Make sure all changes finished before we switch to new idle */
> - smp_wmb();
> - pm_idle = cpuidle_idle_call;
> - }
> -}
> -
> -/**
> - * cpuidle_uninstall_idle_handler - uninstalls the cpuidle idle loop handler
> - */
> -void cpuidle_uninstall_idle_handler(void)
> -{
> - if (enabled_devices && pm_idle_old && (pm_idle != pm_idle_old)) {
> - pm_idle = pm_idle_old;
> - cpuidle_kick_cpus();
> - }
> -}
> -
I see the routines above being called in from
cpuidle_pause/resume_and_lock/unlock below and they are entries from
ACPI on ACPI_PROCESSOR_NOTIFY_POWER and from the hotplug path, could
you test them to make sure they are not broken. We also seem to be
missing a cpuidle_kick_cpus() in cpuidle_pause_and_lock()
[snip]
--
Balbir
^ permalink raw reply
* Linux seamless booting
From: Fortini Matteo @ 2009-10-12 11:07 UTC (permalink / raw)
To: u-boot; +Cc: linuxppc-dev
Hi all,
we've been working on a PPC512x board booting with u-boot + linux
2.6.24.6, and one major issue for our application is boot time.
Right now, we went down to less than 6s boot time (i.e. time from power
off to launch of the user app), even with some drivers installed, i.e.:
* CAN bus
* GPU on PCI bus
* USB host
* UBI
with r/o squashfs root and r/w ubifs configuration filesystem mounted
from a NOR flash memory.
This time could be enough for the high-level application (we're showing
a splash screen in about 2-3s so it's ok if the main app takes a little
longer to come up), but the whole system is connected to others via CAN
and we can't afford the "black out" period between u-boot and linux.
Some other operating systems (e.g. QNX) have this "seamless booting"
function, in which drivers are started in stages, so that a (minimal)
functionality can be given in milliseconds, and more functionalities
come up as time goes by.
Is there a way to support something similar with the u-boot -> linux
solution?
Thank you,
Matteo
^ permalink raw reply
* Re: [PATCH 1/1] powerpc/40x: Add new PPC440EPx based board HCU5 of Netstal Maschinen
From: Josh Boyer @ 2009-10-12 12:32 UTC (permalink / raw)
To: Niklaus Giger; +Cc: linuxppc-dev, niklaus.giger
In-Reply-To: <1255075865-4025-2-git-send-email-niklaus.giger@member.fsf.org>
On Fri, Oct 09, 2009 at 10:11:05AM +0200, Niklaus Giger wrote:
>Adds support for a HCU5 PPC405EPx based board from Netstal Maschinen AG.
Should be 440EPx, no?
Also, the subject should probably be "powerpc/44x". These are minor things,
not really a big deal. Overall, nice patch. See below for a few more
comments.
>+ UART0: serial@ef600300 {
>+ device_type = "serial";
>+ compatible = "ns16550";
>+ reg = <0xef600300 0x00000008>;
>+ virtual-reg = <0xef600300>;
>+ clock-frequency = <0>; /* Filled in by U-Boot */
>+ current-speed = <0>; /* Filled in by U-Boot */
I've been considering dropping the current-speed property entirely in most
4xx boards. Given that you have a bootargs specified in chosen that explicitly
tells the kernel to use 115200, do you think you could drop this property and
see how things work?
>+ interrupt-parent = <&UIC0>;
>+ interrupts = <0x0 0x4>;
>+ };
>+
>+ IIC0: i2c@ef600700 {
>+ #address-cells = <1>;
>+ #size-cells = <0>;
>+ compatible = "ibm,iic-440epx", "ibm,iic";
>+ reg = <0xef600700 0x00000014>;
>+ interrupt-parent = <&UIC0>;
>+ interrupts = <0x2 0x4>;
>+ };
>+
>+ IIC1: i2c@ef600800 {
>+ #address-cells = <1>;
>+ #size-cells = <0>;
>+ compatible = "ibm,iic-440epx", "ibm,iic";
>+ reg = <0xef600800 0x00000014>;
>+ interrupt-parent = <&UIC0>;
>+ interrupts = <0x7 0x4>;
>+ };
>+
>+
>+ ZMII0: emac-zmii@ef600d00 {
>+ compatible = "ibm,zmii-440epx", "ibm,zmii";
>+ reg = <0xef600d00 0x0000000c>;
>+ };
>+
>+ SMII0: emac-smii@ef601000 {
>+ compatible = "ibm,smii-440epx", "ibm,smmii";
>+ reg = <0xef601000 0x00000008>;
>+ has-mdio;
>+ };
>+
>+ EMAC0: ethernet@ef600e00 {
>+ device_type = "network";
>+ compatible = "ibm,emac-440epx", "ibm,emac4";
>+ interrupt-parent = <&EMAC0>;
>+ interrupts = <0x0 0x1>;
>+ #interrupt-cells = <1>;
>+ #address-cells = <0>;
>+ #size-cells = <0>;
>+ interrupt-map = </*Status*/ 0x0 &UIC0 0x18 0x4
>+ /*Wake*/ 0x1 &UIC1 0x1d 0x4>;
>+ reg = <0xef600e00 0x00000074>;
>+ local-mac-address = [000000000000];
>+ mal-device = <&MAL0>;
>+ mal-tx-channel = <0>;
>+ mal-rx-channel = <0>;
>+ cell-index = <0>;
>+ max-frame-size = <9000>;
>+ rx-fifo-size = <4096>;
>+ tx-fifo-size = <2048>;
>+ phy-mode = "smii";
>+ phy-map = <1>;
>+ zmii-device = <&ZMII0>;
>+ zmii-channel = <0>;
>+ has-inverted-stacr-oc;
>+ has-new-stacr-staopc;
>+ };
>+
>+ CPLD: cpld@0xcd000000 {
>+ reg = <0xcd000000 0x00000100>;
>+ interval = "1000";
>+ device_type = "cpld";
Should drop the device_type.
>+ interrupt-parent = <&UIC1>;
>+ interrupts = <28 8>; /* 8 is IRQ_TYPE_LEVEL_LOW */
>+ };
>+
>+ /* The HCU5 has two Intel CAN SCC82527 controllers */
>+ CAN1: can0@0xc8000000 {
>+ device_type = "can1";
Same comment here and for the one below as well.
>+ compatible = "intel,82527";
>+ reg = <0xc800000 0x00000100>;
>+ interrupt-parent = <&UIC2>;
>+ interrupts = <3 8>; /* 8 is IRQ_TYPE_LEVEL_LOW */
>+ };
>+
>+ CAN2: can1@0xc8000100 {
>+ device_type = "can2";
>+ compatible = "intel,82527";
>+ reg = <0xc8000100 0x00000100>;
>+ interrupt-parent = <&UIC2>;
>+ interrupts = <4 8>; /* 8 is IRQ_TYPE_LEVEL_LOW */
>+ };
>+
>+ };
>+
>+ };
>+
>+ chosen {
>+ linux,stdout-path = "/plb/opb/serial@ef600300";
>+ bootargs = "console=ttyS0,115200";
>+ };
>+};
>+# Platform support
>+#
>+# CONFIG_PPC_CELL is not set
>+# CONFIG_PPC_CELL_NATIVE is not set
>+# CONFIG_PQ2ADS is not set
>+CONFIG_BAMBOO=y
>+# CONFIG_EBONY is not set
>+CONFIG_HCU5=y
You have both bamboo and hcu5 enabled...
>+# CONFIG_SAM440EP is not set
>+# CONFIG_SEQUOIA is not set
>+# CONFIG_TAISHAN is not set
>+# CONFIG_KATMAI is not set
>+# CONFIG_RAINIER is not set
>+# CONFIG_WARP is not set
>+# CONFIG_ARCHES is not set
>+# CONFIG_CANYONLANDS is not set
>+# CONFIG_GLACIER is not set
>+# CONFIG_REDWOOD is not set
>+# CONFIG_EIGER is not set
>+# CONFIG_YOSEMITE is not set
>+# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
>+CONFIG_PPC44x_SIMPLE=y
>+# CONFIG_PPC4xx_GPIO is not set
>+CONFIG_440EP=y
>+CONFIG_440EPX=y
>+CONFIG_IBM440EP_ERR42=y
And both 440EP and 440EPx? Just curious as to why.
>+#
>+# Bus options
>+#
>+CONFIG_ZONE_DMA=y
>+CONFIG_PPC_INDIRECT_PCI=y
>+CONFIG_4xx_SOC=y
>+CONFIG_PPC_PCI_CHOICE=y
>+CONFIG_PCI=y
>+CONFIG_PCI_DOMAINS=y
>+CONFIG_PCI_SYSCALL=y
You have PCI enabled, but no PCI device nodes in your DTS.
>diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
>index 7486bff..cbf3601 100644
>--- a/arch/powerpc/platforms/44x/Kconfig
>+++ b/arch/powerpc/platforms/44x/Kconfig
>@@ -18,6 +18,15 @@ config EBONY
> help
> This option enables support for the IBM PPC440GP evaluation board.
>
>+config HCU5
>+ bool "Hcu5"
>+ depends on 44x
>+ default n
>+ select PPC44x_SIMPLE
I don't think you need to select this here. PPC44x_SIMPLE is for boards that
don't have their own .c file.
>+ select 440EPX
>+ help
>+ This option enables support for the Netstal Maschinen HCU5 board.
>+
> config SAM440EP
> bool "Sam440ep"
> depends on 44x
>diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile
>index ee6185a..5263595 100644
>--- a/arch/powerpc/platforms/44x/Makefile
>+++ b/arch/powerpc/platforms/44x/Makefile
>@@ -1,6 +1,7 @@
> obj-$(CONFIG_44x) := misc_44x.o idle.o
> obj-$(CONFIG_PPC44x_SIMPLE) += ppc44x_simple.o
> obj-$(CONFIG_EBONY) += ebony.o
>+obj-$(CONFIG_HCU5) += hcu5.o
> obj-$(CONFIG_SAM440EP) += sam440ep.o
> obj-$(CONFIG_WARP) += warp.o
> obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
>diff --git a/arch/powerpc/platforms/44x/hcu5.c b/arch/powerpc/platforms/44x/hcu5.c
>new file mode 100644
>index 0000000..1248a84
>--- /dev/null
>+++ b/arch/powerpc/platforms/44x/hcu5.c
>@@ -0,0 +1,153 @@
>+/*
>+ * arch/ppc/platforms/4xx/hcu5.c
>+ *
>+ * HCU5 board specific routines
>+ *
>+ * Copyright (c) 2009 Niklaus Giger <niklaus.giger@member.fsf.org>
>+ *
>+ * Copyright 2006-2007 DENX Software Engineering, Stefan Roese <sr@denx.de>
>+ *
>+ * Based on bamboo.c from Wade Farnsworth <wfarnsworth@mvista.com>
>+ * Copyright 2004 MontaVista Software Inc.
>+ * Copyright 2006 AMCC
>+ *
>+ * This program is free software; you can redistribute it and/or modify it
>+ * under the terms of the GNU General Public License as published by the
>+ * Free Software Foundation; either version 2 of the License, or (at your
>+ * option) any later version.
>+ *
>+ */
>+
>+#include <asm/machdep.h>
>+#include <asm/pci-bridge.h>
>+#include <asm/ppc4xx.h>
>+#include <asm/prom.h>
>+#include <asm/time.h>
>+#include <asm/udbg.h>
>+#include <asm/uic.h>
>+
>+#include <linux/init.h>
>+#include <linux/of_platform.h>
>+#include <linux/of_device.h>
>+#include <asm/irq.h>
>+#include <linux/types.h>
>+#include <linux/interrupt.h>
>+#include <asm/device.h>
>+
>+static int __init hcu5_probe(void);
>+#define debug printk
We have a pr_debug already. Could you use that? As it stands now this does
nothing more than s/printk/debug, which seems unecessary unless you meant for
it to be switchable.
>+/* HCU5 tick-status und tick-ontrol-register definitions */
>+#define CFG_CS_2 0xCC000000
>+#define CFG_CPLD CFG_CS_2
>+#define HCU_TICK_CONTROL_REGISTER_ADDRESS (CFG_CPLD + 0x1000000)
>+
>+#define TICK_INTERRUPT_ON_HCU5 60 /* UIC1, 28, GPIO40, IRQ0 */
>+#define CAN1_INTERRUPT_ON_HCU5 67 /* UIC2, 3 GPIO42 IRQ2 */
>+#define CAN2_INTERRUPT_ON_HCU5 68 /* UIC3, 4 GPIO43 IRQ3 */
>+
>+#define TICK_INT_ENABLE 0x01
>+#define TICK_INT_RESET 0x02
>+#define TICK_INT_PENDING 0x04
>+#define TICK_START 0x08
>+
>+#define TICK_INTERVAL_250_US 0x00
>+#define TICK_INTERVAL_500_US 0x10
>+#define TICK_INTERVAL_1000_US 0x20
>+#define TICK_INTERVAL_2000_US 0x30
>+
>+static u16 __iomem *tickAddr;
>+
>+static irqreturn_t cpld_interrupt(int irq, void *dev_id)
>+{
>+ /*
>+ out_be16(HCU_TICK_CONTROL_REGISTER_ADDRESS,
>+ TICK_INT_ENABLE | TICK_INT_RESET | TICK_START |
>+ TICK_INTERVAL_1000_US);
>+ */
>+ return 0;
>+}
>+
>+static irqreturn_t can1_interrupt(int irq, void *dev_id)
>+{
>+ return 0;
>+}
>+
>+static irqreturn_t can2_interrupt(int irq, void *dev_id)
>+{
>+ return 0;
>+}
>+
>+static int map_one_irq(const char *typeName, void *proc)
>+{
>+ struct device_node *np;
>+ int irq = 0;
>+ int rc;
>+
>+ np = of_find_node_by_type(NULL, typeName);
Use of_find_compatible_node and specify proper compatible properties instead.
>+ debug(KERN_INFO "%s: %s np %p\n", __func__, typeName, np);
>+ if (!np) {
>+ printk(KERN_INFO "\n\nNo %s found in device tree\n", typeName);
>+ return -1;
>+ }
>+
>+ irq = irq_of_parse_and_map(np, 0);
>+ debug(KERN_INFO "%s: %s with irq %d\n", __func__, typeName, irq);
>+ if (irq == NO_IRQ) {
>+ printk(KERN_ERR "%s: irq_of_parse_and_map failed\n", typeName);
>+ of_node_put(np);
>+ return -ENODEV;
>+ }
>+ rc = request_irq(irq, proc, IRQF_TRIGGER_LOW,
>+ typeName, NULL);
>+ debug(KERN_INFO"%s: %s %d rc %d\n",
>+ __func__, typeName, irq, rc);
>+ return 0;
>+}
>+
>+static __initdata struct of_device_id hcu5_of_bus[] = {
>+ { .compatible = "ibm,plb4", },
>+ { .compatible = "ibm,opb", },
>+ { .compatible = "ibm,ebc", },
>+ { .compatible = "simple-bus", },
>+ {},
>+};
>+
>+static int __init hcu5_device_probe(void)
>+{
>+ of_platform_bus_probe(NULL, hcu5_of_bus, NULL);
>+ tickAddr = ioremap(HCU_TICK_CONTROL_REGISTER_ADDRESS, 0x100);
>+ printk(KERN_INFO "%s: tickAddr is at %p from 0x%x\n", __func__,
>+ tickAddr, HCU_TICK_CONTROL_REGISTER_ADDRESS);
>+ map_one_irq("cpld", cpld_interrupt);
>+ map_one_irq("can1", can1_interrupt);
>+ map_one_irq("can2", can2_interrupt);
>+
>+ return 0;
>+}
>+
>+machine_device_initcall(hcu5, hcu5_device_probe);
>+
>+/*
>+* Called very early, MMU is off, device-tree isn't unflattened
>+*/
>+static int __init hcu5_probe(void)
>+{
>+ unsigned long root = of_get_flat_dt_root();
>+
>+ if (!of_flat_dt_is_compatible(root, "netstal,hcu5"))
>+ return 0;
>+ ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
Do you need this line at all? You don't have PCI nodes...
>+ return 1;
>+}
>+
josh
^ permalink raw reply
* Re: [PATCH] powerpc/40x: Cleanups for HCU4 board
From: Josh Boyer @ 2009-10-12 12:34 UTC (permalink / raw)
To: Niklaus Giger; +Cc: linuxppc-dev, niklaus.giger
In-Reply-To: <1255117658-3889-1-git-send-email-niklaus.giger@member.fsf.org>
On Fri, Oct 09, 2009 at 09:47:38PM +0200, Niklaus Giger wrote:
>- hcu4.dts: Added definitions for 2 CAN (Intel 82527)
>- hcu4.c: Some code for CPLD (special HW clock) and 2 CAN (Intel 82527)
Same comments here as in the HCU5 patch. Drop the device_type for cpld and
can, and use compatible properties please.
josh
^ permalink raw reply
* [PATCH] spufs: Fix test in spufs_switch_log_read()
From: Roel Kluin @ 2009-10-12 13:12 UTC (permalink / raw)
To: Jeremy Kerr, linuxppc-dev, cbe-oss-dev, Andrew Morton
size_t len cannot be less than 0.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
Or can this test be removed?
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 884e8bc..d4f304f 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -2494,7 +2494,7 @@ static ssize_t spufs_switch_log_read(struct file *file, char __user *buf,
struct spu_context *ctx = SPUFS_I(inode)->i_ctx;
int error = 0, cnt = 0;
- if (!buf || len < 0)
+ if (!buf || (ssize_t)len < 0)
return -EINVAL;
error = spu_acquire(ctx);
^ permalink raw reply related
* Re: Linux seamless booting
From: Roberto Guerra @ 2009-10-12 13:23 UTC (permalink / raw)
To: Fortini Matteo; +Cc: u-boot, linuxppc-dev
In-Reply-To: <4AD30DF0.1000901@mta.it>
Did you try "setenv bootdelay 0" in uboot?
On Mon, Oct 12, 2009 at 7:07 AM, Fortini Matteo <matteo.fortini@mta.it> wro=
te:
> Hi all,
> we've been working on a PPC512x board booting with u-boot + linux 2.6.24.=
6,
> and one major issue for our application is boot time.
>
> Right now, we went down to less than 6s boot time (i.e. time from power o=
ff
> to launch of the user app), even with some drivers installed, i.e.:
>
> =A0 * CAN bus
> =A0 * GPU on PCI bus
> =A0 * USB host
> =A0 * UBI
>
> with r/o squashfs root and r/w ubifs configuration filesystem mounted fro=
m a
> NOR flash memory.
>
> This time could be enough for the high-level application (we're showing a
> splash screen in about 2-3s so it's ok if the main app takes a little lon=
ger
> to come up), but the whole system is connected to others via CAN and we
> can't afford the "black out" period between u-boot and linux.
>
> Some other operating systems (e.g. QNX) have this "seamless booting"
> function, in which drivers are started in stages, so that a (minimal)
> functionality can be given in milliseconds, and more functionalities come=
up
> as time goes by.
>
> Is there a way to support something similar with the u-boot -> linux
> solution?
>
> Thank you,
> Matteo
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
^ permalink raw reply
* Re: linux booting fails on ppc440x5 with SRAM
From: Vineeth _ @ 2009-10-12 13:34 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: Johnny Hung, linuxppc-dev
In-Reply-To: <20091009113338.2B7E3E84EBC@gemini.denx.de>
Hi Wolfgang,
The link says about the initialization of the SDRAM; Does it
applicable in our case, where we have SRAM on our board. Does the
initialization means just clearing the memory in case of SRAM ? We
tried clearing the memory before the operation which doesnt work too.
We are creating a TLB of 16MB for the SRAM which is not cachable .
-Vineeth
On Fri, Oct 9, 2009 at 5:03 PM, Wolfgang Denk <wd@denx.de> wrote:
> Dear Vineeth _,
>
> In message <a9b543570910090320t1444f8f1qf4c8ab7dbbef679f@mail.gmail.com> =
you wrote:
>> We ported the uboot Memory test and tested the 15MB ram and it was
>> successful.interestingly we have only 16MB SRAM in our board.We used 1
>
> Such a memory test means nothing. The only thing you can learn from it
> is that basic read and write accesses are working. You don;t get any
> information about the behaviour for burst mode accesses from such a
> test. See the FAQ at
> http://www.denx.de/wiki/view/DULG/LinuxCrashesRandomly =A0and at
> http://www.denx.de/wiki/DULG/UBootCrashAfterRelocation
>
> Best regards,
>
> Wolfgang Denk
>
> --
> DENX Software Engineering GmbH, =A0 =A0 MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
> I mean, I . . . think to understand you, I just don't know =A0what =A0you
> are saying ... =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0- Terry Pra=
tchett, _Soul Music_
>
^ permalink raw reply
* Re: Linux seamless booting
From: Fortini Matteo @ 2009-10-12 13:54 UTC (permalink / raw)
To: Roberto Guerra; +Cc: u-boot@lists.denx.de, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <7c4144600910120623k2c9aea89ia0f255164f03ff89@mail.gmail.com>
Yes, that's what we're currently using, but the problem is a little
broader: I should answer to CAN messages in at most 100-200ms from
powerup, and that can be done in u-boot.
However, handing CAN transmission control over to Linux is quite
complicated nowadays, since it would involve passing structures in
memory and hacking through device init.
It'd be nice to have a framework with which u-boot could hand-over
devices to Linux in a clean and defined way.
We were thinking about starting some kind of development in that
direction, but with very little resources, so I was looking for someone
who had looked at the same problem.
Thanks,
Matteo
Roberto Guerra ha scritto:
> Did you try "setenv bootdelay 0" in uboot?
>
> On Mon, Oct 12, 2009 at 7:07 AM, Fortini Matteo <matteo.fortini@mta.it> wrote:
>
>> Hi all,
>> we've been working on a PPC512x board booting with u-boot + linux 2.6.24.6,
>> and one major issue for our application is boot time.
>>
>> Right now, we went down to less than 6s boot time (i.e. time from power off
>> to launch of the user app), even with some drivers installed, i.e.:
>>
>> * CAN bus
>> * GPU on PCI bus
>> * USB host
>> * UBI
>>
>> with r/o squashfs root and r/w ubifs configuration filesystem mounted from a
>> NOR flash memory.
>>
>> This time could be enough for the high-level application (we're showing a
>> splash screen in about 2-3s so it's ok if the main app takes a little longer
>> to come up), but the whole system is connected to others via CAN and we
>> can't afford the "black out" period between u-boot and linux.
>>
>> Some other operating systems (e.g. QNX) have this "seamless booting"
>> function, in which drivers are started in stages, so that a (minimal)
>> functionality can be given in milliseconds, and more functionalities come up
>> as time goes by.
>>
>> Is there a way to support something similar with the u-boot -> linux
>> solution?
>>
>> Thank you,
>> Matteo
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>>
>>
> .
>
>
^ permalink raw reply
* [PATCH] of/platform: Implement support for dev_pm_ops
From: Anton Vorontsov @ 2009-10-12 15:50 UTC (permalink / raw)
To: Grant Likely, Benjamin Herrenschmidt; +Cc: linuxppc-dev, linux-pm, David Miller
Linux power management subsystem supports vast amount of new PM
callbacks that are crucial for proper suspend and hibernation support
in drivers.
This patch implements support for dev_pm_ops, preserving support
for legacy callbacks.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/of/platform.c | 305 ++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 290 insertions(+), 15 deletions(-)
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 298de0f..d58ade1 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -65,47 +65,322 @@ static int of_platform_device_remove(struct device *dev)
return 0;
}
-static int of_platform_device_suspend(struct device *dev, pm_message_t state)
+static void of_platform_device_shutdown(struct device *dev)
{
struct of_device *of_dev = to_of_device(dev);
struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
- int error = 0;
- if (dev->driver && drv->suspend)
- error = drv->suspend(of_dev, state);
- return error;
+ if (dev->driver && drv->shutdown)
+ drv->shutdown(of_dev);
}
-static int of_platform_device_resume(struct device * dev)
+#ifdef CONFIG_PM_SLEEP
+
+static int of_platform_legacy_suspend(struct device *dev, pm_message_t mesg)
{
struct of_device *of_dev = to_of_device(dev);
struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
- int error = 0;
+ int ret = 0;
- if (dev->driver && drv->resume)
- error = drv->resume(of_dev);
- return error;
+ if (dev->driver && drv->suspend)
+ ret = drv->suspend(of_dev, mesg);
+ return ret;
}
-static void of_platform_device_shutdown(struct device *dev)
+static int of_platform_legacy_resume(struct device *dev)
{
struct of_device *of_dev = to_of_device(dev);
struct of_platform_driver *drv = to_of_platform_driver(dev->driver);
+ int ret = 0;
- if (dev->driver && drv->shutdown)
- drv->shutdown(of_dev);
+ if (dev->driver && drv->resume)
+ ret = drv->resume(of_dev);
+ return ret;
+}
+
+static int of_platform_pm_prepare(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (drv && drv->pm && drv->pm->prepare)
+ ret = drv->pm->prepare(dev);
+
+ return ret;
+}
+
+static void of_platform_pm_complete(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+
+ if (drv && drv->pm && drv->pm->complete)
+ drv->pm->complete(dev);
+}
+
+#ifdef CONFIG_SUSPEND
+
+static int of_platform_pm_suspend(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->suspend)
+ ret = drv->pm->suspend(dev);
+ } else {
+ ret = of_platform_legacy_suspend(dev, PMSG_SUSPEND);
+ }
+
+ return ret;
}
+static int of_platform_pm_suspend_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->suspend_noirq)
+ ret = drv->pm->suspend_noirq(dev);
+ }
+
+ return ret;
+}
+
+static int of_platform_pm_resume(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->resume)
+ ret = drv->pm->resume(dev);
+ } else {
+ ret = of_platform_legacy_resume(dev);
+ }
+
+ return ret;
+}
+
+static int of_platform_pm_resume_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->resume_noirq)
+ ret = drv->pm->resume_noirq(dev);
+ }
+
+ return ret;
+}
+
+#else /* !CONFIG_SUSPEND */
+
+#define of_platform_pm_suspend NULL
+#define of_platform_pm_resume NULL
+#define of_platform_pm_suspend_noirq NULL
+#define of_platform_pm_resume_noirq NULL
+
+#endif /* !CONFIG_SUSPEND */
+
+#ifdef CONFIG_HIBERNATION
+
+static int of_platform_pm_freeze(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->freeze)
+ ret = drv->pm->freeze(dev);
+ } else {
+ ret = of_platform_legacy_suspend(dev, PMSG_FREEZE);
+ }
+
+ return ret;
+}
+
+static int of_platform_pm_freeze_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->freeze_noirq)
+ ret = drv->pm->freeze_noirq(dev);
+ }
+
+ return ret;
+}
+
+static int of_platform_pm_thaw(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->thaw)
+ ret = drv->pm->thaw(dev);
+ } else {
+ ret = of_platform_legacy_resume(dev);
+ }
+
+ return ret;
+}
+
+static int of_platform_pm_thaw_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->thaw_noirq)
+ ret = drv->pm->thaw_noirq(dev);
+ }
+
+ return ret;
+}
+
+static int of_platform_pm_poweroff(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->poweroff)
+ ret = drv->pm->poweroff(dev);
+ } else {
+ ret = of_platform_legacy_suspend(dev, PMSG_HIBERNATE);
+ }
+
+ return ret;
+}
+
+static int of_platform_pm_poweroff_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->poweroff_noirq)
+ ret = drv->pm->poweroff_noirq(dev);
+ }
+
+ return ret;
+}
+
+static int of_platform_pm_restore(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->restore)
+ ret = drv->pm->restore(dev);
+ } else {
+ ret = of_platform_legacy_resume(dev);
+ }
+
+ return ret;
+}
+
+static int of_platform_pm_restore_noirq(struct device *dev)
+{
+ struct device_driver *drv = dev->driver;
+ int ret = 0;
+
+ if (!drv)
+ return 0;
+
+ if (drv->pm) {
+ if (drv->pm->restore_noirq)
+ ret = drv->pm->restore_noirq(dev);
+ }
+
+ return ret;
+}
+
+#else /* !CONFIG_HIBERNATION */
+
+#define of_platform_pm_freeze NULL
+#define of_platform_pm_thaw NULL
+#define of_platform_pm_poweroff NULL
+#define of_platform_pm_restore NULL
+#define of_platform_pm_freeze_noirq NULL
+#define of_platform_pm_thaw_noirq NULL
+#define of_platform_pm_poweroff_noirq NULL
+#define of_platform_pm_restore_noirq NULL
+
+#endif /* !CONFIG_HIBERNATION */
+
+static struct dev_pm_ops of_platform_dev_pm_ops = {
+ .prepare = of_platform_pm_prepare,
+ .complete = of_platform_pm_complete,
+ .suspend = of_platform_pm_suspend,
+ .resume = of_platform_pm_resume,
+ .freeze = of_platform_pm_freeze,
+ .thaw = of_platform_pm_thaw,
+ .poweroff = of_platform_pm_poweroff,
+ .restore = of_platform_pm_restore,
+ .suspend_noirq = of_platform_pm_suspend_noirq,
+ .resume_noirq = of_platform_pm_resume_noirq,
+ .freeze_noirq = of_platform_pm_freeze_noirq,
+ .thaw_noirq = of_platform_pm_thaw_noirq,
+ .poweroff_noirq = of_platform_pm_poweroff_noirq,
+ .restore_noirq = of_platform_pm_restore_noirq,
+};
+
+#define OF_PLATFORM_PM_OPS_PTR (&of_platform_dev_pm_ops)
+
+#else /* !CONFIG_PM_SLEEP */
+
+#define OF_PLATFORM_PM_OPS_PTR NULL
+
+#endif /* !CONFIG_PM_SLEEP */
+
int of_bus_type_init(struct bus_type *bus, const char *name)
{
bus->name = name;
bus->match = of_platform_bus_match;
bus->probe = of_platform_device_probe;
bus->remove = of_platform_device_remove;
- bus->suspend = of_platform_device_suspend;
- bus->resume = of_platform_device_resume;
bus->shutdown = of_platform_device_shutdown;
bus->dev_attrs = of_platform_device_attrs;
+ bus->pm = OF_PLATFORM_PM_OPS_PTR;
return bus_register(bus);
}
--
1.6.3.3
^ permalink raw reply related
* [PATCH 0/8] gianfar: Add support for hibernation
From: Anton Vorontsov @ 2009-10-12 16:00 UTC (permalink / raw)
To: David Miller; +Cc: Scott Wood, linuxppc-dev, netdev, Andy Fleming
Hi all,
Here are few patches that add support for hibernation for gianfar
driver.
Technically, we could just do gfar_close() and then gfar_enet_open()
sequence to restore gianfar functionality after hibernation, but
close/open does so many unneeded things (e.g. BDs buffers freeing and
allocation, IRQ freeing and requesting), that I felt it would be much
better to cleanup and refactor some code to make the hibernation [and
not only hibernation] code a little bit prettier.
Patches on the way...
Thanks,
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* [PATCH 1/8] gianfar: Some cleanups for startup_gfar()
From: Anton Vorontsov @ 2009-10-12 16:00 UTC (permalink / raw)
To: David Miller; +Cc: Scott Wood, linuxppc-dev, netdev, Andy Fleming
In-Reply-To: <20091012160000.GA32406@oksana.dev.rtsoft.ru>
We're going to split the startup_gfar() into 3 separate functions,
so let's cleanup the code a little bit so that cosmetic changes
won't distract attention from logical ones.
- Remove needless casts (e.g. (struct sk_buff **)kmalloc());
- Turn 'unsigned long vaddr;' into 'void *vaddr', to avoid casting;
- Add new 'struct device *dev' variable as a shorthand for
'&priv->ofdev->dev' that is used all over the place, also rename
'struct net_device *dev' to 'struct net_device *ndev';
- Turn printk(KERN_ERR ...) to pr_err(...), which is shorter;
- Don't return bogus -1 (i.e. -EPERM) when request_irq() fails;
- Turn '&priv->regs->' to just '®s->'.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/net/gianfar.c | 143 ++++++++++++++++++++++---------------------------
1 files changed, 64 insertions(+), 79 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 5bf31f1..8c7322f 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -925,16 +925,17 @@ void gfar_start(struct net_device *dev)
}
/* Bring the controller up and running */
-int startup_gfar(struct net_device *dev)
+int startup_gfar(struct net_device *ndev)
{
struct txbd8 *txbdp;
struct rxbd8 *rxbdp;
dma_addr_t addr = 0;
- unsigned long vaddr;
+ void *vaddr;
int i;
- struct gfar_private *priv = netdev_priv(dev);
+ struct gfar_private *priv = netdev_priv(ndev);
+ struct device *dev = &priv->ofdev->dev;
struct gfar __iomem *regs = priv->regs;
- int err = 0;
+ int err;
u32 rctrl = 0;
u32 tctrl = 0;
u32 attrs = 0;
@@ -942,38 +943,34 @@ int startup_gfar(struct net_device *dev)
gfar_write(®s->imask, IMASK_INIT_CLEAR);
/* Allocate memory for the buffer descriptors */
- vaddr = (unsigned long) dma_alloc_coherent(&priv->ofdev->dev,
- sizeof (struct txbd8) * priv->tx_ring_size +
- sizeof (struct rxbd8) * priv->rx_ring_size,
- &addr, GFP_KERNEL);
-
- if (vaddr == 0) {
+ vaddr = dma_alloc_coherent(dev, sizeof(*txbdp) * priv->tx_ring_size +
+ sizeof(*rxbdp) * priv->rx_ring_size,
+ &addr, GFP_KERNEL);
+ if (!vaddr) {
if (netif_msg_ifup(priv))
- printk(KERN_ERR "%s: Could not allocate buffer descriptors!\n",
- dev->name);
+ pr_err("%s: Could not allocate buffer descriptors!\n",
+ ndev->name);
return -ENOMEM;
}
- priv->tx_bd_base = (struct txbd8 *) vaddr;
+ priv->tx_bd_base = vaddr;
/* enet DMA only understands physical addresses */
gfar_write(®s->tbase0, addr);
/* Start the rx descriptor ring where the tx ring leaves off */
- addr = addr + sizeof (struct txbd8) * priv->tx_ring_size;
- vaddr = vaddr + sizeof (struct txbd8) * priv->tx_ring_size;
- priv->rx_bd_base = (struct rxbd8 *) vaddr;
+ addr = addr + sizeof(*txbdp) * priv->tx_ring_size;
+ vaddr = vaddr + sizeof(*txbdp) * priv->tx_ring_size;
+ priv->rx_bd_base = vaddr;
gfar_write(®s->rbase0, addr);
/* Setup the skbuff rings */
- priv->tx_skbuff =
- (struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
- priv->tx_ring_size, GFP_KERNEL);
-
- if (NULL == priv->tx_skbuff) {
+ priv->tx_skbuff = kmalloc(sizeof(*priv->tx_skbuff) *
+ priv->tx_ring_size, GFP_KERNEL);
+ if (!priv->tx_skbuff) {
if (netif_msg_ifup(priv))
- printk(KERN_ERR "%s: Could not allocate tx_skbuff\n",
- dev->name);
+ pr_err("%s: Could not allocate tx_skbuff\n",
+ ndev->name);
err = -ENOMEM;
goto tx_skb_fail;
}
@@ -981,14 +978,12 @@ int startup_gfar(struct net_device *dev)
for (i = 0; i < priv->tx_ring_size; i++)
priv->tx_skbuff[i] = NULL;
- priv->rx_skbuff =
- (struct sk_buff **) kmalloc(sizeof (struct sk_buff *) *
- priv->rx_ring_size, GFP_KERNEL);
-
- if (NULL == priv->rx_skbuff) {
+ priv->rx_skbuff = kmalloc(sizeof(*priv->rx_skbuff) *
+ priv->rx_ring_size, GFP_KERNEL);
+ if (!priv->rx_skbuff) {
if (netif_msg_ifup(priv))
- printk(KERN_ERR "%s: Could not allocate rx_skbuff\n",
- dev->name);
+ pr_err("%s: Could not allocate rx_skbuff\n",
+ ndev->name);
err = -ENOMEM;
goto rx_skb_fail;
}
@@ -1019,18 +1014,16 @@ int startup_gfar(struct net_device *dev)
for (i = 0; i < priv->rx_ring_size; i++) {
struct sk_buff *skb;
- skb = gfar_new_skb(dev);
-
+ skb = gfar_new_skb(ndev);
if (!skb) {
- printk(KERN_ERR "%s: Can't allocate RX buffers\n",
- dev->name);
-
+ pr_err("%s: Can't allocate RX buffers\n", ndev->name);
+ err = -ENOMEM;
goto err_rxalloc_fail;
}
priv->rx_skbuff[i] = skb;
- gfar_new_rxbdp(dev, rxbdp, skb);
+ gfar_new_rxbdp(ndev, rxbdp, skb);
rxbdp++;
}
@@ -1044,44 +1037,39 @@ int startup_gfar(struct net_device *dev)
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
/* Install our interrupt handlers for Error,
* Transmit, and Receive */
- if (request_irq(priv->interruptError, gfar_error,
- 0, priv->int_name_er, dev) < 0) {
+ err = request_irq(priv->interruptError, gfar_error, 0,
+ priv->int_name_er, ndev);
+ if (err) {
if (netif_msg_intr(priv))
- printk(KERN_ERR "%s: Can't get IRQ %d\n",
- dev->name, priv->interruptError);
-
- err = -1;
+ pr_err("%s: Can't get IRQ %d\n", ndev->name,
+ priv->interruptError);
goto err_irq_fail;
}
- if (request_irq(priv->interruptTransmit, gfar_transmit,
- 0, priv->int_name_tx, dev) < 0) {
+ err = request_irq(priv->interruptTransmit, gfar_transmit, 0,
+ priv->int_name_tx, ndev);
+ if (err) {
if (netif_msg_intr(priv))
- printk(KERN_ERR "%s: Can't get IRQ %d\n",
- dev->name, priv->interruptTransmit);
-
- err = -1;
-
+ pr_err("%s: Can't get IRQ %d\n", ndev->name,
+ priv->interruptTransmit);
goto tx_irq_fail;
}
- if (request_irq(priv->interruptReceive, gfar_receive,
- 0, priv->int_name_rx, dev) < 0) {
+ err = request_irq(priv->interruptReceive, gfar_receive, 0,
+ priv->int_name_rx, ndev);
+ if (err) {
if (netif_msg_intr(priv))
- printk(KERN_ERR "%s: Can't get IRQ %d (receive0)\n",
- dev->name, priv->interruptReceive);
-
- err = -1;
+ pr_err("%s: Can't get IRQ %d (receive0)\n",
+ ndev->name, priv->interruptReceive);
goto rx_irq_fail;
}
} else {
- if (request_irq(priv->interruptTransmit, gfar_interrupt,
- 0, priv->int_name_tx, dev) < 0) {
+ err = request_irq(priv->interruptTransmit, gfar_interrupt,
+ 0, priv->int_name_tx, ndev);
+ if (err) {
if (netif_msg_intr(priv))
- printk(KERN_ERR "%s: Can't get IRQ %d\n",
- dev->name, priv->interruptTransmit);
-
- err = -1;
+ pr_err("%s: Can't get IRQ %d\n", ndev->name,
+ priv->interruptTransmit);
goto err_irq_fail;
}
}
@@ -1103,7 +1091,7 @@ int startup_gfar(struct net_device *dev)
if (priv->extended_hash) {
rctrl |= RCTRL_EXTHASH;
- gfar_clear_exact_match(dev);
+ gfar_clear_exact_match(ndev);
rctrl |= RCTRL_EMEN;
}
@@ -1119,18 +1107,18 @@ int startup_gfar(struct net_device *dev)
}
/* Init rctrl based on our settings */
- gfar_write(&priv->regs->rctrl, rctrl);
+ gfar_write(®s->rctrl, rctrl);
- if (dev->features & NETIF_F_IP_CSUM)
+ if (ndev->features & NETIF_F_IP_CSUM)
tctrl |= TCTRL_INIT_CSUM;
- gfar_write(&priv->regs->tctrl, tctrl);
+ gfar_write(®s->tctrl, tctrl);
/* Set the extraction length and index */
attrs = ATTRELI_EL(priv->rx_stash_size) |
ATTRELI_EI(priv->rx_stash_index);
- gfar_write(&priv->regs->attreli, attrs);
+ gfar_write(®s->attreli, attrs);
/* Start with defaults, and add stashing or locking
* depending on the approprate variables */
@@ -1142,32 +1130,29 @@ int startup_gfar(struct net_device *dev)
if (priv->rx_stash_size != 0)
attrs |= ATTR_BUFSTASH;
- gfar_write(&priv->regs->attr, attrs);
+ gfar_write(®s->attr, attrs);
- gfar_write(&priv->regs->fifo_tx_thr, priv->fifo_threshold);
- gfar_write(&priv->regs->fifo_tx_starve, priv->fifo_starve);
- gfar_write(&priv->regs->fifo_tx_starve_shutoff, priv->fifo_starve_off);
+ gfar_write(®s->fifo_tx_thr, priv->fifo_threshold);
+ gfar_write(®s->fifo_tx_starve, priv->fifo_starve);
+ gfar_write(®s->fifo_tx_starve_shutoff, priv->fifo_starve_off);
/* Start the controller */
- gfar_start(dev);
+ gfar_start(ndev);
return 0;
rx_irq_fail:
- free_irq(priv->interruptTransmit, dev);
+ free_irq(priv->interruptTransmit, ndev);
tx_irq_fail:
- free_irq(priv->interruptError, dev);
+ free_irq(priv->interruptError, ndev);
err_irq_fail:
err_rxalloc_fail:
rx_skb_fail:
free_skb_resources(priv);
tx_skb_fail:
- dma_free_coherent(&priv->ofdev->dev,
- sizeof(struct txbd8)*priv->tx_ring_size
- + sizeof(struct rxbd8)*priv->rx_ring_size,
- priv->tx_bd_base,
- gfar_read(®s->tbase0));
-
+ dma_free_coherent(dev, sizeof(*txbdp) * priv->tx_ring_size +
+ sizeof(*rxbdp) * priv->rx_ring_size,
+ priv->tx_bd_base, gfar_read(®s->tbase0));
return err;
}
--
1.6.3.3
^ permalink raw reply related
* [PATCH 2/8] gianfar: Simplify skb resources freeing code
From: Anton Vorontsov @ 2009-10-12 16:00 UTC (permalink / raw)
To: David Miller; +Cc: Scott Wood, linuxppc-dev, netdev, Andy Fleming
In-Reply-To: <20091012160000.GA32406@oksana.dev.rtsoft.ru>
Remove dma_free_coherent() from stop_gfar() and gfar_start() calls,
place it into free_skb_resources(). That makes SKB resources management
more understandable, plus free_skb_resources() will be used as a cleanup
routine for gfar_alloc_skb_resources() that will be implemented soon.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/net/gianfar.c | 53 +++++++++++++++++++++++-------------------------
1 files changed, 25 insertions(+), 28 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 8c7322f..b7881e6 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -806,7 +806,6 @@ void gfar_halt(struct net_device *dev)
void stop_gfar(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
- struct gfar __iomem *regs = priv->regs;
unsigned long flags;
phy_stop(priv->phydev);
@@ -830,18 +829,13 @@ void stop_gfar(struct net_device *dev)
}
free_skb_resources(priv);
-
- dma_free_coherent(&priv->ofdev->dev,
- sizeof(struct txbd8)*priv->tx_ring_size
- + sizeof(struct rxbd8)*priv->rx_ring_size,
- priv->tx_bd_base,
- gfar_read(®s->tbase0));
}
/* If there are any tx skbs or rx skbs still around, free them.
* Then free tx_skbuff and rx_skbuff */
static void free_skb_resources(struct gfar_private *priv)
{
+ struct device *dev = &priv->ofdev->dev;
struct rxbd8 *rxbdp;
struct txbd8 *txbdp;
int i, j;
@@ -849,6 +843,9 @@ static void free_skb_resources(struct gfar_private *priv)
/* Go through all the buffer descriptors and free their data buffers */
txbdp = priv->tx_bd_base;
+ if (!priv->tx_skbuff)
+ goto skip_tx_skbuff;
+
for (i = 0; i < priv->tx_ring_size; i++) {
if (!priv->tx_skbuff[i])
continue;
@@ -867,30 +864,33 @@ static void free_skb_resources(struct gfar_private *priv)
}
kfree(priv->tx_skbuff);
+skip_tx_skbuff:
rxbdp = priv->rx_bd_base;
- /* rx_skbuff is not guaranteed to be allocated, so only
- * free it and its contents if it is allocated */
- if(priv->rx_skbuff != NULL) {
- for (i = 0; i < priv->rx_ring_size; i++) {
- if (priv->rx_skbuff[i]) {
- dma_unmap_single(&priv->ofdev->dev, rxbdp->bufPtr,
- priv->rx_buffer_size,
- DMA_FROM_DEVICE);
-
- dev_kfree_skb_any(priv->rx_skbuff[i]);
- priv->rx_skbuff[i] = NULL;
- }
-
- rxbdp->lstatus = 0;
- rxbdp->bufPtr = 0;
+ if (!priv->rx_skbuff)
+ goto skip_rx_skbuff;
- rxbdp++;
+ for (i = 0; i < priv->rx_ring_size; i++) {
+ if (priv->rx_skbuff[i]) {
+ dma_unmap_single(&priv->ofdev->dev, rxbdp->bufPtr,
+ priv->rx_buffer_size,
+ DMA_FROM_DEVICE);
+ dev_kfree_skb_any(priv->rx_skbuff[i]);
+ priv->rx_skbuff[i] = NULL;
}
- kfree(priv->rx_skbuff);
+ rxbdp->lstatus = 0;
+ rxbdp->bufPtr = 0;
+ rxbdp++;
}
+
+ kfree(priv->rx_skbuff);
+skip_rx_skbuff:
+
+ dma_free_coherent(dev, sizeof(*txbdp) * priv->tx_ring_size +
+ sizeof(*rxbdp) * priv->rx_ring_size,
+ priv->tx_bd_base, gfar_read(&priv->regs->tbase0));
}
void gfar_start(struct net_device *dev)
@@ -1148,11 +1148,8 @@ tx_irq_fail:
err_irq_fail:
err_rxalloc_fail:
rx_skb_fail:
- free_skb_resources(priv);
tx_skb_fail:
- dma_free_coherent(dev, sizeof(*txbdp) * priv->tx_ring_size +
- sizeof(*rxbdp) * priv->rx_ring_size,
- priv->tx_bd_base, gfar_read(®s->tbase0));
+ free_skb_resources(priv);
return err;
}
--
1.6.3.3
^ permalink raw reply related
* [PATCH 3/8] gianfar: Don't needlessly set the wrap bit for the last RX BD
From: Anton Vorontsov @ 2009-10-12 16:00 UTC (permalink / raw)
To: David Miller; +Cc: Scott Wood, linuxppc-dev, netdev, Andy Fleming
In-Reply-To: <20091012160000.GA32406@oksana.dev.rtsoft.ru>
startup_gfar() sets the wrap bit for the last rxbd just after
gfar_new_rxbdp() call, which is issued for all rxbds. And
gfar_new_rxbdp() has the following check already:
if (bdp == priv->rx_bd_base + priv->rx_ring_size - 1)
lstatus |= BD_LFLAG(RXBD_WRAP);
So we don't need to set the bit again.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/net/gianfar.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index b7881e6..ee23431 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -1028,10 +1028,6 @@ int startup_gfar(struct net_device *ndev)
rxbdp++;
}
- /* Set the last descriptor in the ring to wrap */
- rxbdp--;
- rxbdp->status |= RXBD_WRAP;
-
/* If the device has multiple interrupts, register for
* them. Otherwise, only register for the one */
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
--
1.6.3.3
^ permalink raw reply related
* [PATCH 4/8] gianfar: Split allocation and initialization steps out of startup_gfar()
From: Anton Vorontsov @ 2009-10-12 16:00 UTC (permalink / raw)
To: David Miller; +Cc: Scott Wood, linuxppc-dev, netdev, Andy Fleming
In-Reply-To: <20091012160000.GA32406@oksana.dev.rtsoft.ru>
Two new functions implemented: gfar_alloc_skb_resources() and
gfar_init_mac(). We'll use gfar_init_mac() for restoring after
hibernation.
The patch just moves the code around, there should be no functional
changes.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/net/gianfar.c | 334 ++++++++++++++++++++++++++-----------------------
1 files changed, 176 insertions(+), 158 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index ee23431..4dcaaa7 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -147,6 +147,176 @@ MODULE_AUTHOR("Freescale Semiconductor, Inc");
MODULE_DESCRIPTION("Gianfar Ethernet Driver");
MODULE_LICENSE("GPL");
+static int gfar_alloc_skb_resources(struct net_device *ndev)
+{
+ struct txbd8 *txbdp;
+ struct rxbd8 *rxbdp;
+ dma_addr_t addr = 0;
+ void *vaddr;
+ int i;
+ struct gfar_private *priv = netdev_priv(ndev);
+ struct device *dev = &priv->ofdev->dev;
+ struct gfar __iomem *regs = priv->regs;
+
+ /* Allocate memory for the buffer descriptors */
+ vaddr = dma_alloc_coherent(dev, sizeof(*txbdp) * priv->tx_ring_size +
+ sizeof(*rxbdp) * priv->rx_ring_size,
+ &addr, GFP_KERNEL);
+ if (!vaddr) {
+ if (netif_msg_ifup(priv))
+ pr_err("%s: Could not allocate buffer descriptors!\n",
+ ndev->name);
+ return -ENOMEM;
+ }
+
+ priv->tx_bd_base = vaddr;
+
+ /* enet DMA only understands physical addresses */
+ gfar_write(®s->tbase0, addr);
+
+ /* Start the rx descriptor ring where the tx ring leaves off */
+ addr = addr + sizeof(*txbdp) * priv->tx_ring_size;
+ vaddr = vaddr + sizeof(*txbdp) * priv->tx_ring_size;
+ priv->rx_bd_base = vaddr;
+ gfar_write(®s->rbase0, addr);
+
+ /* Setup the skbuff rings */
+ priv->tx_skbuff = kmalloc(sizeof(*priv->tx_skbuff) *
+ priv->tx_ring_size, GFP_KERNEL);
+ if (!priv->tx_skbuff) {
+ if (netif_msg_ifup(priv))
+ pr_err("%s: Could not allocate tx_skbuff\n",
+ ndev->name);
+ goto cleanup;
+ }
+
+ for (i = 0; i < priv->tx_ring_size; i++)
+ priv->tx_skbuff[i] = NULL;
+
+ priv->rx_skbuff = kmalloc(sizeof(*priv->rx_skbuff) *
+ priv->rx_ring_size, GFP_KERNEL);
+ if (!priv->rx_skbuff) {
+ if (netif_msg_ifup(priv))
+ pr_err("%s: Could not allocate rx_skbuff\n",
+ ndev->name);
+ goto cleanup;
+ }
+
+ for (i = 0; i < priv->rx_ring_size; i++)
+ priv->rx_skbuff[i] = NULL;
+
+ /* Initialize some variables in our dev structure */
+ priv->num_txbdfree = priv->tx_ring_size;
+ priv->dirty_tx = priv->cur_tx = priv->tx_bd_base;
+ priv->cur_rx = priv->rx_bd_base;
+ priv->skb_curtx = priv->skb_dirtytx = 0;
+ priv->skb_currx = 0;
+
+ /* Initialize Transmit Descriptor Ring */
+ txbdp = priv->tx_bd_base;
+ for (i = 0; i < priv->tx_ring_size; i++) {
+ txbdp->lstatus = 0;
+ txbdp->bufPtr = 0;
+ txbdp++;
+ }
+
+ /* Set the last descriptor in the ring to indicate wrap */
+ txbdp--;
+ txbdp->status |= TXBD_WRAP;
+
+ rxbdp = priv->rx_bd_base;
+ for (i = 0; i < priv->rx_ring_size; i++) {
+ struct sk_buff *skb;
+
+ skb = gfar_new_skb(ndev);
+ if (!skb) {
+ pr_err("%s: Can't allocate RX buffers\n", ndev->name);
+ goto cleanup;
+ }
+
+ priv->rx_skbuff[i] = skb;
+
+ gfar_new_rxbdp(ndev, rxbdp, skb);
+
+ rxbdp++;
+ }
+
+ return 0;
+
+cleanup:
+ free_skb_resources(priv);
+ return -ENOMEM;
+}
+
+static void gfar_init_mac(struct net_device *ndev)
+{
+ struct gfar_private *priv = netdev_priv(ndev);
+ struct gfar __iomem *regs = priv->regs;
+ u32 rctrl = 0;
+ u32 tctrl = 0;
+ u32 attrs = 0;
+
+ /* Configure the coalescing support */
+ gfar_write(®s->txic, 0);
+ if (priv->txcoalescing)
+ gfar_write(®s->txic, priv->txic);
+
+ gfar_write(®s->rxic, 0);
+ if (priv->rxcoalescing)
+ gfar_write(®s->rxic, priv->rxic);
+
+ if (priv->rx_csum_enable)
+ rctrl |= RCTRL_CHECKSUMMING;
+
+ if (priv->extended_hash) {
+ rctrl |= RCTRL_EXTHASH;
+
+ gfar_clear_exact_match(ndev);
+ rctrl |= RCTRL_EMEN;
+ }
+
+ if (priv->padding) {
+ rctrl &= ~RCTRL_PAL_MASK;
+ rctrl |= RCTRL_PADDING(priv->padding);
+ }
+
+ /* keep vlan related bits if it's enabled */
+ if (priv->vlgrp) {
+ rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT;
+ tctrl |= TCTRL_VLINS;
+ }
+
+ /* Init rctrl based on our settings */
+ gfar_write(®s->rctrl, rctrl);
+
+ if (ndev->features & NETIF_F_IP_CSUM)
+ tctrl |= TCTRL_INIT_CSUM;
+
+ gfar_write(®s->tctrl, tctrl);
+
+ /* Set the extraction length and index */
+ attrs = ATTRELI_EL(priv->rx_stash_size) |
+ ATTRELI_EI(priv->rx_stash_index);
+
+ gfar_write(®s->attreli, attrs);
+
+ /* Start with defaults, and add stashing or locking
+ * depending on the approprate variables */
+ attrs = ATTR_INIT_SETTINGS;
+
+ if (priv->bd_stash_en)
+ attrs |= ATTR_BDSTASH;
+
+ if (priv->rx_stash_size != 0)
+ attrs |= ATTR_BUFSTASH;
+
+ gfar_write(®s->attr, attrs);
+
+ gfar_write(®s->fifo_tx_thr, priv->fifo_threshold);
+ gfar_write(®s->fifo_tx_starve, priv->fifo_starve);
+ gfar_write(®s->fifo_tx_starve_shutoff, priv->fifo_starve_off);
+}
+
static const struct net_device_ops gfar_netdev_ops = {
.ndo_open = gfar_enet_open,
.ndo_start_xmit = gfar_start_xmit,
@@ -927,106 +1097,17 @@ void gfar_start(struct net_device *dev)
/* Bring the controller up and running */
int startup_gfar(struct net_device *ndev)
{
- struct txbd8 *txbdp;
- struct rxbd8 *rxbdp;
- dma_addr_t addr = 0;
- void *vaddr;
- int i;
struct gfar_private *priv = netdev_priv(ndev);
- struct device *dev = &priv->ofdev->dev;
struct gfar __iomem *regs = priv->regs;
int err;
- u32 rctrl = 0;
- u32 tctrl = 0;
- u32 attrs = 0;
gfar_write(®s->imask, IMASK_INIT_CLEAR);
- /* Allocate memory for the buffer descriptors */
- vaddr = dma_alloc_coherent(dev, sizeof(*txbdp) * priv->tx_ring_size +
- sizeof(*rxbdp) * priv->rx_ring_size,
- &addr, GFP_KERNEL);
- if (!vaddr) {
- if (netif_msg_ifup(priv))
- pr_err("%s: Could not allocate buffer descriptors!\n",
- ndev->name);
- return -ENOMEM;
- }
-
- priv->tx_bd_base = vaddr;
-
- /* enet DMA only understands physical addresses */
- gfar_write(®s->tbase0, addr);
-
- /* Start the rx descriptor ring where the tx ring leaves off */
- addr = addr + sizeof(*txbdp) * priv->tx_ring_size;
- vaddr = vaddr + sizeof(*txbdp) * priv->tx_ring_size;
- priv->rx_bd_base = vaddr;
- gfar_write(®s->rbase0, addr);
-
- /* Setup the skbuff rings */
- priv->tx_skbuff = kmalloc(sizeof(*priv->tx_skbuff) *
- priv->tx_ring_size, GFP_KERNEL);
- if (!priv->tx_skbuff) {
- if (netif_msg_ifup(priv))
- pr_err("%s: Could not allocate tx_skbuff\n",
- ndev->name);
- err = -ENOMEM;
- goto tx_skb_fail;
- }
-
- for (i = 0; i < priv->tx_ring_size; i++)
- priv->tx_skbuff[i] = NULL;
-
- priv->rx_skbuff = kmalloc(sizeof(*priv->rx_skbuff) *
- priv->rx_ring_size, GFP_KERNEL);
- if (!priv->rx_skbuff) {
- if (netif_msg_ifup(priv))
- pr_err("%s: Could not allocate rx_skbuff\n",
- ndev->name);
- err = -ENOMEM;
- goto rx_skb_fail;
- }
-
- for (i = 0; i < priv->rx_ring_size; i++)
- priv->rx_skbuff[i] = NULL;
-
- /* Initialize some variables in our dev structure */
- priv->num_txbdfree = priv->tx_ring_size;
- priv->dirty_tx = priv->cur_tx = priv->tx_bd_base;
- priv->cur_rx = priv->rx_bd_base;
- priv->skb_curtx = priv->skb_dirtytx = 0;
- priv->skb_currx = 0;
-
- /* Initialize Transmit Descriptor Ring */
- txbdp = priv->tx_bd_base;
- for (i = 0; i < priv->tx_ring_size; i++) {
- txbdp->lstatus = 0;
- txbdp->bufPtr = 0;
- txbdp++;
- }
-
- /* Set the last descriptor in the ring to indicate wrap */
- txbdp--;
- txbdp->status |= TXBD_WRAP;
-
- rxbdp = priv->rx_bd_base;
- for (i = 0; i < priv->rx_ring_size; i++) {
- struct sk_buff *skb;
-
- skb = gfar_new_skb(ndev);
- if (!skb) {
- pr_err("%s: Can't allocate RX buffers\n", ndev->name);
- err = -ENOMEM;
- goto err_rxalloc_fail;
- }
-
- priv->rx_skbuff[i] = skb;
-
- gfar_new_rxbdp(ndev, rxbdp, skb);
+ err = gfar_alloc_skb_resources(ndev);
+ if (err)
+ return err;
- rxbdp++;
- }
+ gfar_init_mac(ndev);
/* If the device has multiple interrupts, register for
* them. Otherwise, only register for the one */
@@ -1070,71 +1151,11 @@ int startup_gfar(struct net_device *ndev)
}
}
- phy_start(priv->phydev);
-
- /* Configure the coalescing support */
- gfar_write(®s->txic, 0);
- if (priv->txcoalescing)
- gfar_write(®s->txic, priv->txic);
-
- gfar_write(®s->rxic, 0);
- if (priv->rxcoalescing)
- gfar_write(®s->rxic, priv->rxic);
-
- if (priv->rx_csum_enable)
- rctrl |= RCTRL_CHECKSUMMING;
-
- if (priv->extended_hash) {
- rctrl |= RCTRL_EXTHASH;
-
- gfar_clear_exact_match(ndev);
- rctrl |= RCTRL_EMEN;
- }
-
- if (priv->padding) {
- rctrl &= ~RCTRL_PAL_MASK;
- rctrl |= RCTRL_PADDING(priv->padding);
- }
-
- /* keep vlan related bits if it's enabled */
- if (priv->vlgrp) {
- rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT;
- tctrl |= TCTRL_VLINS;
- }
-
- /* Init rctrl based on our settings */
- gfar_write(®s->rctrl, rctrl);
-
- if (ndev->features & NETIF_F_IP_CSUM)
- tctrl |= TCTRL_INIT_CSUM;
-
- gfar_write(®s->tctrl, tctrl);
-
- /* Set the extraction length and index */
- attrs = ATTRELI_EL(priv->rx_stash_size) |
- ATTRELI_EI(priv->rx_stash_index);
-
- gfar_write(®s->attreli, attrs);
-
- /* Start with defaults, and add stashing or locking
- * depending on the approprate variables */
- attrs = ATTR_INIT_SETTINGS;
-
- if (priv->bd_stash_en)
- attrs |= ATTR_BDSTASH;
-
- if (priv->rx_stash_size != 0)
- attrs |= ATTR_BUFSTASH;
-
- gfar_write(®s->attr, attrs);
-
- gfar_write(®s->fifo_tx_thr, priv->fifo_threshold);
- gfar_write(®s->fifo_tx_starve, priv->fifo_starve);
- gfar_write(®s->fifo_tx_starve_shutoff, priv->fifo_starve_off);
-
/* Start the controller */
gfar_start(ndev);
+ phy_start(priv->phydev);
+
return 0;
rx_irq_fail:
@@ -1142,9 +1163,6 @@ rx_irq_fail:
tx_irq_fail:
free_irq(priv->interruptError, ndev);
err_irq_fail:
-err_rxalloc_fail:
-rx_skb_fail:
-tx_skb_fail:
free_skb_resources(priv);
return err;
}
--
1.6.3.3
^ permalink raw reply related
* [PATCH 5/8] gianfar: Move tbase/rbase initialization to gfar_init_mac()
From: Anton Vorontsov @ 2009-10-12 16:00 UTC (permalink / raw)
To: David Miller; +Cc: Scott Wood, linuxppc-dev, netdev, Andy Fleming
In-Reply-To: <20091012160000.GA32406@oksana.dev.rtsoft.ru>
For hibernation we want to call gfar_init_mac() without need to
free/allocate_skb_resources sequence, so save the DMA address into a
private struct, and move tbase/rbase initialization to gfar_init_mac().
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/net/gianfar.c | 17 ++++++++---------
drivers/net/gianfar.h | 1 +
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 4dcaaa7..46b0b37 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -151,17 +151,15 @@ static int gfar_alloc_skb_resources(struct net_device *ndev)
{
struct txbd8 *txbdp;
struct rxbd8 *rxbdp;
- dma_addr_t addr = 0;
void *vaddr;
int i;
struct gfar_private *priv = netdev_priv(ndev);
struct device *dev = &priv->ofdev->dev;
- struct gfar __iomem *regs = priv->regs;
/* Allocate memory for the buffer descriptors */
vaddr = dma_alloc_coherent(dev, sizeof(*txbdp) * priv->tx_ring_size +
sizeof(*rxbdp) * priv->rx_ring_size,
- &addr, GFP_KERNEL);
+ &priv->tx_bd_dma_base, GFP_KERNEL);
if (!vaddr) {
if (netif_msg_ifup(priv))
pr_err("%s: Could not allocate buffer descriptors!\n",
@@ -171,14 +169,9 @@ static int gfar_alloc_skb_resources(struct net_device *ndev)
priv->tx_bd_base = vaddr;
- /* enet DMA only understands physical addresses */
- gfar_write(®s->tbase0, addr);
-
/* Start the rx descriptor ring where the tx ring leaves off */
- addr = addr + sizeof(*txbdp) * priv->tx_ring_size;
vaddr = vaddr + sizeof(*txbdp) * priv->tx_ring_size;
priv->rx_bd_base = vaddr;
- gfar_write(®s->rbase0, addr);
/* Setup the skbuff rings */
priv->tx_skbuff = kmalloc(sizeof(*priv->tx_skbuff) *
@@ -256,6 +249,12 @@ static void gfar_init_mac(struct net_device *ndev)
u32 tctrl = 0;
u32 attrs = 0;
+ /* enet DMA only understands physical addresses */
+ gfar_write(®s->tbase0, priv->tx_bd_dma_base);
+ gfar_write(®s->rbase0, priv->tx_bd_dma_base +
+ sizeof(*priv->tx_bd_base) *
+ priv->tx_ring_size);
+
/* Configure the coalescing support */
gfar_write(®s->txic, 0);
if (priv->txcoalescing)
@@ -1060,7 +1059,7 @@ skip_rx_skbuff:
dma_free_coherent(dev, sizeof(*txbdp) * priv->tx_ring_size +
sizeof(*rxbdp) * priv->rx_ring_size,
- priv->tx_bd_base, gfar_read(&priv->regs->tbase0));
+ priv->tx_bd_base, priv->tx_bd_dma_base);
}
void gfar_start(struct net_device *dev)
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 2cd9433..05732fa 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -726,6 +726,7 @@ struct gfar_private {
unsigned long txic;
/* Buffer descriptor pointers */
+ dma_addr_t tx_bd_dma_base;
struct txbd8 *tx_bd_base; /* First tx buffer descriptor */
struct txbd8 *cur_tx; /* Next free ring entry */
struct txbd8 *dirty_tx; /* First buffer in line
--
1.6.3.3
^ permalink raw reply related
* [PATCH 6/8] gianfar: Factor out RX BDs initialization from gfar_new_rxbdp()
From: Anton Vorontsov @ 2009-10-12 16:00 UTC (permalink / raw)
To: David Miller; +Cc: Scott Wood, linuxppc-dev, netdev, Andy Fleming
In-Reply-To: <20091012160000.GA32406@oksana.dev.rtsoft.ru>
We want to just reinitialize RX BDs after hibernation, no need to
map the skb->data again. So let's factor gfar_init_rxbdp() out of
gfar_new_rxbdp().
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/net/gianfar.c | 33 +++++++++++++++++++++------------
1 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 46b0b37..1b32274 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -147,6 +147,23 @@ MODULE_AUTHOR("Freescale Semiconductor, Inc");
MODULE_DESCRIPTION("Gianfar Ethernet Driver");
MODULE_LICENSE("GPL");
+static void gfar_init_rxbdp(struct net_device *dev, struct rxbd8 *bdp,
+ dma_addr_t buf)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+ u32 lstatus;
+
+ bdp->bufPtr = buf;
+
+ lstatus = BD_LFLAG(RXBD_EMPTY | RXBD_INTERRUPT);
+ if (bdp == priv->rx_bd_base + priv->rx_ring_size - 1)
+ lstatus |= BD_LFLAG(RXBD_WRAP);
+
+ eieio();
+
+ bdp->lstatus = lstatus;
+}
+
static int gfar_alloc_skb_resources(struct net_device *ndev)
{
struct txbd8 *txbdp;
@@ -1676,19 +1693,11 @@ static void gfar_new_rxbdp(struct net_device *dev, struct rxbd8 *bdp,
struct sk_buff *skb)
{
struct gfar_private *priv = netdev_priv(dev);
- u32 lstatus;
-
- bdp->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
- priv->rx_buffer_size, DMA_FROM_DEVICE);
-
- lstatus = BD_LFLAG(RXBD_EMPTY | RXBD_INTERRUPT);
+ dma_addr_t buf;
- if (bdp == priv->rx_bd_base + priv->rx_ring_size - 1)
- lstatus |= BD_LFLAG(RXBD_WRAP);
-
- eieio();
-
- bdp->lstatus = lstatus;
+ buf = dma_map_single(&priv->ofdev->dev, skb->data,
+ priv->rx_buffer_size, DMA_FROM_DEVICE);
+ gfar_init_rxbdp(dev, bdp, buf);
}
--
1.6.3.3
^ permalink raw reply related
* [PATCH 7/8] gianfar: Factor out gfar_init_bds() from gfar_alloc_skb_resources()
From: Anton Vorontsov @ 2009-10-12 16:00 UTC (permalink / raw)
To: David Miller; +Cc: Scott Wood, linuxppc-dev, netdev, Andy Fleming
In-Reply-To: <20091012160000.GA32406@oksana.dev.rtsoft.ru>
After hibernation we want to just reinitialize BDs, no need to allocate
anything. So, factor out BDs initialization code from
gfar_alloc_skb_resourses().
Also, teach gfar_init_bds() to reuse already allocated RX SKBs, i.e.
just call gfar_init_rxbdp() if a SKB was already allocated and mapped.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/net/gianfar.c | 96 ++++++++++++++++++++++++++++--------------------
1 files changed, 56 insertions(+), 40 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 1b32274..634a15b 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -164,19 +164,68 @@ static void gfar_init_rxbdp(struct net_device *dev, struct rxbd8 *bdp,
bdp->lstatus = lstatus;
}
-static int gfar_alloc_skb_resources(struct net_device *ndev)
+static int gfar_init_bds(struct net_device *ndev)
{
+ struct gfar_private *priv = netdev_priv(ndev);
struct txbd8 *txbdp;
struct rxbd8 *rxbdp;
+ int i;
+
+ /* Initialize some variables in our dev structure */
+ priv->num_txbdfree = priv->tx_ring_size;
+ priv->dirty_tx = priv->cur_tx = priv->tx_bd_base;
+ priv->cur_rx = priv->rx_bd_base;
+ priv->skb_curtx = priv->skb_dirtytx = 0;
+ priv->skb_currx = 0;
+
+ /* Initialize Transmit Descriptor Ring */
+ txbdp = priv->tx_bd_base;
+ for (i = 0; i < priv->tx_ring_size; i++) {
+ txbdp->lstatus = 0;
+ txbdp->bufPtr = 0;
+ txbdp++;
+ }
+
+ /* Set the last descriptor in the ring to indicate wrap */
+ txbdp--;
+ txbdp->status |= TXBD_WRAP;
+
+ rxbdp = priv->rx_bd_base;
+ for (i = 0; i < priv->rx_ring_size; i++) {
+ struct sk_buff *skb = priv->rx_skbuff[i];
+
+ if (skb) {
+ gfar_init_rxbdp(ndev, rxbdp, rxbdp->bufPtr);
+ } else {
+ skb = gfar_new_skb(ndev);
+ if (!skb) {
+ pr_err("%s: Can't allocate RX buffers\n",
+ ndev->name);
+ return -ENOMEM;
+ }
+ priv->rx_skbuff[i] = skb;
+
+ gfar_new_rxbdp(ndev, rxbdp, skb);
+ }
+
+ rxbdp++;
+ }
+
+ return 0;
+}
+
+static int gfar_alloc_skb_resources(struct net_device *ndev)
+{
void *vaddr;
int i;
struct gfar_private *priv = netdev_priv(ndev);
struct device *dev = &priv->ofdev->dev;
/* Allocate memory for the buffer descriptors */
- vaddr = dma_alloc_coherent(dev, sizeof(*txbdp) * priv->tx_ring_size +
- sizeof(*rxbdp) * priv->rx_ring_size,
- &priv->tx_bd_dma_base, GFP_KERNEL);
+ vaddr = dma_alloc_coherent(dev,
+ sizeof(*priv->tx_bd_base) * priv->tx_ring_size +
+ sizeof(*priv->rx_bd_base) * priv->rx_ring_size,
+ &priv->tx_bd_dma_base, GFP_KERNEL);
if (!vaddr) {
if (netif_msg_ifup(priv))
pr_err("%s: Could not allocate buffer descriptors!\n",
@@ -187,7 +236,7 @@ static int gfar_alloc_skb_resources(struct net_device *ndev)
priv->tx_bd_base = vaddr;
/* Start the rx descriptor ring where the tx ring leaves off */
- vaddr = vaddr + sizeof(*txbdp) * priv->tx_ring_size;
+ vaddr = vaddr + sizeof(*priv->tx_bd_base) * priv->tx_ring_size;
priv->rx_bd_base = vaddr;
/* Setup the skbuff rings */
@@ -215,41 +264,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev)
for (i = 0; i < priv->rx_ring_size; i++)
priv->rx_skbuff[i] = NULL;
- /* Initialize some variables in our dev structure */
- priv->num_txbdfree = priv->tx_ring_size;
- priv->dirty_tx = priv->cur_tx = priv->tx_bd_base;
- priv->cur_rx = priv->rx_bd_base;
- priv->skb_curtx = priv->skb_dirtytx = 0;
- priv->skb_currx = 0;
-
- /* Initialize Transmit Descriptor Ring */
- txbdp = priv->tx_bd_base;
- for (i = 0; i < priv->tx_ring_size; i++) {
- txbdp->lstatus = 0;
- txbdp->bufPtr = 0;
- txbdp++;
- }
-
- /* Set the last descriptor in the ring to indicate wrap */
- txbdp--;
- txbdp->status |= TXBD_WRAP;
-
- rxbdp = priv->rx_bd_base;
- for (i = 0; i < priv->rx_ring_size; i++) {
- struct sk_buff *skb;
-
- skb = gfar_new_skb(ndev);
- if (!skb) {
- pr_err("%s: Can't allocate RX buffers\n", ndev->name);
- goto cleanup;
- }
-
- priv->rx_skbuff[i] = skb;
-
- gfar_new_rxbdp(ndev, rxbdp, skb);
-
- rxbdp++;
- }
+ if (gfar_init_bds(ndev))
+ goto cleanup;
return 0;
--
1.6.3.3
^ permalink raw reply related
* [PATCH 8/8] gianfar: Add support for hibernation
From: Anton Vorontsov @ 2009-10-12 16:00 UTC (permalink / raw)
To: David Miller; +Cc: Scott Wood, linuxppc-dev, netdev, Andy Fleming
In-Reply-To: <20091012160000.GA32406@oksana.dev.rtsoft.ru>
Thanks to various cleanups and refactorings this is now straightforward:
convert the gianfar driver to dev_pm_ops, plus add ->restore() callback
that will fully reinitialize MAC internal registers and BDs.
Note that I kept legacy suspend/resume callbacks so that this patch
doesn't depend on PowerPC changes (i.e. dev_pm_ops support for OF
platform drivers).
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
drivers/net/gianfar.c | 87 +++++++++++++++++++++++++++++++++++++++---------
1 files changed, 70 insertions(+), 17 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 634a15b..f714186 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -700,23 +700,24 @@ static int gfar_remove(struct of_device *ofdev)
}
#ifdef CONFIG_PM
-static int gfar_suspend(struct of_device *ofdev, pm_message_t state)
+
+static int gfar_suspend(struct device *dev)
{
- struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
- struct net_device *dev = priv->ndev;
+ struct gfar_private *priv = dev_get_drvdata(dev);
+ struct net_device *ndev = priv->ndev;
unsigned long flags;
u32 tempval;
int magic_packet = priv->wol_en &&
(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
- netif_device_detach(dev);
+ netif_device_detach(ndev);
- if (netif_running(dev)) {
+ if (netif_running(ndev)) {
spin_lock_irqsave(&priv->txlock, flags);
spin_lock(&priv->rxlock);
- gfar_halt_nodisable(dev);
+ gfar_halt_nodisable(ndev);
/* Disable Tx, and Rx if wake-on-LAN is disabled. */
tempval = gfar_read(&priv->regs->maccfg1);
@@ -749,17 +750,17 @@ static int gfar_suspend(struct of_device *ofdev, pm_message_t state)
return 0;
}
-static int gfar_resume(struct of_device *ofdev)
+static int gfar_resume(struct device *dev)
{
- struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
- struct net_device *dev = priv->ndev;
+ struct gfar_private *priv = dev_get_drvdata(dev);
+ struct net_device *ndev = priv->ndev;
unsigned long flags;
u32 tempval;
int magic_packet = priv->wol_en &&
(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
- if (!netif_running(dev)) {
- netif_device_attach(dev);
+ if (!netif_running(ndev)) {
+ netif_device_attach(ndev);
return 0;
}
@@ -777,20 +778,71 @@ static int gfar_resume(struct of_device *ofdev)
tempval &= ~MACCFG2_MPEN;
gfar_write(&priv->regs->maccfg2, tempval);
- gfar_start(dev);
+ gfar_start(ndev);
spin_unlock(&priv->rxlock);
spin_unlock_irqrestore(&priv->txlock, flags);
- netif_device_attach(dev);
+ netif_device_attach(ndev);
+
+ napi_enable(&priv->napi);
+
+ return 0;
+}
+
+static int gfar_restore(struct device *dev)
+{
+ struct gfar_private *priv = dev_get_drvdata(dev);
+ struct net_device *ndev = priv->ndev;
+
+ if (!netif_running(ndev))
+ return 0;
+
+ gfar_init_bds(ndev);
+ init_registers(ndev);
+ gfar_set_mac_address(ndev);
+ gfar_init_mac(ndev);
+ gfar_start(ndev);
+
+ priv->oldlink = 0;
+ priv->oldspeed = 0;
+ priv->oldduplex = -1;
+
+ if (priv->phydev)
+ phy_start(priv->phydev);
+ netif_device_attach(ndev);
napi_enable(&priv->napi);
return 0;
}
+
+static struct dev_pm_ops gfar_pm_ops = {
+ .suspend = gfar_suspend,
+ .resume = gfar_resume,
+ .freeze = gfar_suspend,
+ .thaw = gfar_resume,
+ .restore = gfar_restore,
+};
+
+#define GFAR_PM_OPS (&gfar_pm_ops)
+
+static int gfar_legacy_suspend(struct of_device *ofdev, pm_message_t state)
+{
+ return gfar_suspend(&ofdev->dev);
+}
+
+static int gfar_legacy_resume(struct of_device *ofdev)
+{
+ return gfar_resume(&ofdev->dev);
+}
+
#else
-#define gfar_suspend NULL
-#define gfar_resume NULL
+
+#define GFAR_PM_OPS NULL
+#define gfar_legacy_suspend NULL
+#define gfar_legacy_resume NULL
+
#endif
/* Reads the controller's registers to determine what interface
@@ -2362,8 +2414,9 @@ static struct of_platform_driver gfar_driver = {
.probe = gfar_probe,
.remove = gfar_remove,
- .suspend = gfar_suspend,
- .resume = gfar_resume,
+ .suspend = gfar_legacy_suspend,
+ .resume = gfar_legacy_resume,
+ .driver.pm = GFAR_PM_OPS,
};
static int __init gfar_init(void)
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] * mpc8313erdb.dts: Fixed eTSEC interrupt assignment.
From: Kim Phillips @ 2009-10-12 16:06 UTC (permalink / raw)
To: Kumar Gala; +Cc: Scott Wood, u-boot, linuxppc-dev, Roland Lezuo
In-Reply-To: <F7AA2B23-A019-4E11-993D-AF0F6F1FD50A@kernel.crashing.org>
On Wed, 9 Sep 2009 15:28:01 -0500
Kumar Gala <galak@kernel.crashing.org> wrote:
>
> On Sep 9, 2009, at 1:22 PM, Scott Wood wrote:
>
> > On Fri, Sep 04, 2009 at 12:31:25PM +0200, Roland Lezuo wrote:
> >> The following patch is needed to correctly assign the IRQs for the
> >> gianfar driver on the MPC8313ERDB-revc boards. ERR and TX are swapped
> >> as well as the interrupt lines for the two devices.
> >
> > And it will incorrectly assign them on older revisions of the chip.
> >
> > We really should have a u-boot fixup based on SVR.
Roland, is it possible for you to test this u-boot patch?:
>From 44c73137acf20626e930e3f4142e60054d8bd46f Mon Sep 17 00:00:00 2001
From: Kim Phillips <kim.phillips@freescale.com>
Date: Mon, 12 Oct 2009 10:51:20 -0500
Subject: [PATCH] mpc83xx: mpc8313 - handle erratum IPIC1 (TSEC IRQ number swappage)
mpc8313e erratum IPIC1 swapped TSEC interrupt ID numbers on rev. 1
h/w (see AN3545). The base device tree in use has rev. 1 ID numbers,
so if on Rev. 2 (and higher) h/w, we fix them up here.
Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
---
cpu/mpc83xx/fdt.c | 39 +++++++++++++++++++++++++++++++++++++++
1 files changed, 39 insertions(+), 0 deletions(-)
diff --git a/cpu/mpc83xx/fdt.c b/cpu/mpc83xx/fdt.c
index 13443cb..daf73a6 100644
--- a/cpu/mpc83xx/fdt.c
+++ b/cpu/mpc83xx/fdt.c
@@ -69,6 +69,45 @@ void ft_cpu_setup(void *blob, bd_t *bd)
defined(CONFIG_HAS_ETH2) || defined(CONFIG_HAS_ETH3) ||\
defined(CONFIG_HAS_ETH4) || defined(CONFIG_HAS_ETH5)
fdt_fixup_ethernet(blob);
+#ifdef CONFIG_MPC8313
+ /*
+ * mpc8313e erratum IPIC1 swapped TSEC interrupt ID numbers on rev. 1
+ * h/w (see AN3545). The base device tree in use has rev. 1 ID numbers,
+ * so if on Rev. 2 (and higher) h/w, we fix them up here
+ */
+ if (REVID_MAJOR(immr->sysconf.spridr) >= 2) {
+ int nodeoffset, path;
+ const char *prop;
+
+ nodeoffset = fdt_path_offset(blob, "/aliases");
+ if (nodeoffset >= 0) {
+#if defined(CONFIG_HAS_ETH0)
+ prop = fdt_getprop(blob, nodeoffset, "ethernet0", NULL);
+ if (prop) {
+ u32 tmp[] = { 32, 0x8, 33, 0x8, 34, 0x8 };
+
+ path = fdt_path_offset(blob, prop);
+ prop = fdt_getprop(blob, path, "interrupts", 0);
+ if (prop)
+ fdt_setprop(blob, path, "interrupts",
+ &tmp, sizeof(tmp));
+ }
+#endif
+#if defined(CONFIG_HAS_ETH1)
+ prop = fdt_getprop(blob, nodeoffset, "ethernet1", NULL);
+ if (prop) {
+ u32 tmp[] = { 35, 0x8, 36, 0x8, 37, 0x8 };
+
+ path = fdt_path_offset(blob, prop);
+ prop = fdt_getprop(blob, path, "interrupts", 0);
+ if (prop)
+ fdt_setprop(blob, path, "interrupts",
+ &tmp, sizeof(tmp));
+ }
+#endif
+ }
+ }
+#endif
#endif
do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
--
1.6.4.4
^ permalink raw reply related
* [PATCH] powerpc/8xxx: enable IPsec ESP by default on mpc83xx/mpc85xx
From: Kim Phillips @ 2009-10-12 16:35 UTC (permalink / raw)
To: linuxppc-dev
Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
---
arch/powerpc/configs/mpc83xx_defconfig | 15 ++++++++-------
arch/powerpc/configs/mpc85xx_defconfig | 16 ++++++++--------
arch/powerpc/configs/mpc85xx_smp_defconfig | 16 ++++++++--------
3 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig
index 4a96cb6..d6d28f2 100644
--- a/arch/powerpc/configs/mpc83xx_defconfig
+++ b/arch/powerpc/configs/mpc83xx_defconfig
@@ -343,7 +343,8 @@ CONFIG_XFRM_USER=m
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
# CONFIG_XFRM_STATISTICS is not set
-# CONFIG_NET_KEY is not set
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
@@ -358,7 +359,7 @@ CONFIG_IP_PNP_BOOTP=y
# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
+CONFIG_INET_ESP=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
@@ -1591,7 +1592,7 @@ CONFIG_CRYPTO_PCBC=m
#
# Hash modes
#
-# CONFIG_CRYPTO_HMAC is not set
+CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
#
@@ -1605,16 +1606,16 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set
#
# Ciphers
#
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index ada5958..35f941c 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -344,7 +344,7 @@ CONFIG_XFRM_USER=y
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
# CONFIG_XFRM_STATISTICS is not set
-CONFIG_NET_KEY=m
+CONFIG_NET_KEY=y
# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -368,12 +368,12 @@ CONFIG_IP_PIMSM_V2=y
CONFIG_ARPD=y
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
+CONFIG_INET_ESP=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
CONFIG_INET_TUNNEL=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=y
@@ -1768,16 +1768,16 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
-CONFIG_CRYPTO_SHA1=m
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set
#
# Ciphers
#
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig
index db082ce..ab45fd9 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -348,7 +348,7 @@ CONFIG_XFRM_USER=y
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
# CONFIG_XFRM_STATISTICS is not set
-CONFIG_NET_KEY=m
+CONFIG_NET_KEY=y
# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -372,12 +372,12 @@ CONFIG_IP_PIMSM_V2=y
CONFIG_ARPD=y
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
+CONFIG_INET_ESP=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
CONFIG_INET_TUNNEL=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
# CONFIG_INET_XFRM_MODE_BEET is not set
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=y
@@ -1772,16 +1772,16 @@ CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
-CONFIG_CRYPTO_SHA1=m
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set
#
# Ciphers
#
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=y
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
--
1.6.4.4
^ permalink raw reply related
* [RESEND][PATCH 0/8] spi_mpc8xxx: Add support for DMA transfers
From: Anton Vorontsov @ 2009-10-12 16:48 UTC (permalink / raw)
To: Kumar Gala
Cc: David Brownell, Greg Kroah-Hartman, linux-kernel, linuxppc-dev,
spi-devel-general, Andrew Morton
Hello Kumar,
There are Acks from Greg KH and David Brownell to pass the whole
patchset via PowerPC tree. Can you please apply it?
Thanks,
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply
* [PATCH 1/8] powerpc/cpm: Remove SPI defines and spi structs
From: Anton Vorontsov @ 2009-10-12 16:49 UTC (permalink / raw)
To: Kumar Gala
Cc: David Brownell, Greg Kroah-Hartman, linux-kernel, linuxppc-dev,
spi-devel-general, Andrew Morton
In-Reply-To: <20091012164841.GA32214@oksana.dev.rtsoft.ru>
When cpm2.h included into spi_mpc8xxx driver, the SPI defines
in the header conflict with defines in the driver.
We don't need them in the header file, so remove them. Plus
remove "struct spi", we'll use a better version in the driver.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
arch/powerpc/include/asm/cpm1.h | 45 ---------------------------------------
arch/powerpc/include/asm/cpm2.h | 39 ---------------------------------
2 files changed, 0 insertions(+), 84 deletions(-)
diff --git a/arch/powerpc/include/asm/cpm1.h b/arch/powerpc/include/asm/cpm1.h
index 7685ffd..81b0119 100644
--- a/arch/powerpc/include/asm/cpm1.h
+++ b/arch/powerpc/include/asm/cpm1.h
@@ -478,51 +478,6 @@ typedef struct iic {
char res2[2]; /* Reserved */
} iic_t;
-/* SPI parameter RAM.
-*/
-typedef struct spi {
- ushort spi_rbase; /* Rx Buffer descriptor base address */
- ushort spi_tbase; /* Tx Buffer descriptor base address */
- u_char spi_rfcr; /* Rx function code */
- u_char spi_tfcr; /* Tx function code */
- ushort spi_mrblr; /* Max receive buffer length */
- uint spi_rstate; /* Internal */
- uint spi_rdp; /* Internal */
- ushort spi_rbptr; /* Internal */
- ushort spi_rbc; /* Internal */
- uint spi_rxtmp; /* Internal */
- uint spi_tstate; /* Internal */
- uint spi_tdp; /* Internal */
- ushort spi_tbptr; /* Internal */
- ushort spi_tbc; /* Internal */
- uint spi_txtmp; /* Internal */
- uint spi_res;
- ushort spi_rpbase; /* Relocation pointer */
- ushort spi_res2;
-} spi_t;
-
-/* SPI Mode register.
-*/
-#define SPMODE_LOOP ((ushort)0x4000) /* Loopback */
-#define SPMODE_CI ((ushort)0x2000) /* Clock Invert */
-#define SPMODE_CP ((ushort)0x1000) /* Clock Phase */
-#define SPMODE_DIV16 ((ushort)0x0800) /* BRG/16 mode */
-#define SPMODE_REV ((ushort)0x0400) /* Reversed Data */
-#define SPMODE_MSTR ((ushort)0x0200) /* SPI Master */
-#define SPMODE_EN ((ushort)0x0100) /* Enable */
-#define SPMODE_LENMSK ((ushort)0x00f0) /* character length */
-#define SPMODE_LEN4 ((ushort)0x0030) /* 4 bits per char */
-#define SPMODE_LEN8 ((ushort)0x0070) /* 8 bits per char */
-#define SPMODE_LEN16 ((ushort)0x00f0) /* 16 bits per char */
-#define SPMODE_PMMSK ((ushort)0x000f) /* prescale modulus */
-
-/* SPIE fields */
-#define SPIE_MME 0x20
-#define SPIE_TXE 0x10
-#define SPIE_BSY 0x04
-#define SPIE_TXB 0x02
-#define SPIE_RXB 0x01
-
/*
* RISC Controller Configuration Register definitons
*/
diff --git a/arch/powerpc/include/asm/cpm2.h b/arch/powerpc/include/asm/cpm2.h
index 990ff19..236cfa3 100644
--- a/arch/powerpc/include/asm/cpm2.h
+++ b/arch/powerpc/include/asm/cpm2.h
@@ -654,45 +654,6 @@ typedef struct iic {
uint iic_txtmp; /* Internal */
} iic_t;
-/* SPI parameter RAM.
-*/
-typedef struct spi {
- ushort spi_rbase; /* Rx Buffer descriptor base address */
- ushort spi_tbase; /* Tx Buffer descriptor base address */
- u_char spi_rfcr; /* Rx function code */
- u_char spi_tfcr; /* Tx function code */
- ushort spi_mrblr; /* Max receive buffer length */
- uint spi_rstate; /* Internal */
- uint spi_rdp; /* Internal */
- ushort spi_rbptr; /* Internal */
- ushort spi_rbc; /* Internal */
- uint spi_rxtmp; /* Internal */
- uint spi_tstate; /* Internal */
- uint spi_tdp; /* Internal */
- ushort spi_tbptr; /* Internal */
- ushort spi_tbc; /* Internal */
- uint spi_txtmp; /* Internal */
- uint spi_res; /* Tx temp. */
- uint spi_res1[4]; /* SDMA temp. */
-} spi_t;
-
-/* SPI Mode register.
-*/
-#define SPMODE_LOOP ((ushort)0x4000) /* Loopback */
-#define SPMODE_CI ((ushort)0x2000) /* Clock Invert */
-#define SPMODE_CP ((ushort)0x1000) /* Clock Phase */
-#define SPMODE_DIV16 ((ushort)0x0800) /* BRG/16 mode */
-#define SPMODE_REV ((ushort)0x0400) /* Reversed Data */
-#define SPMODE_MSTR ((ushort)0x0200) /* SPI Master */
-#define SPMODE_EN ((ushort)0x0100) /* Enable */
-#define SPMODE_LENMSK ((ushort)0x00f0) /* character length */
-#define SPMODE_PMMSK ((ushort)0x000f) /* prescale modulus */
-
-#define SPMODE_LEN(x) ((((x)-1)&0xF)<<4)
-#define SPMODE_PM(x) ((x) &0xF)
-
-#define SPI_EB ((u_char)0x10) /* big endian byte order */
-
/* IDMA parameter RAM
*/
typedef struct idma {
--
1.6.3.3
^ permalink raw reply related
* [PATCH 2/8] powerpc/qe&cpm2: Avoid redefinitions in CPM2 and QE headers
From: Anton Vorontsov @ 2009-10-12 16:49 UTC (permalink / raw)
To: Kumar Gala
Cc: David Brownell, Greg Kroah-Hartman, linux-kernel, linuxppc-dev,
spi-devel-general, Andrew Morton
In-Reply-To: <20091012164841.GA32214@oksana.dev.rtsoft.ru>
struct mcc defined in both immap_qe.h and immap_cpm2.h, so they will
conflic when included in a single file. The mcc struct is easy to deal
with, since it isn't used in any driver (yet), so let's just rename QE
version to qe_mcc.
The ucb_ctlr is a bit trickier, since it is used by fsl_qe_udc driver,
and the driver supports both CPM and QE UDCs, plus the QE version is
used to form a bigger immap struct.
I don't want to touch too much of USB code in this series, so for now
let's just copy most generic version into the common cpm.h header,
later we'll create cpm_usb.h where we'll place common USB structs that
are used by QE/CPM UDC and QE Host drivers (FHCI).
And as for the structs in qe.h and cpm2.h, just prefix them with qe_
and cpm_.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
arch/powerpc/include/asm/cpm.h | 22 ++++++++++++++++++++++
arch/powerpc/include/asm/immap_cpm2.h | 2 +-
arch/powerpc/include/asm/immap_qe.h | 8 ++++----
3 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h
index 24d79e3..b5f1534 100644
--- a/arch/powerpc/include/asm/cpm.h
+++ b/arch/powerpc/include/asm/cpm.h
@@ -5,6 +5,28 @@
#include <linux/types.h>
#include <linux/of.h>
+/*
+ * USB Controller pram common to QE and CPM.
+ */
+struct usb_ctlr {
+ u8 usb_usmod;
+ u8 usb_usadr;
+ u8 usb_uscom;
+ u8 res1[1];
+ __be16 usb_usep[4];
+ u8 res2[4];
+ __be16 usb_usber;
+ u8 res3[2];
+ __be16 usb_usbmr;
+ u8 res4[1];
+ u8 usb_usbs;
+ /* Fields down below are QE-only */
+ __be16 usb_ussft;
+ u8 res5[2];
+ __be16 usb_usfrn;
+ u8 res6[0x22];
+} __attribute__ ((packed));
+
/* Opcodes common to CPM1 and CPM2
*/
#define CPM_CR_INIT_TRX ((ushort)0x0000)
diff --git a/arch/powerpc/include/asm/immap_cpm2.h b/arch/powerpc/include/asm/immap_cpm2.h
index d4f069b..7c64fda 100644
--- a/arch/powerpc/include/asm/immap_cpm2.h
+++ b/arch/powerpc/include/asm/immap_cpm2.h
@@ -549,7 +549,7 @@ typedef struct comm_proc {
/* USB Controller.
*/
-typedef struct usb_ctlr {
+typedef struct cpm_usb_ctlr {
u8 usb_usmod;
u8 usb_usadr;
u8 usb_uscom;
diff --git a/arch/powerpc/include/asm/immap_qe.h b/arch/powerpc/include/asm/immap_qe.h
index c346d0b..4e10f50 100644
--- a/arch/powerpc/include/asm/immap_qe.h
+++ b/arch/powerpc/include/asm/immap_qe.h
@@ -210,7 +210,7 @@ struct sir {
} __attribute__ ((packed));
/* USB Controller */
-struct usb_ctlr {
+struct qe_usb_ctlr {
u8 usb_usmod;
u8 usb_usadr;
u8 usb_uscom;
@@ -229,7 +229,7 @@ struct usb_ctlr {
} __attribute__ ((packed));
/* MCC */
-struct mcc {
+struct qe_mcc {
__be32 mcce; /* MCC event register */
__be32 mccm; /* MCC mask register */
__be32 mccf; /* MCC configuration register */
@@ -431,9 +431,9 @@ struct qe_immap {
struct qe_mux qmx; /* QE Multiplexer */
struct qe_timers qet; /* QE Timers */
struct spi spi[0x2]; /* spi */
- struct mcc mcc; /* mcc */
+ struct qe_mcc mcc; /* mcc */
struct qe_brg brg; /* brg */
- struct usb_ctlr usb; /* USB */
+ struct qe_usb_ctlr usb; /* USB */
struct si1 si1; /* SI */
u8 res11[0x800];
struct sir sir; /* SI Routing Tables */
--
1.6.3.3
^ permalink raw reply related
* [PATCH 3/8] powerpc/cpm: Move CPMFCR_* defines into cpm.h
From: Anton Vorontsov @ 2009-10-12 16:49 UTC (permalink / raw)
To: Kumar Gala
Cc: David Brownell, Greg Kroah-Hartman, linux-kernel, linuxppc-dev,
spi-devel-general, Andrew Morton
In-Reply-To: <20091012164841.GA32214@oksana.dev.rtsoft.ru>
The bits are generic to CPM devices, so let's move them to the
common header file, so drivers won't need to privately reintroduce
another bunch of the same bits (as we can't include cpm2.h header
together with cpm1.h).
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
arch/powerpc/include/asm/cpm.h | 16 ++++++++++++++++
arch/powerpc/include/asm/cpm2.h | 8 --------
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h
index b5f1534..ea3fdb9 100644
--- a/arch/powerpc/include/asm/cpm.h
+++ b/arch/powerpc/include/asm/cpm.h
@@ -27,6 +27,22 @@ struct usb_ctlr {
u8 res6[0x22];
} __attribute__ ((packed));
+/*
+ * Function code bits, usually generic to devices.
+ */
+#ifdef CONFIG_CPM1
+#define CPMFCR_GBL ((u_char)0x00) /* Flag doesn't exist in CPM1 */
+#define CPMFCR_TC2 ((u_char)0x00) /* Flag doesn't exist in CPM1 */
+#define CPMFCR_DTB ((u_char)0x00) /* Flag doesn't exist in CPM1 */
+#define CPMFCR_BDB ((u_char)0x00) /* Flag doesn't exist in CPM1 */
+#else
+#define CPMFCR_GBL ((u_char)0x20) /* Set memory snooping */
+#define CPMFCR_TC2 ((u_char)0x04) /* Transfer code 2 value */
+#define CPMFCR_DTB ((u_char)0x02) /* Use local bus for data when set */
+#define CPMFCR_BDB ((u_char)0x01) /* Use local bus for BD when set */
+#endif
+#define CPMFCR_EB ((u_char)0x10) /* Set big endian byte order */
+
/* Opcodes common to CPM1 and CPM2
*/
#define CPM_CR_INIT_TRX ((ushort)0x0000)
diff --git a/arch/powerpc/include/asm/cpm2.h b/arch/powerpc/include/asm/cpm2.h
index 236cfa3..f42e9ba 100644
--- a/arch/powerpc/include/asm/cpm2.h
+++ b/arch/powerpc/include/asm/cpm2.h
@@ -124,14 +124,6 @@ static inline void cpm2_fastbrg(uint brg, uint rate, int div16)
__cpm2_setbrg(brg, rate, CPM2_BRG_INT_CLK, div16, CPM_BRG_EXTC_INT);
}
-/* Function code bits, usually generic to devices.
-*/
-#define CPMFCR_GBL ((u_char)0x20) /* Set memory snooping */
-#define CPMFCR_EB ((u_char)0x10) /* Set big endian byte order */
-#define CPMFCR_TC2 ((u_char)0x04) /* Transfer code 2 value */
-#define CPMFCR_DTB ((u_char)0x02) /* Use local bus for data when set */
-#define CPMFCR_BDB ((u_char)0x01) /* Use local bus for BD when set */
-
/* Parameter RAM offsets from the base.
*/
#define PROFF_SCC1 ((uint)0x8000)
--
1.6.3.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox