* [PATCH] ARM i.MX53: enable fec driver on EVK board
From: Yong Shen @ 2011-01-06 9:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110106061647.GB30232@jasper.tkos.co.il>
Hi Baruch,
Thanks for comments.
>>
>> +static inline void fec_reset(void)
>
> For the sake of clearer stack traces I prefer a less generic name for this
> routine, something like mx53_evk_fec_reset().
>
Acked.
>> +{
>> + ? ? int ret;
>> +
>> + ? ? /* reset FEC PHY */
>> + ? ? ret = gpio_request(SMD_FEC_PHY_RST, "fec-phy-reset");
>> + ? ? if (ret) {
>> + ? ? ? ? ? ? printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
>> + ? ? ? ? ? ? return;
>> + ? ? }
>> + ? ? gpio_direction_output(SMD_FEC_PHY_RST, 0);
>> + ? ? gpio_set_value(SMD_FEC_PHY_RST, 0);
>
> This seems to be redundant. gpio_direction_output() has already set the value
> to 0.
You are right. But, gpio_set_value is meant to be here to show the
process of fec reset: first pull low and then pull high. And
gpio_direction_output here is for direction configuration although it
has the ability of configure output value.
cheers
Yong
^ permalink raw reply
* [PATCH v2] i.MX51 Framebuffer support
From: Russell King - ARM Linux @ 2011-01-06 9:42 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D246C54.9060503@free.fr>
On Wed, Jan 05, 2011 at 02:04:20PM +0100, Julien Boibessot wrote:
> Hello,
>
> Sascha Hauer a ?crit :
> > The following series adds i.MX51 framebuffer support based on the IPUv3. It
> > is not perfect but I decided it is good enough to open it for a wider audience
> > and collect first reviews. I tested this on a babbage board using both outputs
> > (VGA/DVI) with different resolutions up to 1680x1050 and different colour depths.
> > I also tested it on one custom board using a fixed display setting.
> >
> This driver is also working fine for me on a custom i.MX51 board with a
> 800x480 18 bits TFT LCD (16bpp mode).
>
> The only strange thing I noticed was a kind of uggly sprite/artefact
> (32x32, I would say) appearing at the same time as the Linux console. I
> think it may be related to a hardware cursor badly (?) initialised, but
> I didn't find a fix yet.
> It disappears when I launch a graphical application (Qt or SDL).
In the top left corner? That'll be the linux penguin logo, and if it's
not coming out correctly, your framebuffer driver is badly broken.
Maybe your RGB bitfield information or visual is wrong?
^ permalink raw reply
* [PATCH 1/2] stackprotector: add stack smashing protector generic implementation
From: Russell King - ARM Linux @ 2011-01-06 9:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D245D16.5010702@st.com>
On Wed, Jan 05, 2011 at 12:59:18PM +0100, Carmelo AMOROSO wrote:
> Is someone interested into this stuff ?
Looking at the CC list, you're asking the people who already have the
support in the kernel. I suspect they don't have that much of an
interest in it.
Maybe you should try asking other architecture maintainers who don't
support this yet? Not every architecture maintainer is subscribed to,
or reads LKML...
^ permalink raw reply
* [PATCH 3/6] i2c/pxa2xx: Add PCI support for PXA I2C controller
From: Russell King - ARM Linux @ 2011-01-06 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110105230834.GA26399@suse.de>
On Wed, Jan 05, 2011 at 03:08:34PM -0800, Greg KH wrote:
> On Wed, Jan 05, 2011 at 11:03:42PM +0000, Russell King - ARM Linux wrote:
> > On Wed, Jan 05, 2011 at 05:51:00PM +0100, Sebastian Andrzej Siewior wrote:
> > > +static void plat_dev_release(struct device *dev)
> > > +{
> > > + struct ce4100_i2c_device *sd = container_of(dev,
> > > + struct ce4100_i2c_device, pdev.dev);
> > > +
> > > + of_device_node_put(&sd->pdev.dev);
> > > +}
> > > +static int add_i2c_device(struct pci_dev *dev, int bar,
> > > + struct ce4100_i2c_device *sd)
> > > +{
> > > + struct platform_device *pdev = &sd->pdev;
> > > + struct i2c_pxa_platform_data *pdata = &sd->pdata;
> > ...
> > > + pdev->name = "ce4100-i2c";
> > > + pdev->dev.release = plat_dev_release;
> > > + pdev->dev.parent = &dev->dev;
> > > +
> > > + pdev->dev.platform_data = pdata;
> > > + pdev->resource = sd->res;
> > ...
> > > +static int __devinit ce4100_i2c_probe(struct pci_dev *dev,
> > > + const struct pci_device_id *ent)
> > > +{
> > > + sds = kzalloc(sizeof(*sds), GFP_KERNEL);
> > > + if (!sds)
> > > + goto err_mem;
> > > +
> > > + pci_set_drvdata(dev, sds);
> > > +
> > > + for (i = 0; i < ARRAY_SIZE(sds->sd); i++) {
> > > + ret = add_i2c_device(dev, i, &sds->sd[i]);
> > > + if (ret) {
> > > + while (--i >= 0)
> > > + platform_device_unregister(&sds->sd[i].pdev);
> > ...
> > > +static void __devexit ce4100_i2c_remove(struct pci_dev *dev)
> > ...
> > > + for (i = 0; i < ARRAY_SIZE(sds->sd); i++)
> > > + platform_device_unregister(&sds->sd[i].pdev);
> > > +
> > > + pci_disable_device(dev);
> > > + kfree(sds);
> > > +}
> >
> > I see we're still repeating the same mistakes with lifetime rules of
> > sysfs objects.
> >
> > Any struct device which has been registered into the device model can
> > remain indefinitely live after it's been unregistered (by, eg, if
> > userspace holds a reference to it via sysfs.)
>
> Actually this race is almost not possible these days with the rework
> that Tejun did on sysfs, so it's not easy to test for this anymore.
Is it wise to make such a problematical bug harder to trigger without
completely preventing it triggering?
A different approach was taken with IRQ handling where people were
registering handlers before the driver was ready for it to be called -
request_irq() would explicitly call the handler as soon as it was
registered to provoke bugs.
Surely for these lifetime violations a similar approach should be taken.
Make the kernel more likely to oops should a violation occur before the
developer can get the code out the door. One way I can think of doing
that is when devices are unregistered but not yet released, place them
on a list which is periodically scanned, and not only is the device
dereferenced by also the release function.
When the use count drops to zero, don't immediately release, but wait
a number of polls.
If either goes away before the device has been released, then we
predictably oops, and the developer gets to know about his violation
of the rules immediately.
^ permalink raw reply
* [PATCH v3 08/10] ARM: mxs: add ocotp read function
From: Russell King - ARM Linux @ 2011-01-06 9:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110106005052.GA4476@shareable.org>
On Thu, Jan 06, 2011 at 12:50:52AM +0000, Jamie Lokier wrote:
> Russell King - ARM Linux wrote:
> > On Wed, Jan 05, 2011 at 07:44:18PM +0000, Jamie Lokier wrote:
> > > 'git show 534be1d5' explains how it works: cpu_relax() flushes buffered
> > > writes from _this_ CPU, so that other CPUs which are polling can make
> > > progress, which avoids this CPU getting stuck if there is an indirect
> > > dependency (no matter how convoluted) between what it's polling and which
> > > it wrote just before.
> > >
> > > So cpu_relax() is *essential* in some polling loops, not a hint.
> > >
> > > In principle that could happen for I/O polling, if (a) buffered memory
> > > writes are delayed by I/O read transactions, and (b) the device state we're
> > > waiting on depends on I/O yet to be done on another CPU, which could be
> > > polling memory first (e.g. a spinlock).
> > >
> > > I doubt (a) in practice - but what about buses that block during I/O read?
> > > (I have a chip like that here, but it's ARMv4T.)
> >
> > Let's be clear - ARMv5 and below generally are well ordered architectures
> > within the limits of caching. There are cases where the write buffer
> > allows two writes to pass each other. However, for IO we generally map
> > these - especially for ARMv4 and below - as 'uncacheable unbufferable'.
> > So on these, if the program says "read this location" the pipeline will
> > stall until the read has been issued - and if you use the result in the
> > next instruction, it will stall until the data is available. So really,
> > it's not a problem here.
> >
> > ARMv6 and above have a weakly ordered memory model with speculative
> > prefetching, so memory reads/writes can be completely unordered. Device
> > accesses can pass memory accesses, but device accesses are always visible
> > in program order with respect to each other.
> >
> > So, if you're spinning in a loop reading an IO device, all previous IO
> > accesses will be completed (in all ARM architectures) before the result
> > of your read is evaluated.
>
> No, that wasn't the scenario - it was:
>
> You're spinning reading an IO device, whose state depends indirectly
> on a *CPU memory* write that is forever buffered.
>
> (Go and re-read 'git show 534be1d5' if you haven't already.)
I know what that's about, and it's about memory based accesses _only_.
What you're talking about is a programming error. Such errors cause
data corruption if you're talking about DMA stuff.
At the moment, the solution to that is to put whatever's necessary into
readl/writel to ensure that they behave as ordered operations with
respect to everything else. You'll find that on ARM, writel has a
barrier before it to ensure memory writes are visible before the device
write, and on readl there's a barrier to ensure that no memory read can
happen before the IO device read.
cpu_relax() has nothing to do with ensuring ordering with devices.
With relaxed IO operations, the responsibility for ensuring proper ordering
between memory and IO falls to the programmer.
^ permalink raw reply
* [RFC 2/5] ARM: P2V: avoid initializers and assembly using PHYS_OFFSET
From: Russell King - ARM Linux @ 2011-01-06 9:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110106085145.GB26617@pengutronix.de>
On Thu, Jan 06, 2011 at 09:51:45AM +0100, Sascha Hauer wrote:
> As Russell noted this conflicts with the current i.MX branch. In current
> i.MX branch we have:
>
> - .boot_params = PHYS_OFFSET + 0x100,
> + .boot_params = MX51_PHYS_OFFSET + 0x100,
>
> PLAT_PHYS_OFFSET should be defined to MX51_PHYS_OFFSET, so it shouldn't
> matter which solution to the conflict we choose.
I've actually dropped my modifications to this files as your change
to them makes more sense longer term.
^ permalink raw reply
* [PATCH] arm: mm: Poison freed init memory
From: Russell King - ARM Linux @ 2011-01-06 9:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D255263.7040106@codeaurora.org>
On Wed, Jan 05, 2011 at 09:25:55PM -0800, Stephen Boyd wrote:
> On 01/05/2011 12:26 PM, Russell King - ARM Linux wrote:
> > On Wed, Jan 05, 2011 at 11:47:25AM -0800, Stephen Boyd wrote:
> >> Poisoning __init marked memory can be useful when tracking down
> >> obscure memory corruption bugs. When a pointer is 0xCCCCCCCC in an
> >
> > That's a bad idea for a value. With a 3GB page offset and 256MB or
> > more memory, accesses to such an address will always succeed.
> >
> > There's two things to be considered when selecting a possible poison
> > value:
> >
> > 1. what value is guaranteed to provoke an undefined instruction exception?
> > 2. what value when used as an address and dereferenced is mostly always
> > going to abort?
> >
> > 1 for ARM mode implies an 0xe7fXXXfX value. For Thumb mode 0xdeXX. We
> > use this space for breakpoints.
> >
> > 2 unfortunately depends on the platform.
>
> A coworker proposed we use a SWI instruction. We could do that if the
> poison is 0xEF and then do something in the SWI handler where that
> number causes us to blow up?
Doesn't work with EABI - the comment field in the SWI instruction is
ignored on EABI.
> If I'm following correctly, point 1 is about __init functions and point
> 2 is about __initdata. I'm more concerned about __initdata because
> __init functions called from non __init marked functions are usually
> caught with section mismatch checks. Also, if we're jumping to
> 0xCCCCCCCC we're probably not in the text section of the kernel with a
But, as I pointed out, you don't know that 0xCCCCCCCC isn't a valid
address _and_ on modern platforms it won't fault. So it's pointless
to use it as a poison value.
^ permalink raw reply
* [RFC 2/5] ARM: P2V: avoid initializers and assembly using PHYS_OFFSET
From: Sascha Hauer @ 2011-01-06 8:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <E1PaDOv-00023d-Gi@rmk-PC.arm.linux.org.uk>
On Tue, Jan 04, 2011 at 08:22:37PM +0000, Russell King - ARM Linux wrote:
> As PHYS_OFFSET will be becoming a variable, we can't have it used in
> initializers nor assembly code. Replace those in generic code with
> a run-time initialization. Replace those in platform code using the
> individual platform specific PLAT_PHYS_OFFSET.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
> arch/arm/kernel/setup.c | 4 +++-
> arch/arm/mach-msm/board-msm7x27.c | 8 ++++----
> arch/arm/mach-msm/board-msm7x30.c | 6 +++---
> arch/arm/mach-msm/board-qsd8x50.c | 4 ++--
> arch/arm/mach-msm/board-sapphire.c | 2 +-
> arch/arm/mach-mx5/board-cpuimx51.c | 2 +-
> arch/arm/mach-mx5/board-cpuimx51sd.c | 2 +-
> arch/arm/mach-mx5/board-mx51_3ds.c | 2 +-
> arch/arm/mach-pxa/balloon3.c | 2 +-
> arch/arm/mach-realview/realview_eb.c | 2 +-
> arch/arm/mach-realview/realview_pb1176.c | 2 +-
> arch/arm/mach-realview/realview_pb11mp.c | 2 +-
> arch/arm/mach-realview/realview_pba8.c | 2 +-
> arch/arm/mach-realview/realview_pbx.c | 2 +-
> arch/arm/mach-s5pv210/sleep.S | 2 +-
> arch/arm/mach-tcc8k/board-tcc8000-sdk.c | 2 +-
> arch/arm/mach-vexpress/ct-ca9x4.c | 2 +-
> 17 files changed, 25 insertions(+), 23 deletions(-)
>
> diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-mx5/board-cpuimx51.c
> index 6a9792f..c4c3a9c 100644
> --- a/arch/arm/mach-mx5/board-cpuimx51.c
> +++ b/arch/arm/mach-mx5/board-cpuimx51.c
> @@ -292,7 +292,7 @@ static struct sys_timer mxc_timer = {
>
> MACHINE_START(EUKREA_CPUIMX51, "Eukrea CPUIMX51 Module")
> /* Maintainer: Eric B??nard <eric@eukrea.com> */
> - .boot_params = PHYS_OFFSET + 0x100,
> + .boot_params = PLAT_PHYS_OFFSET + 0x100,
> .map_io = mx51_map_io,
> .init_irq = mx51_init_irq,
> .init_machine = eukrea_cpuimx51_init,
> diff --git a/arch/arm/mach-mx5/board-cpuimx51sd.c b/arch/arm/mach-mx5/board-cpuimx51sd.c
> index 4b3a611..b887381 100644
> --- a/arch/arm/mach-mx5/board-cpuimx51sd.c
> +++ b/arch/arm/mach-mx5/board-cpuimx51sd.c
> @@ -323,7 +323,7 @@ static struct sys_timer mxc_timer = {
>
> MACHINE_START(EUKREA_CPUIMX51SD, "Eukrea CPUIMX51SD")
> /* Maintainer: Eric B??nard <eric@eukrea.com> */
> - .boot_params = PHYS_OFFSET + 0x100,
> + .boot_params = PLAT_PHYS_OFFSET + 0x100,
> .map_io = mx51_map_io,
> .init_irq = mx51_init_irq,
> .init_machine = eukrea_cpuimx51sd_init,
> diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-mx5/board-mx51_3ds.c
> index 79ce8dc..10e6ce3 100644
> --- a/arch/arm/mach-mx5/board-mx51_3ds.c
> +++ b/arch/arm/mach-mx5/board-mx51_3ds.c
> @@ -186,7 +186,7 @@ static struct sys_timer mxc_timer = {
>
> MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board")
> /* Maintainer: Freescale Semiconductor, Inc. */
> - .boot_params = PHYS_OFFSET + 0x100,
> + .boot_params = PLAT_PHYS_OFFSET + 0x100,
> .map_io = mx51_map_io,
> .init_irq = mx51_init_irq,
> .init_machine = mxc_board_init,
As Russell noted this conflicts with the current i.MX branch. In current
i.MX branch we have:
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = MX51_PHYS_OFFSET + 0x100,
PLAT_PHYS_OFFSET should be defined to MX51_PHYS_OFFSET, so it shouldn't
matter which solution to the conflict we choose.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [patch 2/5] ulpi: handle ULPI_OTG_CTRL_CHRGVBUS
From: Igor Grinberg @ 2011-01-06 7:54 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTimWfucS6XqovGDCyVhM20HgKpxCwTOkeHKzqK29@mail.gmail.com>
On 01/04/11 22:03, Matt Sealey wrote:
> On Tue, Jan 4, 2011 at 2:00 PM, Arnaud Patard <arnaud.patard@rtp-net.org> wrote:
>> Igor Grinberg <grinberg@compulab.co.il> writes:
>>
>> Adding Matt Sealey in CC:. he's the product development analyst so he
>> knows the hardware (unlike me).
>>>>> Also, what ulpi vendor/product id is reported in ulpi_init()?
>>>> ULPI transceiver vendor/product ID 0x0424/0x0006
>>>> Found SMSC USB3319 ULPI transceiver.
>>> SMSC USB3319 does not have either an integrated Vbus switch or Charge Pump,
>>> For the device connected to that transceiver could work properly,
>>> there is a need in _external Vbus switch_ , that should be enabled using
>>> some kind of CPEN pin (can be GPIO).
>>> This means, that you don't even need to call ulpi_set_vbus().
>>>
>>> Either way, this patch is NAK.
>>> I think you need to check your hardware (in particular Vbus supply).
> Hey guys,
Hi
Thanks for the information. Now I am finally getting the picture of what's is
going on there...
> On the Smartbook at least both USB host ports (H1 and H2) on the board
> (one port each) are connected directly to 4-port USB hubs (SMSC2514).
> We don't have anything on there except that connection: the hub should
> handle VBUS properly. Both ports use an SMSC3317 (just a 3311 with a
> built in 3.3V supply so the id and behavior should be identical).
OK, so the SMSC331x ulpi transceiver is connected to the SMSC2514 usb hub,
so all the peripheral devices (ethernet/wifi/bt/hid) are connected to the
downstream ports of that hub and thus get their Vbus as expected. This is fine.
> On the Smarttop H1 is connected to a 4-port USB hub (Terminus FE1.1)
> with the same configuration. Same PHY. The DR port is connected
> directly to an ASIX ethernet controller. VBUS seems routed to a test
> point.
>
> I'm curious exactly what the real problem here is: that VBUS is
> basically not being handled correctly? It should be driven or not? I'm
> not entirely familiar with the specification.
SMSC2514 usb hub will not provide power to its D+ and D- pull-up resistors
until it detects a Vbus enabled on the upstream port. This is totally fine.
SMSC331x ulpi transceiver does not have either an integrated Vbus switch or
an integrated charge pump - this means that it cannot provide a Vbus to the hub.
The hub in its turn does not power the pull-up resistors and peripheral devices
are not being connected to the usb subsystem.
With this patch applied, SMSC331x ulpi transceiver issues an SRP pulses on the Vbus
and hub senses that there is something that looks like Vbus and then enables the
pull-up resistors -> peripheral devices are being connected to the usb subsystem.
This behavior violates the ULPI (and mostly certain OTG and may be also USB 2.0)
specification and SMSC2514 usb hub datasheet.
According to the SMSC2514 usb hub datasheet, VBUS_DET pin has to be connected
to a valid Vbus from the upstream port, but SMSC331x does not provide this Vbus.
This means that you should have add a Vbus switch or a charge pump to the
VBUS_DET pin of the usb hub and provide means (like GPIO) to enable/disable that
switch or charge pump.
This is h/w design bug we are dealing with.
The best solution to this would be to add a missing h/w component.
Now, I understand that it can be kind a problematic ;)
But, we cannot violate the ULPI spec and the generic driver to workaround
some h/w problem that is existing in some specific configuration and hopefully will
be fixed in the next h/w revisions. Therefore, as I said before, this patch is NAK.
What we can do is:
1) implement the int (*start_srp)(struct otg_transceiver *otg);
method as defined by the ULPI spec.
2) and then add a call (along with huge comment explaining this workaround)
to otg_start_srp(). I'd recommend to restrict this call to that specific board somehow,
but it is up to Sascha to decide where to put it.
--
Regards,
Igor.
^ permalink raw reply
* [PATCH 4/9] fb: export fb mode db table
From: Paul Mundt @ 2011-01-06 7:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1291902441-24712-5-git-send-email-s.hauer@pengutronix.de>
On Thu, Dec 09, 2010 at 02:47:16PM +0100, Sascha Hauer wrote:
> The different modes can be useful for drivers. Currently there is
> no way to expose the modes to sysfs, so export them.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
I'll admit I don't really like the idea of exposing the modedb to drivers
in this way, but given that we're already doing it for the vesa and cea
modes, allowing drivers to copy ranges in to their modelist from the
standard db is probably something we can live with.
The mode list dumping is basically a blatant sysfs abuse already though,
and it would be much cleaner simply to back the mode store with an
fb_find/try_mode() pair that grovels all the right places in addition to
doing a pass over the fb_info's modelist.
^ permalink raw reply
* [PATCH v4 10/10] ARM: mxs: add initial pm support
From: Shawn Guo @ 2011-01-06 7:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294297998-26930-1-git-send-email-shawn.guo@freescale.com>
This is a very initial pm support and basically does nothing.
With this pm support entry, drivers can start testing their own
pm functions.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Let build of pm.c depend on CONFIG_PM
- Remove the blank line above device_initcall in pm.c
arch/arm/mach-mxs/Makefile | 2 ++
arch/arm/mach-mxs/pm.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/pm.c
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index f23ebbd..45a2925 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,6 +1,8 @@
# Common support
obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
+obj-$(CONFIG_PM) += pm.o
+
obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c
new file mode 100644
index 0000000..fb042da
--- /dev/null
+++ b/arch/arm/mach-mxs/pm.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include <mach/system.h>
+
+static int mxs_suspend_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ arch_idle();
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static struct platform_suspend_ops mxs_suspend_ops = {
+ .enter = mxs_suspend_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init mxs_pm_init(void)
+{
+ suspend_set_ops(&mxs_suspend_ops);
+ return 0;
+}
+device_initcall(mxs_pm_init);
--
1.7.1
^ permalink raw reply related
* [PATCH v4 09/10] ARM: mx28: read fec mac address from ocotp
From: Shawn Guo @ 2011-01-06 7:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294297998-26930-1-git-send-email-shawn.guo@freescale.com>
Read fec mac address from ocotp and save it into fec_platform_data
mac field for fec driver to use.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- It's not necessary to remove "const" for fec_platform_data from
platform-fec.c and devices-common.h, so add it back.
- Hard-coding Freescale OUI (00:04:9f) instead of just the first
two two octets.
- Correct the return of mx28evk_fec_get_mac() and check it
with caller
arch/arm/mach-mxs/mach-mx28evk.c | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index def6519..54fa512 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -129,12 +129,44 @@ static struct fec_platform_data mx28_fec_pdata[] = {
},
};
+static int __init mx28evk_fec_get_mac(void)
+{
+ int i, ret;
+ u32 val;
+
+ /*
+ * OCOTP only stores the last 4 octets for each mac address,
+ * so hard-code Freescale OUI (00:04:9f) here.
+ */
+ for (i = 0; i < 2; i++) {
+ ret = mxs_read_ocotp(0x20 + i * 0x10, 1, &val);
+ if (ret)
+ goto error;
+
+ mx28_fec_pdata[i].mac[0] = 0x00;
+ mx28_fec_pdata[i].mac[1] = 0x04;
+ mx28_fec_pdata[i].mac[2] = 0x9f;
+ mx28_fec_pdata[i].mac[3] = (val >> 16) & 0xff;
+ mx28_fec_pdata[i].mac[4] = (val >> 8) & 0xff;
+ mx28_fec_pdata[i].mac[5] = (val >> 0) & 0xff;
+ }
+
+ return 0;
+
+error:
+ pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
+ return ret;
+}
+
static void __init mx28evk_init(void)
{
mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
mx28_add_duart();
+ if (mx28evk_fec_get_mac())
+ pr_warn("%s: failed on fec mac setup\n", __func__);
+
mx28evk_fec_reset();
mx28_add_fec(0, &mx28_fec_pdata[0]);
#ifdef CONFIG_FEC2
--
1.7.1
^ permalink raw reply related
* [PATCH v4 08/10] ARM: mxs: add ocotp read function
From: Shawn Guo @ 2011-01-06 7:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294297998-26930-1-git-send-email-shawn.guo@freescale.com>
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
- Call cpu_relax() during polling
Changes for v2:
- Add mutex locking for mxs_read_ocotp()
- Use type size_t for count and i
- Add comment for clk_enable/disable skipping
- Add ERROR bit clearing and polling step
arch/arm/mach-mxs/Makefile | 2 +-
arch/arm/mach-mxs/include/mach/common.h | 1 +
arch/arm/mach-mxs/ocotp.c | 79 +++++++++++++++++++++++++++++++
3 files changed, 81 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-mxs/ocotp.c
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 39d3f9c..f23ebbd 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,5 +1,5 @@
# Common support
-obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index 59133eb..cf02552 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -13,6 +13,7 @@
struct clk;
+extern int mxs_read_ocotp(int offset, int count, u32 *values);
extern int mxs_reset_block(void __iomem *);
extern void mxs_timer_init(struct clk *, int);
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
new file mode 100644
index 0000000..e2d39aa
--- /dev/null
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+#include <mach/mxs.h>
+
+#define BM_OCOTP_CTRL_BUSY (1 << 8)
+#define BM_OCOTP_CTRL_ERROR (1 << 9)
+#define BM_OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
+
+static DEFINE_MUTEX(ocotp_mutex);
+
+int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
+{
+ void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
+ int timeout = 0x400;
+ size_t i;
+
+ mutex_lock(&ocotp_mutex);
+
+ /*
+ * clk_enable(hbus_clk) for ocotp can be skipped
+ * as it must be on when system is running.
+ */
+
+ /* try to clear ERROR bit */
+ __mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
+
+ /* check both BUSY and ERROR cleared */
+ while ((__raw_readl(ocotp_base) &
+ (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
+ cpu_relax();
+
+ if (unlikely(!timeout))
+ goto error_unlock;
+
+ /* open OCOTP banks for read */
+ __mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+ /* approximately wait 32 hclk cycles */
+ udelay(1);
+
+ /* poll BUSY bit becoming cleared */
+ timeout = 0x400;
+ while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
+ cpu_relax();
+
+ if (unlikely(!timeout))
+ goto error_unlock;
+
+ for (i = 0; i < count; i++, offset += 4)
+ *values++ = __raw_readl(ocotp_base + offset);
+
+ /* close banks for power saving */
+ __mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+ mutex_unlock(&ocotp_mutex);
+
+ return 0;
+
+error_unlock:
+ mutex_unlock(&ocotp_mutex);
+ pr_err("%s: timeout in reading OCOTP\n", __func__);
+ return -ETIMEDOUT;
+}
--
1.7.1
^ permalink raw reply related
* [PATCH v4 07/10] ARM: mx28: add the second fec device registration
From: Shawn Guo @ 2011-01-06 7:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294297998-26930-1-git-send-email-shawn.guo@freescale.com>
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/mach-mx28evk.c | 28 +++++++++++++++++++++++++---
1 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index d162e95..def6519 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -57,6 +57,19 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
MX28_PAD_ENET_CLK__CLKCTRL_ENET |
(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ /* fec1 */
+ MX28_PAD_ENET0_CRS__ENET1_RX_EN |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_RXD2__ENET1_RXD0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_RXD3__ENET1_RXD1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_COL__ENET1_TX_EN |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_TXD2__ENET1_TXD0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_TXD3__ENET1_TXD1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
/* phy power line */
MX28_PAD_SSP1_DATA3__GPIO_2_15 |
(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
@@ -106,8 +119,14 @@ static void __init mx28evk_fec_reset(void)
gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
}
-static const struct fec_platform_data mx28_fec_pdata __initconst = {
- .phy = PHY_INTERFACE_MODE_RMII,
+static struct fec_platform_data mx28_fec_pdata[] = {
+ {
+ /* fec0 */
+ .phy = PHY_INTERFACE_MODE_RMII,
+ }, {
+ /* fec1 */
+ .phy = PHY_INTERFACE_MODE_RMII,
+ },
};
static void __init mx28evk_init(void)
@@ -117,7 +136,10 @@ static void __init mx28evk_init(void)
mx28_add_duart();
mx28evk_fec_reset();
- mx28_add_fec(0, &mx28_fec_pdata);
+ mx28_add_fec(0, &mx28_fec_pdata[0]);
+#ifdef CONFIG_FEC2
+ mx28_add_fec(1, &mx28_fec_pdata[1]);
+#endif
}
static void __init mx28evk_timer_init(void)
--
1.7.1
^ permalink raw reply related
* [PATCH v4 06/10] ARM: mx28: update clock and device name for dual fec support
From: Shawn Guo @ 2011-01-06 7:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294297998-26930-1-git-send-email-shawn.guo@freescale.com>
Change device name from "fec" to "imx28-fec", so that fec driver
can distinguish mx28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
- Use "imx28-fec" as fec device name
Changes for v3:
- Change device name to "enet-mac"
arch/arm/mach-mxs/clock-mx28.c | 3 ++-
arch/arm/mach-mxs/devices/platform-fec.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index f20b254..e2a8b0f 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -606,7 +606,8 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
/* for amba-pl011 driver */
_REGISTER_CLOCK("duart", NULL, uart_clk)
- _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
_REGISTER_CLOCK("rtc", NULL, rtc_clk)
_REGISTER_CLOCK("pll2", NULL, pll2_clk)
_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
index c08168c..c42dff7 100644
--- a/arch/arm/mach-mxs/devices/platform-fec.c
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -45,6 +45,6 @@ struct platform_device *__init mxs_add_fec(
},
};
- return mxs_add_platform_device("fec", data->id,
+ return mxs_add_platform_device("imx28-fec", data->id,
res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
}
--
1.7.1
^ permalink raw reply related
* [PATCH v4 05/10] net/fec: add dual fec support for mx28
From: Shawn Guo @ 2011-01-06 7:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294297998-26930-1-git-send-email-shawn.guo@freescale.com>
This patch is to add mx28 dual fec support. Here are some key notes
for mx28 fec controller.
- The mx28 fec controller naming ENET-MAC is a different IP from FEC
used on other i.mx variants. But they are basically compatible
on software interface, so it's possible to share the same driver.
- ENET-MAC design on mx28 made an improper assumption that it runs
on a big-endian system. As the result, driver has to swap every
frame going to and coming from the controller.
- The external phys can only be configured by fec0, which means fec1
can not work independently and both phys need to be configured by
mii_bus attached on fec0.
- ENET-MAC reset will get mac address registers reset too.
- ENET-MAC MII/RMII mode and 10M/100M speed are configured
differently FEC.
- ETHER_EN bit must be set to get ENET-MAC interrupt work.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
- Use #ifndef CONFIG_ARM to include ColdFire header files
- Define quirk bits in id_entry.driver_data to handle controller
difference, which is more scalable than using device name
- Define fec0_mii_bus as a static function in fec_enet_mii_init
to fold the mii_bus instance attached on fec0
- Use cpu_to_be32 over __swab32 in function swap_buffer
Changes for v3:
- Move v2 changes into patch #3
- Use device name to check if it's running on ENET-MAC
drivers/net/Kconfig | 7 ++-
drivers/net/fec.c | 148 +++++++++++++++++++++++++++++++++++++++++++++------
drivers/net/fec.h | 5 +-
3 files changed, 139 insertions(+), 21 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4f1755b..f34629b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1944,18 +1944,19 @@ config 68360_ENET
config FEC
bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
- MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
+ MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
select PHYLIB
help
Say Y here if you want to use the built-in 10/100 Fast ethernet
controller on some Motorola ColdFire and Freescale i.MX processors.
config FEC2
- bool "Second FEC ethernet controller (on some ColdFire CPUs)"
+ bool "Second FEC ethernet controller"
depends on FEC
help
Say Y here if you want to use the second built-in 10/100 Fast
- ethernet controller on some Motorola ColdFire processors.
+ ethernet controller on some Motorola ColdFire and Freescale
+ i.MX processors.
config FEC_MPC52xx
tristate "MPC52xx FEC driver"
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 8a1c51f..2a71373 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -17,6 +17,8 @@
*
* Bug fixes and cleanup by Philippe De Muyter (phdm at macqel.be)
* Copyright (c) 2004-2006 Macq Electronique SA.
+ *
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
*/
#include <linux/module.h>
@@ -45,20 +47,36 @@
#include <asm/cacheflush.h>
-#ifndef CONFIG_ARCH_MXC
+#ifndef CONFIG_ARM
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#endif
#include "fec.h"
-#ifdef CONFIG_ARCH_MXC
-#include <mach/hardware.h>
+#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
#define FEC_ALIGNMENT 0xf
#else
#define FEC_ALIGNMENT 0x3
#endif
+#define DRIVER_NAME "fec"
+
+/* Controller is ENET-MAC */
+#define FEC_QUIRK_ENET_MAC (1 << 0)
+/* Controller needs driver to swap frame */
+#define FEC_QUIRK_SWAP_FRAME (1 << 1)
+
+static struct platform_device_id fec_devtype[] = {
+ {
+ .name = DRIVER_NAME,
+ .driver_data = 0,
+ }, {
+ .name = "imx28-fec",
+ .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME,
+ }
+};
+
static unsigned char macaddr[ETH_ALEN];
module_param_array(macaddr, byte, NULL, 0);
MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
@@ -129,7 +147,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
* account when setting it.
*/
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
+ defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
+ defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
#else
#define OPT_FRAME_SIZE 0
@@ -208,10 +227,23 @@ static void fec_stop(struct net_device *dev);
/* Transmitter timeout */
#define TX_TIMEOUT (2 * HZ)
+static void *swap_buffer(void *bufaddr, int len)
+{
+ int i;
+ unsigned int *buf = bufaddr;
+
+ for (i = 0; i < (len + 3) / 4; i++, buf++)
+ *buf = cpu_to_be32(*buf);
+
+ return bufaddr;
+}
+
static netdev_tx_t
fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
+ const struct platform_device_id *id_entry =
+ platform_get_device_id(fep->pdev);
struct bufdesc *bdp;
void *bufaddr;
unsigned short status;
@@ -256,6 +288,14 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
bufaddr = fep->tx_bounce[index];
}
+ /*
+ * Some design made an incorrect assumption on endian mode of
+ * the system that it's running on. As the result, driver has to
+ * swap every frame going to and coming from the controller.
+ */
+ if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
+ swap_buffer(bufaddr, skb->len);
+
/* Save skb pointer */
fep->tx_skbuff[fep->skb_cur] = skb;
@@ -424,6 +464,8 @@ static void
fec_enet_rx(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
+ const struct platform_device_id *id_entry =
+ platform_get_device_id(fep->pdev);
struct bufdesc *bdp;
unsigned short status;
struct sk_buff *skb;
@@ -487,6 +529,9 @@ fec_enet_rx(struct net_device *dev)
dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
DMA_FROM_DEVICE);
+ if (id_entry->driver_data & FEC_QUIRK_SWAP_FRAME)
+ swap_buffer(data, pkt_len);
+
/* This does 16 byte alignment, exactly what we need.
* The packet length includes FCS, but we don't want to
* include that when passing upstream as it messes up
@@ -689,6 +734,7 @@ static int fec_enet_mii_probe(struct net_device *dev)
char mdio_bus_id[MII_BUS_ID_SIZE];
char phy_name[MII_BUS_ID_SIZE + 3];
int phy_id;
+ int dev_id = fep->pdev->id;
fep->phy_dev = NULL;
@@ -700,6 +746,8 @@ static int fec_enet_mii_probe(struct net_device *dev)
continue;
if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
continue;
+ if (dev_id--)
+ continue;
strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
break;
}
@@ -737,10 +785,35 @@ static int fec_enet_mii_probe(struct net_device *dev)
static int fec_enet_mii_init(struct platform_device *pdev)
{
+ static struct mii_bus *fec0_mii_bus;
struct net_device *dev = platform_get_drvdata(pdev);
struct fec_enet_private *fep = netdev_priv(dev);
+ const struct platform_device_id *id_entry =
+ platform_get_device_id(fep->pdev);
int err = -ENXIO, i;
+ /*
+ * The dual fec interfaces are not equivalent with enet-mac.
+ * Here are the differences:
+ *
+ * - fec0 supports MII & RMII modes while fec1 only supports RMII
+ * - fec0 acts as the 1588 time master while fec1 is slave
+ * - external phys can only be configured by fec0
+ *
+ * That is to say fec1 can not work independently. It only works
+ * when fec0 is working. The reason behind this design is that the
+ * second interface is added primarily for Switch mode.
+ *
+ * Because of the last point above, both phys are attached on fec0
+ * mdio interface in board design, and need to be configured by
+ * fec0 mii_bus.
+ */
+ if ((id_entry->driver_data & FEC_QUIRK_ENET_MAC) && pdev->id) {
+ /* fec1 uses fec0 mii_bus */
+ fep->mii_bus = fec0_mii_bus;
+ return 0;
+ }
+
fep->mii_timeout = 0;
/*
@@ -777,6 +850,10 @@ static int fec_enet_mii_init(struct platform_device *pdev)
if (mdiobus_register(fep->mii_bus))
goto err_out_free_mdio_irq;
+ /* save fec0 mii_bus */
+ if (id_entry->driver_data & FEC_QUIRK_ENET_MAC)
+ fec0_mii_bus = fep->mii_bus;
+
return 0;
err_out_free_mdio_irq:
@@ -1148,12 +1225,25 @@ static void
fec_restart(struct net_device *dev, int duplex)
{
struct fec_enet_private *fep = netdev_priv(dev);
+ const struct platform_device_id *id_entry =
+ platform_get_device_id(fep->pdev);
int i;
+ u32 val, temp_mac[2];
/* Whack a reset. We should wait for this. */
writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
+ /*
+ * enet-mac reset will reset mac address registers too,
+ * so need to reconfigure it.
+ */
+ if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
+ memcpy(&temp_mac, dev->dev_addr, ETH_ALEN);
+ writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
+ writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
+ }
+
/* Clear any outstanding interrupt. */
writel(0xffc00000, fep->hwp + FEC_IEVENT);
@@ -1200,20 +1290,45 @@ fec_restart(struct net_device *dev, int duplex)
/* Set MII speed */
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
-#ifdef FEC_MIIGSK_ENR
- if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
- /* disable the gasket and wait */
- writel(0, fep->hwp + FEC_MIIGSK_ENR);
- while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
- udelay(1);
+ /*
+ * The phy interface and speed need to get configured
+ * differently on enet-mac.
+ */
+ if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) {
+ val = readl(fep->hwp + FEC_R_CNTRL);
- /* configure the gasket: RMII, 50 MHz, no loopback, no echo */
- writel(1, fep->hwp + FEC_MIIGSK_CFGR);
+ /* MII or RMII */
+ if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
+ val |= (1 << 8);
+ else
+ val &= ~(1 << 8);
- /* re-enable the gasket */
- writel(2, fep->hwp + FEC_MIIGSK_ENR);
- }
+ /* 10M or 100M */
+ if (fep->phy_dev && fep->phy_dev->speed == SPEED_100)
+ val &= ~(1 << 9);
+ else
+ val |= (1 << 9);
+
+ writel(val, fep->hwp + FEC_R_CNTRL);
+ } else {
+#ifdef FEC_MIIGSK_ENR
+ if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
+ /* disable the gasket and wait */
+ writel(0, fep->hwp + FEC_MIIGSK_ENR);
+ while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
+ udelay(1);
+
+ /*
+ * configure the gasket:
+ * RMII, 50 MHz, no loopback, no echo
+ */
+ writel(1, fep->hwp + FEC_MIIGSK_CFGR);
+
+ /* re-enable the gasket */
+ writel(2, fep->hwp + FEC_MIIGSK_ENR);
+ }
#endif
+ }
/* And last, enable the transmit and receive processing */
writel(2, fep->hwp + FEC_ECNTRL);
@@ -1410,12 +1525,13 @@ static const struct dev_pm_ops fec_pm_ops = {
static struct platform_driver fec_driver = {
.driver = {
- .name = "fec",
+ .name = DRIVER_NAME,
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &fec_pm_ops,
#endif
},
+ .id_table = fec_devtype,
.probe = fec_probe,
.remove = __devexit_p(fec_drv_remove),
};
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 2c48b25..ace318d 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -14,7 +14,8 @@
/****************************************************************************/
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
+ defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
+ defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
/*
* Just figures, Motorola would have to change the offsets for
* registers in the same peripheral device on different models
@@ -78,7 +79,7 @@
/*
* Define the buffer descriptor structure.
*/
-#ifdef CONFIG_ARCH_MXC
+#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
struct bufdesc {
unsigned short cbd_datlen; /* Data length */
unsigned short cbd_sc; /* Control and status info */
--
1.7.1
^ permalink raw reply related
* [PATCH v4 04/10] net/fec: improve pm for better suspend/resume
From: Shawn Guo @ 2011-01-06 7:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294297998-26930-1-git-send-email-shawn.guo@freescale.com>
The following commit made a fix to use fec_enet_open/fec_enet_close
over fec_enet_init/fec_stop for suspend/resume, because fec_enet_init
does not allow to have a working network interface at resume.
e3fe8558c7fc182972c3d947d88744482111f304
net/fec: fix pm to survive to suspend/resume
This fix works for i.mx/mxc fec controller, but fails on mx28 fec
which gets a different interrupt logic design. On i.mx fec, interrupt
can be triggered even bit ETHER_EN of ECR register is not set. But
on mx28 fec, ETHER_EN must be set to get interrupt work. Meanwhile,
MII interrupt is mandatory to resume the driver, because MDIO
read/write changed to interrupt mode by commit below.
97b72e4320a9aaa4a7f1592ee7d2da7e2c9bd349
fec: use interrupt for MDIO completion indication
fec_restart/fec_stop comes out as the solution working for both
cases.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
drivers/net/fec.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 47a3c7b..8a1c51f 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1372,8 +1372,10 @@ fec_suspend(struct device *dev)
if (ndev) {
fep = netdev_priv(ndev);
- if (netif_running(ndev))
- fec_enet_close(ndev);
+ if (netif_running(ndev)) {
+ fec_stop(ndev);
+ netif_device_detach(ndev);
+ }
clk_disable(fep->clk);
}
return 0;
@@ -1388,8 +1390,10 @@ fec_resume(struct device *dev)
if (ndev) {
fep = netdev_priv(ndev);
clk_enable(fep->clk);
- if (netif_running(ndev))
- fec_enet_open(ndev);
+ if (netif_running(ndev)) {
+ fec_restart(ndev, fep->full_duplex);
+ netif_device_attach(ndev);
+ }
}
return 0;
}
--
1.7.1
^ permalink raw reply related
* [PATCH v4 03/10] net/fec: add mac field into platform data and consolidate fec_get_mac
From: Shawn Guo @ 2011-01-06 7:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294297998-26930-1-git-send-email-shawn.guo@freescale.com>
Add mac field into fec_platform_data and consolidate function
fec_get_mac to get mac address in following order.
1) module parameter via kernel command line fec.macaddr=0x00,0x04,...
2) from flash in case of CONFIG_M5272 or fec_platform_data mac
field for others, which typically have mac stored in fuse
3) fec mac address registers set by bootloader
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Use module parameter than new kernel command line to pass
mac address
- Change variable name and comment to remove confusing word
"default"
- Fix copyright breakage in fec.h
drivers/net/fec.c | 81 ++++++++++++++++++++++++---------------------------
include/linux/fec.h | 3 ++
2 files changed, 41 insertions(+), 43 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 47f6b3b..47a3c7b 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -59,15 +59,11 @@
#define FEC_ALIGNMENT 0x3
#endif
-/*
- * Define the fixed address of the FEC hardware.
- */
-#if defined(CONFIG_M5272)
-
-static unsigned char fec_mac_default[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
+static unsigned char macaddr[ETH_ALEN];
+module_param_array(macaddr, byte, NULL, 0);
+MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
+#if defined(CONFIG_M5272)
/*
* Some hardware gets it MAC address out of local flash memory.
* if this is non-zero then assume it is the address to get MAC from.
@@ -537,37 +533,50 @@ rx_processing_done:
}
/* ------------------------------------------------------------------------- */
-#ifdef CONFIG_M5272
static void __inline__ fec_get_mac(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
+ struct fec_platform_data *pdata = fep->pdev->dev.platform_data;
unsigned char *iap, tmpaddr[ETH_ALEN];
- if (FEC_FLASHMAC) {
- /*
- * Get MAC address from FLASH.
- * If it is all 1's or 0's, use the default.
- */
- iap = (unsigned char *)FEC_FLASHMAC;
- if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
- (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
- iap = fec_mac_default;
- if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
- (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
- iap = fec_mac_default;
- } else {
- *((unsigned long *) &tmpaddr[0]) = readl(fep->hwp + FEC_ADDR_LOW);
- *((unsigned short *) &tmpaddr[4]) = (readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
+ /*
+ * try to get mac address in following order:
+ *
+ * 1) module parameter via kernel command line in form
+ * fec.macaddr=0x00,0x04,0x9f,0x01,0x30,0xe0
+ */
+ iap = macaddr;
+
+ /*
+ * 2) from flash or fuse (via platform data)
+ */
+ if (!is_valid_ether_addr(iap)) {
+#ifdef CONFIG_M5272
+ if (FEC_FLASHMAC)
+ iap = (unsigned char *)FEC_FLASHMAC;
+#else
+ if (pdata)
+ memcpy(iap, pdata->mac, ETH_ALEN);
+#endif
+ }
+
+ /*
+ * 3) FEC mac registers set by bootloader
+ */
+ if (!is_valid_ether_addr(iap)) {
+ *((unsigned long *) &tmpaddr[0]) =
+ be32_to_cpu(readl(fep->hwp + FEC_ADDR_LOW));
+ *((unsigned short *) &tmpaddr[4]) =
+ be16_to_cpu(readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
iap = &tmpaddr[0];
}
memcpy(dev->dev_addr, iap, ETH_ALEN);
- /* Adjust MAC if using default MAC address */
- if (iap == fec_mac_default)
- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->pdev->id;
+ /* Adjust MAC if using macaddr */
+ if (iap == macaddr)
+ dev->dev_addr[ETH_ALEN-1] = macaddr[ETH_ALEN-1] + fep->pdev->id;
}
-#endif
/* ------------------------------------------------------------------------- */
@@ -1087,22 +1096,8 @@ static int fec_enet_init(struct net_device *dev)
fep->hwp = (void __iomem *)dev->base_addr;
fep->netdev = dev;
- /* Set the Ethernet address */
-#ifdef CONFIG_M5272
+ /* Get the Ethernet address */
fec_get_mac(dev);
-#else
- {
- unsigned long l;
- l = readl(fep->hwp + FEC_ADDR_LOW);
- dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
- dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
- dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
- dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
- l = readl(fep->hwp + FEC_ADDR_HIGH);
- dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
- dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
- }
-#endif
/* Set receive and transmit descriptor base. */
fep->rx_bd_base = cbd_base;
diff --git a/include/linux/fec.h b/include/linux/fec.h
index 5d3523d..bcff455 100644
--- a/include/linux/fec.h
+++ b/include/linux/fec.h
@@ -3,6 +3,8 @@
* Copyright (c) 2009 Orex Computed Radiography
* Baruch Siach <baruch@tkos.co.il>
*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
* Header file for the FEC platform data
*
* This program is free software; you can redistribute it and/or modify
@@ -16,6 +18,7 @@
struct fec_platform_data {
phy_interface_t phy;
+ unsigned char mac[ETH_ALEN];
};
#endif
--
1.7.1
^ permalink raw reply related
* [PATCH v4 02/10] net/fec: remove the use of "index" which is legacy
From: Shawn Guo @ 2011-01-06 7:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294297998-26930-1-git-send-email-shawn.guo@freescale.com>
The "index" becomes legacy since fep->pdev->id starts working
to identify the instance.
Moreover, the call of fec_enet_init(ndev, 0) always passes 0
to fep->index. This makes the following code in fec_get_mac buggy.
/* Adjust MAC if using default MAC address */
if (iap == fec_mac_default)
dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
It may be the time to remove "index" and use fep->pdev->id instead.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
drivers/net/fec.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 52e9ca8..47f6b3b 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -186,7 +186,6 @@ struct fec_enet_private {
int mii_timeout;
uint phy_speed;
phy_interface_t phy_interface;
- int index;
int link;
int full_duplex;
struct completion mdio_done;
@@ -566,7 +565,7 @@ static void __inline__ fec_get_mac(struct net_device *dev)
/* Adjust MAC if using default MAC address */
if (iap == fec_mac_default)
- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
+ dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->pdev->id;
}
#endif
@@ -1067,9 +1066,8 @@ static const struct net_device_ops fec_netdev_ops = {
/*
* XXX: We need to clean up on failure exits here.
*
- * index is only used in legacy code
*/
-static int fec_enet_init(struct net_device *dev, int index)
+static int fec_enet_init(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
struct bufdesc *cbd_base;
@@ -1086,7 +1084,6 @@ static int fec_enet_init(struct net_device *dev, int index)
spin_lock_init(&fep->hw_lock);
- fep->index = index;
fep->hwp = (void __iomem *)dev->base_addr;
fep->netdev = dev;
@@ -1316,7 +1313,7 @@ fec_probe(struct platform_device *pdev)
}
clk_enable(fep->clk);
- ret = fec_enet_init(ndev, 0);
+ ret = fec_enet_init(ndev);
if (ret)
goto failed_init;
--
1.7.1
^ permalink raw reply related
* [PATCH v4 01/10] net/fec: fix MMFR_OP type in fec_enet_mdio_write
From: Shawn Guo @ 2011-01-06 7:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294297998-26930-1-git-send-email-shawn.guo@freescale.com>
FEC_MMFR_OP_WRITE should be used than FEC_MMFR_OP_READ in
a mdio write operation.
It's probably a typo introduced by commit:
e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
netdev/fec.c: add phylib supporting to enable carrier detection (v2)
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
drivers/net/fec.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index cce32d4..52e9ca8 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -651,8 +651,8 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
fep->mii_timeout = 0;
init_completion(&fep->mdio_done);
- /* start a read op */
- writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
+ /* start a write op */
+ writel(FEC_MMFR_ST | FEC_MMFR_OP_WRITE |
FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(regnum) |
FEC_MMFR_TA | FEC_MMFR_DATA(value),
fep->hwp + FEC_MII_DATA);
--
1.7.1
^ permalink raw reply related
* [PATCH v4 00/10] net/fec: add dual fec support for i.MX28
From: Shawn Guo @ 2011-01-06 7:13 UTC (permalink / raw)
To: linux-arm-kernel
This patch series is to add dual fec support for mx28, which is
a mxs-based soc. Some code changes related to the following commits
are also made in this patch set for some reasons.
e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
netdev/fec.c: add phylib supporting to enable carrier detection (v2)
e3fe8558c7fc182972c3d947d88744482111f304
net/fec: fix pm to survive to suspend/resume
It's been tested on mx28 evk and mx51 babbage. For mx28, it has
to work against the tree
git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-2.6.38
plus patch
[PATCH v4] ARM: mxs: Change duart device to use amba-pl011
The 3 patches below preceding with * have changes since v3, and
the detailed change log can be found in individual patch.
[PATCH v4 01/10] net/fec: fix MMFR_OP type in fec_enet_mdio_write
[PATCH v4 02/10] net/fec: remove the use of "index" which is legacy
[PATCH v4 03/10] net/fec: add mac field into platform data and consolidate fec_get_mac
[PATCH v4 04/10] net/fec: improve pm for better suspend/resume
*[PATCH v4 05/10] net/fec: add dual fec support for mx28
*[PATCH v4 06/10] ARM: mx28: update clock and device name for dual fec support
[PATCH v4 07/10] ARM: mx28: add the second fec device registration
*[PATCH v4 08/10] ARM: mxs: add ocotp read function
[PATCH v4 09/10] ARM: mx28: read fec mac address from ocotp
[PATCH v4 10/10] ARM: mxs: add initial pm support
Thanks for the review.
Regards,
Shawn
^ permalink raw reply
* [PATCH v3 05/10] net/fec: add dual fec support for mx28
From: Uwe Kleine-König @ 2011-01-06 7:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110106041457.GC17891@freescale.com>
Hello Shawn,
On Thu, Jan 06, 2011 at 12:14:59PM +0800, Shawn Guo wrote:
> On Wed, Jan 05, 2011 at 05:34:49PM +0100, Uwe Kleine-K?nig wrote:
> > On Wed, Jan 05, 2011 at 10:07:32PM +0800, Shawn Guo wrote:
> > > +#define DRIVER_NAME "fec"
> > > +#define ENET_MAC_NAME "enet-mac"
> > > +
> > > +static struct platform_device_id fec_devtype[] = {
> > > + {
> > > + .name = DRIVER_NAME,
> > > + }, {
> > > + .name = ENET_MAC_NAME,
> > > + }
> > I'd done it differently:
> >
> > {
> > .name = "fec",
> > .driver_data = 0,
> > }, {
> > .name = "imx28-fec",
> > .driver_data = HAS_ENET_MAC | ...,
> > }
> >
> > and then test the bits in driver_data (which you get using
> > platform_get_device_id() when you need to distinguish.
> > Comparing names doesn't scale, assume there are three further features
> > to distinguish, then you need to use strtok or index and get device
> > names like enet-mac-with-feature1-but-without-feature2-and-feature3.
> >
> Makes sense. The frame endian issue will be fixed in future revision,
> so I would define bit SWAP_FRAME for testing.
sounds sane
> > > + /*
> > > + * enet-mac design made an improper assumption that it's running
> > > + * on a big endian system. As the result, driver has to swap
> > if he was really aware that he limits the performant use of the fec to
> > big endian systems, can you please make him stop designing hardware!?
> >
> You over looked my power :) BTW, he had left Freescale.
so everything seems OK with your power :-)
> > > + * every frame going to and coming from the controller.
> > > + */
> > > + if (fec_is_enetmac)
> > > + swap_buffer(bufaddr, skb->len);
> > > +
> > > /* Save skb pointer */
> > > fep->tx_skbuff[fep->skb_cur] = skb;
> > >
> > > @@ -487,6 +522,9 @@ fec_enet_rx(struct net_device *dev)
> > > dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
> > > DMA_FROM_DEVICE);
> > >
> > > + if (fec_is_enetmac)
> > > + swap_buffer(data, pkt_len);
> > > +
> > > /* This does 16 byte alignment, exactly what we need.
> > > * The packet length includes FCS, but we don't want to
> > > * include that when passing upstream as it messes up
> > > @@ -689,6 +727,7 @@ static int fec_enet_mii_probe(struct net_device *dev)
> > > char mdio_bus_id[MII_BUS_ID_SIZE];
> > > char phy_name[MII_BUS_ID_SIZE + 3];
> > > int phy_id;
> > > + int dev_id = fep->pdev->id;
> > >
> > > fep->phy_dev = NULL;
> > >
> > > @@ -700,6 +739,8 @@ static int fec_enet_mii_probe(struct net_device *dev)
> > > continue;
> > > if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
> > > continue;
> > > + if (fec_is_enetmac && dev_id--)
> > > + continue;
> > > strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
> > > break;
> > > }
> > > @@ -741,6 +782,28 @@ static int fec_enet_mii_init(struct platform_device *pdev)
> > > struct fec_enet_private *fep = netdev_priv(dev);
> > > int err = -ENXIO, i;
> > >
> > > + /*
> > > + * The dual fec interfaces are not equivalent with enet-mac.
> > > + * Here are the differences:
> > > + *
> > > + * - fec0 supports MII & RMII modes while fec1 only supports RMII
> > > + * - fec0 acts as the 1588 time master while fec1 is slave
> > > + * - external phys can only be configured by fec0
> > > + *
> > > + * That is to say fec1 can not work independently. It only works
> > > + * when fec0 is working. The reason behind this design is that the
> > > + * second interface is added primarily for Switch mode.
> > > + *
> > > + * Because of the last point above, both phys are attached on fec0
> > > + * mdio interface in board design, and need to be configured by
> > > + * fec0 mii_bus.
> > > + */
> > > + if (fec_is_enetmac && pdev->id) {
> > > + /* fec1 uses fec0 mii_bus */
> > > + fep->mii_bus = fec_mii_bus;
> > > + return 0;
> > > + }
> > > +
> > > fep->mii_timeout = 0;
> > >
> > > /*
> > > @@ -777,6 +840,10 @@ static int fec_enet_mii_init(struct platform_device *pdev)
> > > if (mdiobus_register(fep->mii_bus))
> > > goto err_out_free_mdio_irq;
> > >
> > > + /* save fec0 mii_bus */
> > > + if (fec_is_enetmac)
> > > + fec_mii_bus = fep->mii_bus;
> > > +
> > > return 0;
> > >
> > > err_out_free_mdio_irq:
> > > @@ -1149,11 +1216,22 @@ fec_restart(struct net_device *dev, int duplex)
> > > {
> > > struct fec_enet_private *fep = netdev_priv(dev);
> > > int i;
> > > + u32 val, temp_mac[2];
> > >
> > > /* Whack a reset. We should wait for this. */
> > > writel(1, fep->hwp + FEC_ECNTRL);
> > > udelay(10);
> > >
> > > + /*
> > > + * enet-mac reset will reset mac address registers too,
> > > + * so need to reconfigure it.
> > > + */
> > > + if (fec_is_enetmac) {
> > > + memcpy(&temp_mac, dev->dev_addr, ETH_ALEN);
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > + writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
> > > + writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
> > where is the value saved to temp_mac[]? For me it looks you write
> > uninitialized data into the mac registers.
>
> memcpy above.
oops. right. I looked for something like
temp_mac[0] = dev->dev_addr[0] << $shiftfor0 | ...
which AFAIK is what you want here. memcpy is sensible to (at least)
endian issues. If you ask me factor out the setting of the mac address
in probe to a function and use that here, too.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH v4 5/8] arm: mxc: move IOMUX_CONFIG_XXXX definitions to iomux-v3.h
From: Richard Zhao @ 2011-01-06 6:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1293708306-20170-5-git-send-email-richard.zhao@freescale.com>
Hello Sascha,
On Thu, Dec 30, 2010 at 07:25:04PM +0800, Richard Zhao wrote:
> IOMUX_CONFIG_GPIO is not for iomux-v3. It's for old freescale
> iomux routines. Remove it.
>
> Signed-off-by: Richard Zhao <richard.zhao@freescale.com>
> Acked-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
If you don't have comments, could you please merge this patch?
It's causing arch/arm/plat-mxc/include/mach/iomux-mx50.h incomplete.
Thanks
Richard
> ---
> arch/arm/plat-mxc/include/mach/iomux-mx51.h | 16 ----------------
> arch/arm/plat-mxc/include/mach/iomux-mx53.h | 16 ----------------
> arch/arm/plat-mxc/include/mach/iomux-v3.h | 15 +++++++++++++++
> 3 files changed, 15 insertions(+), 32 deletions(-)
>
> diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
> index e1600f3..31af1f5 100644
> --- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h
> +++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
> @@ -15,22 +15,6 @@
>
> #include <mach/iomux-v3.h>
>
> -/*
> - * various IOMUX alternate output functions (1-7)
> - */
> -typedef enum iomux_config {
> - IOMUX_CONFIG_ALT0,
> - IOMUX_CONFIG_ALT1,
> - IOMUX_CONFIG_ALT2,
> - IOMUX_CONFIG_ALT3,
> - IOMUX_CONFIG_ALT4,
> - IOMUX_CONFIG_ALT5,
> - IOMUX_CONFIG_ALT6,
> - IOMUX_CONFIG_ALT7,
> - IOMUX_CONFIG_GPIO, /* added to help user use GPIO mode */
> - IOMUX_CONFIG_SION = 0x1 << 4, /* LOOPBACK:MUX SION bit */
> -} iomux_pin_cfg_t;
> -
> /* Pad control groupings */
> #define MX51_UART1_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
> PAD_CTL_DSE_HIGH)
> diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx53.h b/arch/arm/plat-mxc/include/mach/iomux-mx53.h
> index 80cb3c5..4155124 100644
> --- a/arch/arm/plat-mxc/include/mach/iomux-mx53.h
> +++ b/arch/arm/plat-mxc/include/mach/iomux-mx53.h
> @@ -21,22 +21,6 @@
>
> #include <mach/iomux-v3.h>
>
> -/*
> - * various IOMUX alternate output functions (1-7)
> - */
> -typedef enum iomux_config {
> - IOMUX_CONFIG_ALT0,
> - IOMUX_CONFIG_ALT1,
> - IOMUX_CONFIG_ALT2,
> - IOMUX_CONFIG_ALT3,
> - IOMUX_CONFIG_ALT4,
> - IOMUX_CONFIG_ALT5,
> - IOMUX_CONFIG_ALT6,
> - IOMUX_CONFIG_ALT7,
> - IOMUX_CONFIG_GPIO, /* added to help user use GPIO mode */
> - IOMUX_CONFIG_SION = 0x1 << 4, /* LOOPBACK:MUX SION bit */
> -} iomux_pin_cfg_t;
> -
> /* These 2 defines are for pins that may not have a mux register, but could
> * have a pad setting register, and vice-versa. */
> #define NON_MUX_I 0x00
> diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h
> index 811716f..e1fd71b 100644
> --- a/arch/arm/plat-mxc/include/mach/iomux-v3.h
> +++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h
> @@ -54,6 +54,21 @@ typedef struct deprecated_pad_desc {
> unsigned select_input:3;
> } iomux_v3_cfg_t;
>
> +/*
> + * various IOMUX alternate output functions (1-7)
> + */
> +enum iomux_config {
> + IOMUX_CONFIG_ALT0,
> + IOMUX_CONFIG_ALT1,
> + IOMUX_CONFIG_ALT2,
> + IOMUX_CONFIG_ALT3,
> + IOMUX_CONFIG_ALT4,
> + IOMUX_CONFIG_ALT5,
> + IOMUX_CONFIG_ALT6,
> + IOMUX_CONFIG_ALT7,
> + IOMUX_CONFIG_SION = 0x1 << 4, /* LOOPBACK:MUX SION bit */
> +};
> +
> static inline unsigned int MUX_CTRL_OFS(iomux_v3_cfg_t *pad)
> {
> return pad->mux_ctrl_ofs;
> --
> 1.6.3.3
>
^ permalink raw reply
* [PATCH v3] video: imxfb: Fix the maximum value for yres
From: Paul Mundt @ 2011-01-06 6:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1293193704-2855-1-git-send-email-fabio.estevam@freescale.com>
On Fri, Dec 24, 2010 at 10:28:24AM -0200, Fabio Estevam wrote:
> MX27 and MX25 have 10 bits in the YMAX field of LCDC Size Register.
>
> Fix the maximum value for yres.
>
> Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Applied, thanks.
^ permalink raw reply
* [PATCH v2 0/3] add CNS3xxx AHCI support
From: Lin Mac @ 2011-01-06 6:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <4D24B53C.4020009@pobox.com>
2011/1/6 Jeff Garzik <jgarzik@pobox.com>:
> On 01/05/2011 12:43 AM, mkl0301 at gmail.com wrote:
>>
>> From: Mac Lin<mkl0301@gmail.com>
>>
>> v2:
>> ?- Switch ahci_platform to module device table matching to add SoC
>> specific support
>>
>> v1: http://www.spinics.net/lists/arm-kernel/msg106236.html
>> ?- Add CNS3xxx SoC specific AHCI support
>>
>> This patchset is based on linux-2.6.37-rc2
>>
>> Mac Lin (3):
>> ? ? ? ahci_platform: rename to ahci_pltfm, but keep the original module
>> name
>> ? ? ? ahci_pltfm: switch to module device table matching
>> ? ? ? ahci_platform: add support for CNS3xxx SoC devices
>>
>> ?arch/arm/mach-cns3xxx/devices.c | ? ?2 +-
>> ?drivers/ata/Kconfig ? ? ? ? ? ? | ? 11 ++
>> ?drivers/ata/Makefile ? ? ? ? ? ?| ? ?5 +-
>> ?drivers/ata/ahci_cns3xxx.c ? ? ?| ? 62 +++++++++++
>> ?drivers/ata/ahci_platform.c ? ? | ?197
>> ------------------------------------
>> ?drivers/ata/ahci_pltfm.c ? ? ? ?| ?212
>> +++++++++++++++++++++++++++++++++++++++
>> ?drivers/ata/ahci_pltfm.h ? ? ? ?| ? 19 ++++
>> ?7 files changed, 309 insertions(+), 199 deletions(-)
>> ?create mode 100644 drivers/ata/ahci_cns3xxx.c
>> ?delete mode 100644 drivers/ata/ahci_platform.c
>> ?create mode 100644 drivers/ata/ahci_pltfm.c
>> ?create mode 100644 drivers/ata/ahci_pltfm.h
>
> It is overkill to rename the entirety of ahci_platform just for one override
> function.
> This sort of thing I would have expected to be added directly to
> ahci_platform.c.
It might be overkill for only one controller. but it is more clean and
readable to have different SoC specific changes in separate files,
especially when more SoCs need to make similar changes.
I will add them directly to ahci_platform.c if you insist.
Best Regards,
Mac Lin
^ 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