Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] ARM: OMAP2+: move mailbox.h out of plat-omap headers
From: Omar Ramirez Luna @ 2012-10-30 12:18 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121029175228.GD11908@atomide.com>

Tony,

On 29 October 2012 12:52, Tony Lindgren <tony@atomide.com> wrote:
>> --- /dev/null
>> +++ b/include/linux/platform_data/omap_mailbox.h
>> @@ -0,0 +1,105 @@
>
> This file should only contain pure platform data needed
> by the core omap code to pass to the mailbox driver.

Ok, looking at it closely, this header file is related to the API
itself, there is nothing that could be actually considered as pure
platform data, the structures are related with the mailbox framework
and even if I split this file into two, the additional header would
end up including the "platform_data" header unless I move
save/restore_ctx functions and then export them as symbols for the
API.

So, it might be better for the entire file to sit in
linux/include/mailbox/ then.

> The mailbox API header should be somewhere else,
> like include/linux/mailbox/mailbox-omap.h or similar.

Ok.

> But shouldn't this all now be handled by using the
> remoteproc framework?

Remoteproc doesn't handle the mailbox hardware directly, it still
relies in the mailbox framework for the low level communications.
E.g.: Proc1 has a message (virtqueue msg) queued to Proc2, uses
mailbox msg to generate an interrupt to Proc2, Proc2 queries the
message (virtqueue) based on the mailbox message received.

Regards,

Omar

^ permalink raw reply

* OMAP baseline test results for v3.7-rc1
From: Paul Walmsley @ 2012-10-30 12:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121029200032.GD30152@arwen.pp.htv.fi>

On Mon, 29 Oct 2012, Felipe Balbi wrote:

> that's too bad :-(
> 
> Can you compile with:
> 
> CONFIG_I2C_DEBUG_CORE=y
> CONFIG_I2C_DEBUG_ALGO=y
> CONFIG_I2C_DEBUG_BUS=y
> CONFIG_DEFAULT_MESSAGE_LOGLEVEL=9
> 
> so that I can see all transfers ?

Log is below.

- Paul


U-Boot 2011.06-dirty (Sep 04 2012 - 17:06:58)

OMAP3530-GP ES3.0, CPU-OPP2, L3-165MHz, Max CPU Clock 600 mHz
OMAP3 Beagle board + LPDDR/NAND
I2C:   ready
DRAM:  256 MiB
NAND:  256 MiB
MMC:   OMAP SD/MMC: 0
In:    serial
Out:   serial
Err:   serial
Beagle Rev C1/C2/C3
timed out in wait_for_pin: I2C_STAT=0
I2C read: I/O error
Unrecognized expansion board: 0
Die ID #5cf200030000000004013f7902012010
Hit any key to stop autoboot:  2 \b\b\b 0 
OMAP3 beagleboard.org # 
OMAP3 beagleboard.org # 
OMAP3 beagleboard.org # setenv bootargs console=ttyO2,230400n8 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait
OMAP3 beagleboard.org # setenv bootargs console=ttyO2,230400n8 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait debug ignore_loglevel
OMAP3 beagleboard.org # loady
## Ready for binary (ymodem) download to 0x80200000 at 230400 bps...
CModem - CRC mode, 32426(SOH)/0(STX)/0(CAN) packets, 5 retries
## Total Size      = 0x003f53f0 = 4150256 Bytes
OMAP3 beagleboard.org # bootm
## Booting kernel from Legacy Image at 80200000 ...
   Image Name:   Linux-3.7.0-rc3
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    4150192 Bytes = 4 MiB
   Load Address: 80008000
   Entry Point:  80008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0
[    0.000000] Linux version 3.7.0-rc3 (paul at dusk) (gcc version 4.5.1 (Sourcery G++ Lite 2010.09-50) ) #703 SMP Tue Oct 30 05:56:54 MDT 2012
[    0.000000] CPU: ARMv7 Processor [411fc083] revision 3 (ARMv7), cr=10c53c7d
[    0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
[    0.000000] Machine: OMAP3 Beagle Board
[    0.000000] debug: ignoring loglevel setting.
[    0.000000] Memory policy: ECC disabled, Data cache writeback
[    0.000000] On node 0 totalpages: 65280
[    0.000000] free_area_init_node: node 0, pgdat c07de400, node_mem_map c0d3c000
[    0.000000]   Normal zone: 512 pages used for memmap
[    0.000000]   Normal zone: 0 pages reserved
[    0.000000]   Normal zone: 64768 pages, LIFO batch:15
[    0.000000] OMAP3430/3530 ES3.0 (l2cache iva sgx neon isp )
[    0.000000] Clocking rate (Crystal/Core/MPU): 26.0/332/500 MHz
[    0.000000] PERCPU: Embedded 9 pages/cpu @c0f42000 s12928 r8192 d15744 u36864
[    0.000000] pcpu-alloc: s12928 r8192 d15744 u36864 alloc=9*4096
[    0.000000] pcpu-alloc: [0] 0 
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 64768
[    0.000000] Kernel command line: console=ttyO2,230400n8 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait debug ignore_loglevel
[    0.000000] PID hash table entries: 1024 (order: 0, 4096 bytes)
[    0.000000] Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
[    0.000000] Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.000000] Memory: 255MB = 255MB total
[    0.000000] Memory: 245256k/245256k available, 16888k reserved, 0K highmem
[    0.000000] Virtual kernel memory layout:
[    0.000000]     vector  : 0xffff0000 - 0xffff1000   (   4 kB)
[    0.000000]     fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
[    0.000000]     vmalloc : 0xd0800000 - 0xff000000   ( 744 MB)
[    0.000000]     lowmem  : 0xc0000000 - 0xd0000000   ( 256 MB)
[    0.000000]     pkmap   : 0xbfe00000 - 0xc0000000   (   2 MB)
[    0.000000]     modules : 0xbf000000 - 0xbfe00000   (  14 MB)
[    0.000000]       .text : 0xc0008000 - 0xc07047fc   (7154 kB)
[    0.000000]       .init : 0xc0705000 - 0xc0755280   ( 321 kB)
[    0.000000]       .data : 0xc0756000 - 0xc07e15e0   ( 558 kB)
[    0.000000]        .bss : 0xc07e1604 - 0xc0d3bfac   (5483 kB)
[    0.000000] Hierarchical RCU implementation.
[    0.000000] 	RCU restricting CPUs from NR_CPUS=2 to nr_cpu_ids=1.
[    0.000000] NR_IRQS:16 nr_irqs:16 16
[    0.000000] IRQ: Found an INTC at 0xfa200000 (revision 4.0) with 96 interrupts
[    0.000000] Total of 96 interrupts on 1 active controller
[    0.000000] OMAP clockevent source: GPTIMER12 at 32768 Hz
[    0.000000] sched_clock: 32 bits at 32kHz, resolution 30517ns, wraps every 131071999ms
[    0.000000] OMAP clocksource: 32k_counter at 32768 Hz
[    0.000000] Console: colour dummy device 80x30
[    0.000000] Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar
[    0.000000] ... MAX_LOCKDEP_SUBCLASSES:  8
[    0.000000] ... MAX_LOCK_DEPTH:          48
[    0.000000] ... MAX_LOCKDEP_KEYS:        8191
[    0.000000] ... CLASSHASH_SIZE:          4096
[    0.000000] ... MAX_LOCKDEP_ENTRIES:     16384
[    0.000000] ... MAX_LOCKDEP_CHAINS:      32768
[    0.000000] ... CHAINHASH_SIZE:          16384
[    0.000000]  memory used by lock dependency info: 3695 kB
[    0.000000]  per task-struct memory footprint: 1152 bytes
[    0.001220] Calibrating delay loop... 313.50 BogoMIPS (lpj=1222656)
[    0.103363] pid_max: default: 32768 minimum: 301
[    0.104187] Security Framework initialized
[    0.104431] Mount-cache hash table entries: 512
[    0.110626] CPU: Testing write buffer coherency: ok
[    0.111907] CPU0: thread -1, cpu 0, socket -1, mpidr 0
[    0.112030] Setting up static identity map for 0x8051f158 - 0x8051f1c8
[    0.115997] Brought up 1 CPUs
[    0.116027] SMP: Total of 1 processors activated (313.50 BogoMIPS).
[    0.132202] ttyO2 used as console in debug mode: uart2 clocks will not be gated
[    0.139984] pinctrl core: initialized pinctrl subsystem
[    0.148834] regulator-dummy: no parameters
[    0.151702] NET: Registered protocol family 16
[    0.153503] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.156249] omap-gpmc omap-gpmc: GPMC revision 5.0
[    0.173187] gpiochip_add: registered GPIOs 0 to 31 on device: gpio
[    0.173919] OMAP GPIO hardware version 2.5
[    0.177062] gpiochip_add: registered GPIOs 32 to 63 on device: gpio
[    0.180633] gpiochip_add: registered GPIOs 64 to 95 on device: gpio
[    0.183898] gpiochip_add: registered GPIOs 96 to 127 on device: gpio
[    0.187469] gpiochip_add: registered GPIOs 128 to 159 on device: gpio
[    0.190551] gpiochip_add: registered GPIOs 160 to 191 on device: gpio
[    0.198242] i2c-core: driver [dummy] registered
[    0.200683] omap_mux_init: Add partition: #1: core, flags: 0
[    0.204437] OMAP3 Beagle Rev: C1/C2/C3
[    0.235412] Reprogramming SDRC clock to 332000000 Hz
[    0.236755] Found NAND on CS0
[    0.236785] Registering NAND on CS0
[    0.238677] hw-breakpoint: debug architecture 0x4 unsupported.
[    0.260498]  omap-mcbsp.2: alias fck already exists
[    0.261749]  omap-mcbsp.3: alias fck already exists
[    0.267395] OMAP DMA hardware revision 4.0
[    0.273742]  arm-pmu: alias fck already exists
[    0.372436] bio: create slab <bio-0> at 0
[    0.507171] omap-dma-engine omap-dma-engine: OMAP DMA engine driver
[    0.508972] i2c-core: driver [tps65023] registered
[    0.512786] i2c-core: driver [twl] registered
[    0.515808] SCSI subsystem initialized
[    0.520202] usbcore: registered new interface driver usbfs
[    0.521118] usbcore: registered new interface driver hub
[    0.522094] usbcore: registered new device driver usb
[    0.537139] i2c i2c-1: adapter [OMAP I2C adapter] registered
[    0.537994] i2c 1-0048: uevent
[    0.539367] twl 1-0048: probe
[    0.541015] i2c 1-0049: uevent
[    0.542419] dummy 1-0049: probe
[    0.542510] i2c i2c-1: client [dummy] registered with bus id 1-0049
[    0.542907] i2c 1-004a: uevent
[    0.543670] dummy 1-004a: probe
[    0.543731] i2c i2c-1: client [dummy] registered with bus id 1-004a
[    0.544158] i2c 1-004b: uevent
[    0.544830] dummy 1-004b: probe
[    0.544921] i2c i2c-1: client [dummy] registered with bus id 1-004b
[    0.545227] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    0.545623] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    0.546142] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.546203] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.546478] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    0.546539] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    0.546630] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.546752] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.546844] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    0.546905] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    0.546997] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.547119] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.547210] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    0.547271] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    0.547363] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.547454] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.547576] i2c i2c-1: master_xfer[0] W, addr=0x49, len=2
[    0.547607] omap_i2c omap_i2c.1: addr: 0x0049, len: 2, flags: 0x0, stop: 1
[    0.547698] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.547760] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.547851] i2c i2c-1: master_xfer[0] W, addr=0x49, len=1
[    0.547882] i2c i2c-1: master_xfer[1] R, addr=0x49, len=4
[    0.547943] omap_i2c omap_i2c.1: addr: 0x0049, len: 1, flags: 0x0, stop: 0
[    0.548034] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.548095] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.548187] omap_i2c omap_i2c.1: addr: 0x0049, len: 4, flags: 0x1, stop: 1
[    0.548278] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.548309] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.548400] i2c i2c-1: master_xfer[0] W, addr=0x49, len=2
[    0.548461] omap_i2c omap_i2c.1: addr: 0x0049, len: 2, flags: 0x0, stop: 1
[    0.548553] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.548614] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.549774] i2c i2c-1: master_xfer[0] W, addr=0x49, len=4
[    0.549804] omap_i2c omap_i2c.1: addr: 0x0049, len: 4, flags: 0x0, stop: 1
[    0.549926] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.549987] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.550170] i2c i2c-1: master_xfer[0] W, addr=0x49, len=2
[    0.550201] omap_i2c omap_i2c.1: addr: 0x0049, len: 2, flags: 0x0, stop: 1
[    0.550323] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.550384] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.550476] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=2
[    0.550537] omap_i2c omap_i2c.1: addr: 0x004a, len: 2, flags: 0x0, stop: 1
[    0.550628] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.550689] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.550781] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=2
[    0.550811] omap_i2c omap_i2c.1: addr: 0x004a, len: 2, flags: 0x0, stop: 1
[    0.550903] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.550964] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.551086] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=3
[    0.551116] omap_i2c omap_i2c.1: addr: 0x004a, len: 3, flags: 0x0, stop: 1
[    0.551208] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.551300] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.551391] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=2
[    0.551422] omap_i2c omap_i2c.1: addr: 0x004a, len: 2, flags: 0x0, stop: 1
[    0.551513] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.551574] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.551696] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=2
[    0.551727] omap_i2c omap_i2c.1: addr: 0x004a, len: 2, flags: 0x0, stop: 1
[    0.551818] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.551879] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.552001] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    0.552032] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    0.552124] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.552246] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.552337] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    0.552398] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    0.552459] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.552581] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.552673] i2c i2c-1: master_xfer[0] W, addr=0x49, len=1
[    0.552703] i2c i2c-1: master_xfer[1] R, addr=0x49, len=3
[    0.552764] omap_i2c omap_i2c.1: addr: 0x0049, len: 1, flags: 0x0, stop: 0
[    0.552856] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.552917] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.553009] omap_i2c omap_i2c.1: addr: 0x0049, len: 3, flags: 0x1, stop: 1
[    0.553100] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.553131] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.553222] i2c i2c-1: master_xfer[0] W, addr=0x49, len=1
[    0.553253] i2c i2c-1: master_xfer[1] R, addr=0x49, len=3
[    0.553314] omap_i2c omap_i2c.1: addr: 0x0049, len: 1, flags: 0x0, stop: 0
[    0.553405] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.553466] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.553527] omap_i2c omap_i2c.1: addr: 0x0049, len: 3, flags: 0x1, stop: 1
[    0.553649] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.553680] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.553771] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=1
[    0.553802] i2c i2c-1: master_xfer[1] R, addr=0x4a, len=1
[    0.553833] omap_i2c omap_i2c.1: addr: 0x004a, len: 1, flags: 0x0, stop: 0
[    0.553924] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.553985] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.554077] omap_i2c omap_i2c.1: addr: 0x004a, len: 1, flags: 0x1, stop: 1
[    0.554168] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.554199] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.554290] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=1
[    0.554321] i2c i2c-1: master_xfer[1] R, addr=0x4a, len=1
[    0.554382] omap_i2c omap_i2c.1: addr: 0x004a, len: 1, flags: 0x0, stop: 0
[    0.554473] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.554534] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.554595] omap_i2c omap_i2c.1: addr: 0x004a, len: 1, flags: 0x1, stop: 1
[    0.554687] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.554718] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.554840] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=1
[    0.554840] i2c i2c-1: master_xfer[1] R, addr=0x4a, len=2
[    0.554901] omap_i2c omap_i2c.1: addr: 0x004a, len: 1, flags: 0x0, stop: 0
[    0.554992] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.555053] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.555145] omap_i2c omap_i2c.1: addr: 0x004a, len: 2, flags: 0x1, stop: 1
[    0.555236] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.555267] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.555358] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=1
[    0.555389] i2c i2c-1: master_xfer[1] R, addr=0x4a, len=2
[    0.555419] omap_i2c omap_i2c.1: addr: 0x004a, len: 1, flags: 0x0, stop: 0
[    0.555511] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.555572] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.555664] omap_i2c omap_i2c.1: addr: 0x004a, len: 2, flags: 0x1, stop: 1
[    0.555786] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.555786] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.555908] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=1
[    0.555938] i2c i2c-1: master_xfer[1] R, addr=0x4a, len=1
[    0.555969] omap_i2c omap_i2c.1: addr: 0x004a, len: 1, flags: 0x0, stop: 0
[    0.556060] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.556121] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.556213] omap_i2c omap_i2c.1: addr: 0x004a, len: 1, flags: 0x1, stop: 1
[    0.556732] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.556762] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.556945] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=2
[    0.556976] omap_i2c omap_i2c.1: addr: 0x004a, len: 2, flags: 0x0, stop: 1
[    0.557098] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.557159] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.557250] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=1
[    0.557281] i2c i2c-1: master_xfer[1] R, addr=0x4a, len=1
[    0.557312] omap_i2c omap_i2c.1: addr: 0x004a, len: 1, flags: 0x0, stop: 0
[    0.557403] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.557464] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.557556] omap_i2c omap_i2c.1: addr: 0x004a, len: 1, flags: 0x1, stop: 1
[    0.557647] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.557678] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.557769] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=2
[    0.557830] omap_i2c omap_i2c.1: addr: 0x004a, len: 2, flags: 0x0, stop: 1
[    0.557922] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.557983] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.558074] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    0.558105] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    0.558166] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    0.558258] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.558288] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.558380] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    0.558471] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.558502] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.558593] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    0.558624] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    0.558685] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    0.558776] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.558837] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.558898] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    0.558990] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.559020] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.559295] twl 1-0048: PIH (irq 23) chaining IRQs 338..346
[    0.560180] twl 1-0048: power (irq 343) chaining IRQs 346..353
[    0.560699] i2c i2c-1: master_xfer[0] W, addr=0x49, len=1
[    0.560729] i2c i2c-1: master_xfer[1] R, addr=0x49, len=1
[    0.560760] omap_i2c omap_i2c.1: addr: 0x0049, len: 1, flags: 0x0, stop: 0
[    0.560882] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.560943] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.561035] omap_i2c omap_i2c.1: addr: 0x0049, len: 1, flags: 0x1, stop: 1
[    0.561126] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.561157] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.561279] i2c i2c-1: master_xfer[0] W, addr=0x49, len=2
[    0.561309] omap_i2c omap_i2c.1: addr: 0x0049, len: 2, flags: 0x0, stop: 1
[    0.561401] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.561462] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.565185] twl4030_gpio twl4030_gpio: gpio (irq 338) chaining IRQs 354..371
[    0.565246] i2c i2c-1: master_xfer[0] W, addr=0x49, len=6
[    0.565338] omap_i2c omap_i2c.1: addr: 0x0049, len: 6, flags: 0x0, stop: 1
[    0.565490] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.565521] omap_i2c omap_i2c.1: IRQ (ISR = 0x4000)
[    0.565612] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.565795] i2c i2c-1: master_xfer[0] W, addr=0x49, len=4
[    0.565856] omap_i2c omap_i2c.1: addr: 0x0049, len: 4, flags: 0x0, stop: 1
[    0.565948] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.566040] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.566162] gpiochip_find_base: found new base at 492
[    0.567779] gpiochip_add: registered GPIOs 492 to 511 on device: twl4030
[    0.569366] i2c i2c-1: master_xfer[0] W, addr=0x49, len=2
[    0.569488] omap_i2c omap_i2c.1: addr: 0x0049, len: 2, flags: 0x0, stop: 1
[    0.569641] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.569702] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.569854] i2c i2c-1: master_xfer[0] W, addr=0x49, len=1
[    0.569885] i2c i2c-1: master_xfer[1] R, addr=0x49, len=1
[    0.569946] omap_i2c omap_i2c.1: addr: 0x0049, len: 1, flags: 0x0, stop: 0
[    0.570037] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.570098] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.570190] omap_i2c omap_i2c.1: addr: 0x0049, len: 1, flags: 0x1, stop: 1
[    0.570281] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.570312] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.570404] i2c i2c-1: master_xfer[0] W, addr=0x49, len=2
[    0.570465] omap_i2c omap_i2c.1: addr: 0x0049, len: 2, flags: 0x0, stop: 1
[    0.570556] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.570648] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.570770] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=2
[    0.570800] omap_i2c omap_i2c.1: addr: 0x004a, len: 2, flags: 0x0, stop: 1
[    0.570892] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.570983] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.571075] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=2
[    0.571289] omap_i2c omap_i2c.1: addr: 0x004a, len: 2, flags: 0x0, stop: 1
[    0.571380] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.571472] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.571655] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=1
[    0.571685] i2c i2c-1: master_xfer[1] R, addr=0x4a, len=1
[    0.571716] omap_i2c omap_i2c.1: addr: 0x004a, len: 1, flags: 0x0, stop: 0
[    0.571838] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.571899] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.571960] omap_i2c omap_i2c.1: addr: 0x004a, len: 1, flags: 0x1, stop: 1
[    0.572052] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.572082] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.572204] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=2
[    0.572235] omap_i2c omap_i2c.1: addr: 0x004a, len: 2, flags: 0x0, stop: 1
[    0.572326] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.572418] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.572540] i2c i2c-1: master_xfer[0] W, addr=0x4a, len=2
[    0.572601] omap_i2c omap_i2c.1: addr: 0x004a, len: 2, flags: 0x0, stop: 1
[    0.572692] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.572784] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.580383] vdd_mpu_iva: 600 <--> 1450 mV normal 
[    0.581024] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    0.581085] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    0.581207] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.581298] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.583740] vdd_core: 600 <--> 1450 mV normal 
[    0.584197] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    0.584259] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    0.584411] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.584503] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.587371] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    0.587402] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    0.587493] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    0.587646] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.587738] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.587829] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    0.587951] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.587951] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.588073] VMMC1: 1850 <--> 3150 mV at 3000 mV normal standby
[    0.588104] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    0.588134] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    0.588195] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    0.588287] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.588348] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.588439] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    0.588531] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.588562] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.589202] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    0.589233] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    0.589355] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.589477] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.591949] VDAC: 1800 mV normal standby
[    0.592010] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    0.592041] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    0.592071] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    0.592193] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.592285] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.592376] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    0.592468] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.592498] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.593139] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    0.593200] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    0.593292] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.593688] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.596221] VDVI: 1800 mV normal standby
[    0.596252] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    0.596282] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    0.596343] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    0.596466] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.596527] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.596649] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    0.596740] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.596771] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.597320] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    0.597351] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    0.597473] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.597564] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.599975] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    0.600006] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    0.600067] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    0.600189] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.600250] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.600341] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    0.600433] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.600463] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.600585] VSIM: 1800 <--> 3000 mV at 1800 mV normal standby
[    0.600616] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    0.600646] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    0.600708] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    0.600799] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.601165] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.601348] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    0.601440] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    0.601470] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.602142] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    0.602203] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    0.602294] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    0.602416] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    0.602691] i2c i2c-1: client [twl4030] registered with bus id 1-0048
[    0.602813] omap_i2c omap_i2c.1: bus 1 rev1.3.12 at 2600 kHz
[    0.617614] i2c i2c-3: adapter [OMAP I2C adapter] registered
[    0.618041] i2c 3-0050: uevent
[    0.618743] i2c i2c-3: client [eeprom] registered with bus id 3-0050
[    0.618804] omap_i2c omap_i2c.3: bus 3 rev1.3.12 at 100 kHz
[    0.629852] Switching to clocksource 32k_counter
[    0.819976] NET: Registered protocol family 2
[    0.822814] TCP established hash table entries: 8192 (order: 4, 65536 bytes)
[    0.823394] TCP bind hash table entries: 8192 (order: 6, 294912 bytes)
[    0.829284] TCP: Hash tables configured (established 8192 bind 8192)
[    0.829681] TCP: reno registered
[    0.829711] UDP hash table entries: 256 (order: 2, 20480 bytes)
[    0.830108] UDP-Lite hash table entries: 256 (order: 2, 20480 bytes)
[    0.831573] NET: Registered protocol family 1
[    0.834106] RPC: Registered named UNIX socket transport module.
[    0.834167] RPC: Registered udp transport module.
[    0.834167] RPC: Registered tcp transport module.
[    0.834197] RPC: Registered tcp NFSv4.1 backchannel transport module.
[    0.835723] NetWinder Floating Point Emulator V0.97 (double precision)
[    0.836212] CPU PMU: probing PMU on CPU 0
[    0.836425] hw perfevents: enabled with ARMv7 Cortex-A8 PMU driver, 5 counters available
[    1.058898] VFS: Disk quotas dquot_6.5.2
[    1.059265] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
[    1.063476] NFS: Registering the id_resolver key type
[    1.064178] Key type id_resolver registered
[    1.064208] Key type id_legacy registered
[    1.064453] jffs2: version 2.2. (NAND) (SUMMARY)  ? 2001-2006 Red Hat, Inc.
[    1.065338] msgmni has been set to 479
[    1.070770] io scheduler noop registered
[    1.070800] io scheduler deadline registered
[    1.070922] io scheduler cfq registered (default)
[    1.075500] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
[    1.085754] omap_uart.0: ttyO0 at MMIO 0x4806a000 (irq = 88) is a OMAP UART0
[    1.088653] omap_uart.1: ttyO1 at MMIO 0x4806c000 (irq = 89) is a OMAP UART1
[    1.090850] omap_uart.2: ttyO2 at MMIO 0x49020000 (irq = 90) is a OMAP UART2
[    2.409454] console [ttyO2] enabled
[    2.461151] brd: module loaded
[    2.493194] loop: module loaded
[    2.495727] i2c-core: driver [menelaus] registered
[    2.499206] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    2.502166] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    2.505554] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    2.509490] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    2.512207] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    2.515106] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    2.518920] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    2.521575] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    2.524749] i2c i2c-1: master_xfer[0] W, addr=0x49, len=2
[    2.527709] omap_i2c omap_i2c.1: addr: 0x0049, len: 2, flags: 0x0, stop: 1
[    2.532348] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    2.535064] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    2.546630] mtdoops: mtd device (mtddev=name/number) must be supplied
[    2.550842] NAND device: Manufacturer ID: 0x2c, Chip ID: 0xba (Micron NAND 256MiB 1,8V 16-bit), page size: 2048, OOB size: 64
[    2.557312] Creating 5 MTD partitions on "omap2-nand.0":
[    2.560302] 0x000000000000-0x000000080000 : "X-Loader"
[    2.573455] 0x000000080000-0x000000260000 : "U-Boot"
[    2.584594] 0x000000260000-0x000000280000 : "U-Boot Env"
[    2.593811] 0x000000280000-0x000000680000 : "Kernel"
[    2.606109] 0x000000680000-0x000010000000 : "File System"
[    2.828338] OneNAND driver initializing
[    2.847808] usbcore: registered new interface driver asix
[    2.851654] usbcore: registered new interface driver cdc_ether
[    2.855651] usbcore: registered new interface driver smsc95xx
[    2.859619] usbcore: registered new interface driver net1080
[    2.863464] usbcore: registered new interface driver cdc_subset
[    2.867492] usbcore: registered new interface driver zaurus
[    2.871337] usbcore: registered new interface driver cdc_ncm
[    2.877563] usbcore: registered new interface driver cdc_wdm
[    2.880798] Initializing USB Mass Storage driver...
[    2.884307] usbcore: registered new interface driver usb-storage
[    2.887573] USB Mass Storage support registered.
[    2.891021] usbcore: registered new interface driver usbtest
[    2.896881] mousedev: PS/2 mouse device common for all mice
[    2.904998] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    2.908050] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    2.912017] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    2.914733] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    2.917541] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    2.920562] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=2
[    2.923522] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    2.927398] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    2.930114] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    2.932830] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x1, stop: 1
[    2.936737] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    2.939392] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    2.942138] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=3
[    2.945190] omap_i2c omap_i2c.1: addr: 0x004b, len: 3, flags: 0x0, stop: 1
[    2.949005] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    2.951751] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    2.956054] input: twl4030_pwrbutton as /devices/platform/omap_i2c.1/i2c-1/1-0049/twl4030_pwrbutton/input/input0
[    2.965484] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    2.968749] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    2.971740] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    2.975677] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    2.978393] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    2.981201] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    2.986236] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    2.988891] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    2.991973] twl_rtc twl_rtc: Power up reset detected.
[    2.994750] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    2.997955] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    3.001770] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.004547] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.007415] twl_rtc twl_rtc: Enabling TWL-RTC
[    3.009796] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    3.012756] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    3.016693] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.019439] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.022308] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    3.025268] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    3.029571] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.032318] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.035125] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.038208] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.041168] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.045043] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.047760] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.050537] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.054443] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.057098] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.060821] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.063781] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.066772] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.070739] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.073425] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.076293] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.080108] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.082794] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.085632] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    3.088592] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    3.092468] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.095214] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.098388] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.101440] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=6
[    3.104400] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.108276] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.110992] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.113708] omap_i2c omap_i2c.1: addr: 0x004b, len: 6, flags: 0x1, stop: 1
[    3.117736] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.120422] omap_i2c omap_i2c.1: IRQ (ISR = 0x2000)
[    3.123199] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.125946] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.128906] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=6
[    3.131927] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.135742] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.138519] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.141235] omap_i2c omap_i2c.1: addr: 0x004b, len: 6, flags: 0x1, stop: 1
[    3.145172] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.147827] omap_i2c omap_i2c.1: IRQ (ISR = 0x2000)
[    3.150604] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.153350] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.156372] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.159362] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.163208] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.165924] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.168640] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.172546] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.175201] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.178009] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    3.180969] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    3.184814] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.187561] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.190307] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.193328] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=6
[    3.196319] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.200103] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.202880] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.205596] omap_i2c omap_i2c.1: addr: 0x004b, len: 6, flags: 0x1, stop: 1
[    3.209594] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.212249] omap_i2c omap_i2c.1: IRQ (ISR = 0x2000)
[    3.214965] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.219451] twl_rtc twl_rtc: rtc core: registered twl_rtc as rtc0
[    3.223144] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    3.226287] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    3.230133] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.232910] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.235717] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.238677] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=2
[    3.241760] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.245574] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.248352] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.251129] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x1, stop: 1
[    3.254943] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.257629] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.260498] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=3
[    3.263580] omap_i2c omap_i2c.1: addr: 0x004b, len: 3, flags: 0x0, stop: 1
[    3.267425] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.270141] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.273895] i2c /dev entries driver
[    3.278717] i2c-dev: adapter [OMAP I2C adapter] registered as minor 1
[    3.283691] i2c-dev: adapter [OMAP I2C adapter] registered as minor 3
[    3.287353] Driver for 1-wire Dallas network protocol.
[    3.295043] omap_wdt: OMAP Watchdog Timer Rev 0x31: initial timeout 60 sec
[    3.300048] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    3.303222] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    3.307067] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.309814] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.312713] twl4030_wdt twl4030_wdt: Failed to register misc device
[    3.316192] twl4030_wdt: probe of twl4030_wdt failed with error -16
[    3.323455] i2c i2c-1: master_xfer[0] W, addr=0x49, len=1
[    3.326690] i2c i2c-1: master_xfer[1] R, addr=0x49, len=1
[    3.329711] omap_i2c omap_i2c.1: addr: 0x0049, len: 1, flags: 0x0, stop: 0
[    3.333679] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.336364] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.339202] omap_i2c omap_i2c.1: addr: 0x0049, len: 1, flags: 0x1, stop: 1
[    3.343139] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.345794] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.348602] i2c i2c-1: master_xfer[0] W, addr=0x49, len=2
[    3.351867] omap_i2c omap_i2c.1: addr: 0x0049, len: 2, flags: 0x0, stop: 1
[    3.355682] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.358459] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.362335] omap_hsmmc omap_hsmmc.0: Failed to get debounce clk
[    3.365844] omap-dma-engine omap-dma-engine: allocating channel for 62
[    3.369506] omap-dma-engine omap-dma-engine: allocating channel for 61
[    3.374359] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.377319] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.380371] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.384368] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.387054] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.389953] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.393768] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.396423] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.399353] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.402313] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.405426] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.409240] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.412017] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.414794] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.418609] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.421264] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.424163] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.427124] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.430175] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.433990] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.436767] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.439514] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.443420] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.446075] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.448822] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    3.451873] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    3.455688] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.458404] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.461212] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.464172] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.467193] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.471008] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.473693] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.476501] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.480285] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.482971] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.485778] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.488708] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.491760] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.495574] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.498321] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.501068] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.504852] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.507537] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.510345] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.513366] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.516326] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.520141] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.522888] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.525634] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.529510] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.532165] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.534912] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.537933] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.540893] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.544769] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.547454] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.550170] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.554046] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.556732] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.559478] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    3.562499] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    3.566314] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.569061] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.677520] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.680450] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.683410] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.687316] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.690002] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.692749] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.696624] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.699279] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.702117] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    3.705078] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    3.708953] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.711700] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.714447] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.717468] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.720428] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.724304] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.727020] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.729736] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.733612] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.736267] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.739013] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    3.742034] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    3.745849] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.748626] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.857482] i2c i2c-1: master_xfer[0] W, addr=0x49, len=4
[    3.860443] omap_i2c omap_i2c.1: addr: 0x0049, len: 4, flags: 0x0, stop: 1
[    3.864288] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.867065] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.869812] i2c i2c-1: master_xfer[0] W, addr=0x49, len=1
[    3.872833] i2c i2c-1: master_xfer[1] R, addr=0x49, len=5
[    3.875793] omap_i2c omap_i2c.1: addr: 0x0049, len: 1, flags: 0x0, stop: 0
[    3.879608] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.882385] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.885101] omap_i2c omap_i2c.1: addr: 0x0049, len: 5, flags: 0x1, stop: 1
[    3.889007] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.891662] omap_i2c omap_i2c.1: IRQ (ISR = 0x2000)
[    3.894378] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.897186] i2c i2c-1: master_xfer[0] W, addr=0x49, len=6
[    3.900146] omap_i2c omap_i2c.1: addr: 0x0049, len: 6, flags: 0x0, stop: 1
[    3.904022] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.906677] omap_i2c omap_i2c.1: IRQ (ISR = 0x4000)
[    3.909393] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.914062] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.916992] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.920135] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.923980] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.926666] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.929534] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.933349] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.936035] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.938934] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.941894] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.944946] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.948760] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.951538] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.954284] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.958099] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.960754] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.963653] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    3.966705] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    3.970520] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.973236] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.976623] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    3.979583] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    3.982666] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    3.986480] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    3.989196] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    3.992034] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    3.995849] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    3.998504] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.001403] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    4.004333] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    4.007415] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    4.011230] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.014007] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.016784] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    4.020599] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    4.023254] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.026123] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    4.029174] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    4.032165] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    4.035949] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.038726] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.041473] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    4.045379] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    4.048034] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.050781] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    4.053802] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    4.057617] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.060394] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.063232] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    4.066192] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    4.069213] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    4.073028] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.075805] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.078521] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    4.082336] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    4.084991] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.087799] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    4.090759] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    4.093780] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    4.097595] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.100341] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.103057] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    4.106933] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    4.109588] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.112396] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    4.115447] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    4.119232] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.121978] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.279876] i2c i2c-1: master_xfer[0] W, addr=0x49, len=1
[    4.282836] i2c i2c-1: master_xfer[1] R, addr=0x49, len=1
[    4.285858] omap_i2c omap_i2c.1: addr: 0x0049, len: 1, flags: 0x0, stop: 0
[    4.289855] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.292541] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.297668] omap_i2c omap_i2c.1: addr: 0x0049, len: 1, flags: 0x1, stop: 1
[    4.301544] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    4.304199] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.308349] usbcore: registered new interface driver usbhid
[    4.311523] usbhid: USB HID core driver
[    4.317321] oprofile: using arm/armv7
[    4.320526] TCP: cubic registered
[    4.322326] Initializing XFRM netlink socket
[    4.324859] NET: Registered protocol family 17
[    4.327514] NET: Registered protocol family 15
[    4.330535] Key type dns_resolver registered
[    4.333038] VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 1
[    4.348693] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    4.351776] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    4.354827] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    4.358795] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.361511] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.365783] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    4.369659] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    4.372314] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.377227] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    4.380279] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    4.384185] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.386932] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.391601] PM: no software I/O chain control; some wakeups may be lost
[    4.395812] ThumbEE CPU extension supported.
[    4.443084] clock: disabling unused clocks to save power
[    4.452331] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    4.455291] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    4.458374] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    4.462371] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.465087] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.467987] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    4.471801] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    4.474487] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.477386] VDVI: incomplete constraints, leaving on
[    4.480102] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    4.483306] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    4.486267] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    4.490173] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.492858] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.495666] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    4.499572] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    4.502227] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.505035] VDAC: incomplete constraints, leaving on
[    4.512847] input: gpio-keys as /devices/platform/gpio-keys/input/input1
[    4.519531] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    4.522644] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[    4.525665] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    4.529632] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.532348] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.535156] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[    4.539123] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    4.541778] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.544830] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[    4.547821] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[    4.551635] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.554443] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.557281] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[    4.560363] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=6
[    4.563323] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[    4.567138] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[    4.569915] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.572692] omap_i2c omap_i2c.1: addr: 0x004b, len: 6, flags: 0x1, stop: 1
[    4.576843] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[    4.579498] omap_i2c omap_i2c.1: IRQ (ISR = 0x2000)
[    4.582244] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[    4.585235] twl_rtc twl_rtc: setting system clock to 2000-01-01 00:00:01 UTC (946684801)
[    4.595428] Waiting for root device /dev/mmcblk0p2...
[    4.702789] mmc0: SD Status: Invalid Allocation Unit size.
[    4.708129] mmc0: new SD card at address 8001
[    4.714416] mmcblk0: mmc0:8001 SD02G 1.89 GiB 
[    4.724670]  mmcblk0: p1 p2
[    6.088897] kjournald starting.  Commit interval 5 seconds
[    6.092681] EXT3-fs (mmcblk0p2): warning: maximal mount count reached, running e2fsck is recommended
[    6.279846] EXT3-fs (mmcblk0p2): using internal journal
[    6.287200] EXT3-fs (mmcblk0p2): recovery complete
[    6.289825] EXT3-fs (mmcblk0p2): mounted filesystem with ordered data mode
[    6.294158] VFS: Mounted root (ext3 filesystem) on device 179:2.
[    6.298675] Freeing init memory: 320K
INIT: version 2.86 booting
Starting the hotplug events dispatcher udevd
Synthesizing the initial hotplug events
[    9.449676] twl 1-0048: uevent
[    9.467559] dummy 1-0049: uevent
[    9.472778] dummy 1-004a: uevent
[    9.519195] dummy 1-004b: uevent
[    9.536560] i2c 3-0050: uevent
Remounting root file system...
mount: according to mtab, /proc is already mounted on /proc

WARNING: Couldn't open directory /lib/modules/3.7.0-rc3: No such file or directory
FATAL: Could not open /lib/modules/3.7.0-rc3/modules.dep.temp for writing: No such file or directory
root: mount: mount point /proc/bus/usb does not exist
Setting up IP spoofing protection: rp_filter.
Configuring network interfaces... modprobe: FATAL: Could not load /lib/modules/3.7.0-rc3/modules.dep: No such file or directory

modprobe: FATAL: Could not load /lib/modules/3.7.0-rc3/modules.dep: No such file or directory

ifconfig: SIOCGIFFLAGS: No such device
modprobe: FATAL: Could not load /lib/modules/3.7.0-rc3/modules.dep: No such file or directory

modprobe: FATAL: Could not load /lib/modules/3.7.0-rc3/modules.dep: No such file or directory

modprobe: FATAL: Could not load /lib/modules/3.7.0-rc3/modules.dep: No such file or directory

modprobe: FATAL: Could not load /lib/modules/3.7.0-rc3/modules.dep: No such file or directory

eth0      No such device

modprobe: FATAL: Could not load /lib/modules/3.7.0-rc3/modules.dep: No such file or directory

modprobe: FATAL: Could not load /lib/modules/3.7.0-rc3/modules.dep: No such file or directory

udhcpc: SIOCGIFINDEX: No such device
done.
Starting portmap daemon: portmap.
[   24.558410] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[   24.561553] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[   24.564758] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[   24.568695] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[   24.571411] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.574218] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[   24.578186] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[   24.580871] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.583801] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[   24.586761] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[   24.590576] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[   24.593383] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.596191] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[   24.599243] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=6
[   24.602203] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[   24.606018] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[   24.608764] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.611541] omap_i2c omap_i2c.1: addr: 0x004b, len: 6, flags: 0x1, stop: 1
[   24.615631] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[   24.618286] omap_i2c omap_i2c.1: IRQ (ISR = 0x2000)
[   24.621002] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
Tue Jul 22 00:18:00 UTC 2008
[   24.757415] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[   24.760406] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[   24.763549] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[   24.767395] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[   24.770111] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.773162] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[   24.777038] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[   24.779693] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.782623] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[   24.785614] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[   24.789520] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[   24.792297] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.795166] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=7
[   24.798126] omap_i2c omap_i2c.1: addr: 0x004b, len: 7, flags: 0x0, stop: 1
[   24.801940] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[   24.804626] omap_i2c omap_i2c.1: IRQ (ISR = 0x4000)
[   24.807434] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.810272] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[   24.813232] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[   24.817047] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[   24.819824] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.823242] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[   24.826324] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=1
[   24.829345] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[   24.833282] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[   24.836059] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.838958] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x1, stop: 1
[   24.842864] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[   24.845550] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.848297] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=2
[   24.851348] omap_i2c omap_i2c.1: addr: 0x004b, len: 2, flags: 0x0, stop: 1
[   24.855163] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[   24.857940] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.860687] i2c i2c-1: master_xfer[0] W, addr=0x4b, len=1
[   24.863647] i2c i2c-1: master_xfer[1] R, addr=0x4b, len=6
[   24.866668] omap_i2c omap_i2c.1: addr: 0x004b, len: 1, flags: 0x0, stop: 0
[   24.870483] omap_i2c omap_i2c.1: IRQ (ISR = 0x0010)
[   24.873260] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
[   24.875976] omap_i2c omap_i2c.1: addr: 0x004b, len: 6, flags: 0x1, stop: 1
[   24.880065] omap_i2c omap_i2c.1: IRQ (ISR = 0x0008)
[   24.882720] omap_i2c omap_i2c.1: IRQ (ISR = 0x2000)
[   24.885528] omap_i2c omap_i2c.1: IRQ (ISR = 0x0004)
INIT: Entering runlevel: 5
ALSA: Restoring mixer settings...
/usr/sbin/alsactl: load_state:1327: No soundcards found...
Starting Dropbear SSH server: modprobe: FATAL: Could not load /lib/modules/3.7.0-rc3/modules.dep: No such file or directory

modprobe: FATAL: Could not load /lib/modules/3.7.0-rc3/modules.dep: No such file or directory

dropbear.
Starting advanced power management daemon: No APM support in kernel
(failed.)
Starting system message bus: dbus.
Starting syslogd/klogd: start-stop-daemon: lseek: Invalid argument
 * Starting Avahi mDNS/DNS-SD Daemon: avahi-daemon
[ ok ]
Starting Bluetooth subsystem: hcidmodprobe: FATAL: Could not load /lib/modules/3.7.0-rc3/modules.dep: No such file or directory

 hid2hci.

.-------.                                           
|       |                  .-.                      
|   |   |-----.-----.-----.| |   .----..-----.-----.
|       |     | __  |  ---'| '--.|  .-'|     |     |
|   |   |  |  |     |---  ||  --'|  |  |  '  | | | |
'---'---'--'--'--.  |-----''----''--'  '-----'-'-'-'
                -'  |
                '---'

The Angstrom Distribution beagleboard ttyO2

Angstrom 2008.1-test-20080712 beagleboard ttyO2

beagleboard login: 

^ permalink raw reply

* [PATCH 1/4] net: mvneta: driver for Marvell Armada 370/XP network unit
From: Nobuhiro Iwamatsu @ 2012-10-30 12:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351245804-31478-2-git-send-email-thomas.petazzoni@free-electrons.com>

Hi,

I tested this driver on OpenBlocks AX3 and worked fine.
I will send a patch which support DT for OpenBlocks AX3.

On Fri, Oct 26, 2012 at 7:03 PM, Thomas Petazzoni
<thomas.petazzoni@free-electrons.com> wrote:
> This patch contains a new network driver for the network unit of the
> ARM Marvell Armada 370 and the Armada XP. Both SoCs use the PJ4B
> processor, a Marvell-developed ARM core that implements the ARMv7
> instruction set.
>
> Compared to previous ARM Marvell SoCs (Kirkwood, Orion, Discovery),
> the network unit in Armada 370 and Armada XP is highly different. This
> is the reason why this new 'mvneta' driver is needed, while the older
> ARM Marvell SoCs use the 'mv643xx_eth' driver.
>
> Here is an overview of the most important hardware changes that
> require a new, specific, driver for the network unit of Armada 370/XP:
>
>  - The new network unit has a completely different design and layout
>    for the RX and TX descriptors. They are now organized as a simple
>    array (each RX and TX queue has base address and size of this
>    array) rather than a linked list as in the old SoCs.
>
>  - The new network unit has a different RXQ and TXQ management: this
>    management is done using special read/write counter registers,
>    while in the Old SocS, it was done using the Ownership bit in RX
>    and TX descriptors.
>
>  - The new network unit has different interrupt registers
>
>  - The new network unit way of cleaning of interrupts is not done by
>    writing to the cause register, but by updating per-queue counters
>
>  - The new network unit has different GMAC registers (link, speed,
>    duplex configuration) and different WRR registers.
>
>  - The new network unit has lots of new units like PnC (Parser and
>    Classifier), PMT, BM (Memory Buffer Management), xPON, and more.
>
> The driver proposed in the current patch only handles the basic
> features. Additional hardware features will progressively be supported
> as needed.
>
> This code has originally been written by Rami Rosen
> <rosenr@marvell.com>, and then reviewed and cleaned up by Thomas
> Petazzoni <thomas.petazzoni@free-electrons.com>.
>
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>

Tested-by: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>

> ---
>  .../bindings/net/marvell-armada-370-neta.txt       |   22 +
>  drivers/net/ethernet/marvell/Kconfig               |   12 +
>  drivers/net/ethernet/marvell/Makefile              |    1 +
>  drivers/net/ethernet/marvell/mvneta.c              | 3006 ++++++++++++++++++++
>  4 files changed, 3041 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
>  create mode 100644 drivers/net/ethernet/marvell/mvneta.c
>
> diff --git a/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
> new file mode 100644
> index 0000000..b094c79
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/marvell-armada-370-neta.txt
> @@ -0,0 +1,22 @@
> +* Marvell Armada 370 / Armada XP Ethernet Controller (NETA)
> +
> +Required properties:
> +- compatible: should be "marvell,armada-370-neta".
> +- reg: address and length of the register set for the device.
> +- interrupts: interrupt for the device
> +- phy-mode: String, operation mode of the PHY interface. Supported
> +  values are the ones handled by of_get_phy_mode().
> +- phy-addr: Integer, address of the PHY.
> +- clock-frequency: frequency of the peripheral clock of the SoC.
> +
> +Example:
> +
> +ethernet at d0070000 {
> +               compatible = "marvell,armada-370-neta";
> +               reg = <0xd0070000 0x2500>;
> +               interrupts = <8>;
> +               clock-frequency = <250000000>;
> +               status = "okay";
> +               phy-mode = "rgmii-id";
> +               phy-addr = <25>;
> +};
> diff --git a/drivers/net/ethernet/marvell/Kconfig b/drivers/net/ethernet/marvell/Kconfig
> index 0029934..7bdc5da 100644
> --- a/drivers/net/ethernet/marvell/Kconfig
> +++ b/drivers/net/ethernet/marvell/Kconfig
> @@ -18,6 +18,18 @@ config NET_VENDOR_MARVELL
>
>  if NET_VENDOR_MARVELL
>
> +config MVNETA
> +       tristate "Marvell Armada 370/XP network interface support"
> +       depends on MACH_ARMADA_370_XP
> +       select PHYLIB
> +       ---help---
> +         This driver supports the network interface units in the
> +         Marvell ARMADA XP and ARMADA 370 SoC family.
> +
> +         Note that this driver is distinct from the mv643xx_eth
> +         driver, which should be used for the older Marvell SoCs
> +         (Dove, Orion, Discovery, Kirkwood).
> +
>  config MV643XX_ETH
>         tristate "Marvell Discovery (643XX) and Orion ethernet support"
>         depends on (MV64X60 || PPC32 || PLAT_ORION) && INET
> diff --git a/drivers/net/ethernet/marvell/Makefile b/drivers/net/ethernet/marvell/Makefile
> index 57e3234..a13f9b9 100644
> --- a/drivers/net/ethernet/marvell/Makefile
> +++ b/drivers/net/ethernet/marvell/Makefile
> @@ -6,3 +6,4 @@ obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
>  obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o
>  obj-$(CONFIG_SKGE) += skge.o
>  obj-$(CONFIG_SKY2) += sky2.o
> +obj-$(CONFIG_MVNETA) += mvneta.o
> diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
> new file mode 100644
> index 0000000..1eef8bc
> --- /dev/null
> +++ b/drivers/net/ethernet/marvell/mvneta.c
> @@ -0,0 +1,3006 @@
> +/*
> + * Driver for Marvell NETA network card for Armada XP and Armada 370 SoCs.
> + *
> + * Copyright (C) 2012 Marvell
> + *
> + * Rami Rosen <rosenr@marvell.com>
> + * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/version.h>
> +#include <linux/netdevice.h>
> +#include <linux/etherdevice.h>
> +#include <linux/platform_device.h>
> +#include <linux/skbuff.h>
> +#include <linux/inetdevice.h>
> +#include <linux/mbus.h>
> +#include <linux/module.h>
> +#include <linux/interrupt.h>
> +#include <net/ip.h>
> +#include <net/ipv6.h>
> +#include <linux/of.h>
> +#include <linux/of_irq.h>
> +#include <linux/of_net.h>
> +#include <linux/of_address.h>
> +#include <linux/phy.h>
> +
> +/* Registers */
> +#define MVNETA_RXQ_CONFIG_REG(q)                (0x1400 + ((q) << 2))
> +#define      MVNETA_RXQ_HW_BUF_ALLOC            BIT(1)
> +#define      MVNETA_RXQ_PKT_OFFSET_ALL_MASK     (0xf    << 8)
> +#define      MVNETA_RXQ_PKT_OFFSET_MASK(offs)   ((offs) << 8)
> +#define MVNETA_RXQ_THRESHOLD_REG(q)             (0x14c0 + ((q) << 2))
> +#define      MVNETA_RXQ_NON_OCCUPIED(v)         ((v) << 16)
> +#define MVNETA_RXQ_BASE_ADDR_REG(q)             (0x1480 + ((q) << 2))
> +#define MVNETA_RXQ_SIZE_REG(q)                  (0x14a0 + ((q) << 2))
> +#define      MVNETA_RXQ_BUF_SIZE_SHIFT          19
> +#define      MVNETA_RXQ_BUF_SIZE_MASK           (0x1fff << 19)
> +#define MVNETA_RXQ_STATUS_REG(q)                (0x14e0 + ((q) << 2))
> +#define      MVNETA_RXQ_OCCUPIED_ALL_MASK       0x3fff
> +#define MVNETA_RXQ_STATUS_UPDATE_REG(q)         (0x1500 + ((q) << 2))
> +#define      MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT  16
> +#define      MVNETA_RXQ_ADD_NON_OCCUPIED_MAX    255
> +#define MVNETA_PORT_RX_RESET                    0x1cc0
> +#define      MVNETA_PORT_RX_DMA_RESET           BIT(0)
> +#define MVNETA_PHY_ADDR                         0x2000
> +#define      MVNETA_PHY_ADDR_MASK               0x1f
> +#define MVNETA_SMI                              0x2004
> +#define      MVNETA_SMI_DATA_SHIFT              0
> +#define      MVNETA_SMI_PHY_ADDR_SHIFT          16
> +#define      MVNETA_SMI_PHY_REG_SHIFT           21
> +#define      MVNETA_SMI_READ_OPERATION          BIT(26)
> +#define      MVNETA_SMI_WRITE_OPERATION         0
> +#define      MVNETA_SMI_READ_VALID              BIT(27)
> +#define      MVNETA_SMI_BUSY                    BIT(28)
> +#define MVNETA_MBUS_RETRY                       0x2010
> +#define MVNETA_UNIT_INTR_CAUSE                  0x2080
> +#define MVNETA_UNIT_CONTROL                     0x20B0
> +#define      MVNETA_PHY_POLLING_ENABLE          BIT(1)
> +#define MVNETA_WIN_BASE(w)                      (0x2200 + ((w) << 3))
> +#define MVNETA_WIN_SIZE(w)                      (0x2204 + ((w) << 3))
> +#define MVNETA_WIN_REMAP(w)                     (0x2280 + ((w) << 2))
> +#define MVNETA_BASE_ADDR_ENABLE                 0x2290
> +#define MVNETA_PORT_CONFIG                      0x2400
> +#define      MVNETA_UNI_PROMISC_MODE            BIT(0)
> +#define      MVNETA_DEF_RXQ(q)                  ((q) << 1)
> +#define      MVNETA_DEF_RXQ_ARP(q)              ((q) << 4)
> +#define      MVNETA_TX_UNSET_ERR_SUM            BIT(12)
> +#define      MVNETA_DEF_RXQ_TCP(q)              ((q) << 16)
> +#define      MVNETA_DEF_RXQ_UDP(q)              ((q) << 19)
> +#define      MVNETA_DEF_RXQ_BPDU(q)             ((q) << 22)
> +#define      MVNETA_RX_CSUM_WITH_PSEUDO_HDR     BIT(25)
> +#define      MVNETA_PORT_CONFIG_DEFL_VALUE(q)   (MVNETA_DEF_RXQ(q)       | \
> +                                                MVNETA_DEF_RXQ_ARP(q)   | \
> +                                                MVNETA_DEF_RXQ_TCP(q)   | \
> +                                                MVNETA_DEF_RXQ_UDP(q)   | \
> +                                                MVNETA_DEF_RXQ_BPDU(q)  | \
> +                                                MVNETA_TX_UNSET_ERR_SUM | \
> +                                                MVNETA_RX_CSUM_WITH_PSEUDO_HDR)
> +#define MVNETA_PORT_CONFIG_EXTEND                0x2404
> +#define MVNETA_MAC_ADDR_LOW                      0x2414
> +#define MVNETA_MAC_ADDR_HIGH                     0x2418
> +#define MVNETA_SDMA_CONFIG                       0x241c
> +#define      MVNETA_SDMA_BRST_SIZE_16            4
> +#define      MVNETA_NO_DESC_SWAP                 0x0
> +#define      MVNETA_RX_BRST_SZ_MASK(burst)       ((burst) << 1)
> +#define      MVNETA_RX_NO_DATA_SWAP              BIT(4)
> +#define      MVNETA_TX_NO_DATA_SWAP              BIT(5)
> +#define      MVNETA_TX_BRST_SZ_MASK(burst)       ((burst) << 22)
> +#define MVNETA_PORT_STATUS                       0x2444
> +#define      MVNETA_TX_IN_PRGRS                  BIT(1)
> +#define      MVNETA_TX_FIFO_EMPTY                BIT(8)
> +#define MVNETA_RX_MIN_FRAME_SIZE                 0x247c
> +#define MVNETA_TYPE_PRIO                         0x24bc
> +#define      MVNETA_FORCE_UNI                    BIT(21)
> +#define MVNETA_TXQ_CMD_1                         0x24e4
> +#define MVNETA_TXQ_CMD                           0x2448
> +#define      MVNETA_TXQ_DISABLE_SHIFT            8
> +#define      MVNETA_TXQ_ENABLE_MASK              0x000000ff
> +#define MVNETA_ACC_MODE                          0x2500
> +#define MVNETA_CPU_MAP(cpu)                      (0x2540 + ((cpu) << 2))
> +#define      MVNETA_CPU_RXQ_ACCESS_ALL_MASK      0x000000ff
> +#define      MVNETA_CPU_TXQ_ACCESS_ALL_MASK      0x0000ff00
> +#define MVNETA_RXQ_TIME_COAL_REG(q)              (0x2580 + ((q) << 2))
> +#define MVNETA_INTR_NEW_CAUSE                    0x25a0
> +#define      MVNETA_RX_INTR_MASK(nr_rxqs)        (((1 << nr_rxqs) - 1) << 8)
> +#define MVNETA_INTR_NEW_MASK                     0x25a4
> +#define MVNETA_INTR_OLD_CAUSE                    0x25a8
> +#define MVNETA_INTR_OLD_MASK                     0x25ac
> +#define MVNETA_INTR_MISC_CAUSE                   0x25b0
> +#define MVNETA_INTR_MISC_MASK                    0x25b4
> +#define MVNETA_INTR_ENABLE                       0x25b8
> +#define      MVNETA_TXQ_INTR_ENABLE_ALL_MASK     0x0000ff00
> +#define      MVNETA_RXQ_INTR_ENABLE_ALL_MASK     0xff000000
> +#define MVNETA_RXQ_CMD                           0x2680
> +#define      MVNETA_RXQ_DISABLE_SHIFT            8
> +#define      MVNETA_RXQ_ENABLE_MASK              0x000000ff
> +#define MVETH_TXQ_TOKEN_COUNT_REG(q)             (0x2700 + ((q) << 4))
> +#define MVETH_TXQ_TOKEN_CFG_REG(q)               (0x2704 + ((q) << 4))
> +#define MVNETA_GMAC_CTRL_0                       0x2c00
> +#define      MVNETA_GMAC_MAX_RX_SIZE_SHIFT       2
> +#define      MVNETA_GMAC_MAX_RX_SIZE_MASK        0x7ffc
> +#define      MVNETA_GMAC0_PORT_ENABLE            BIT(0)
> +#define MVNETA_GMAC_CTRL_2                       0x2c08
> +#define      MVNETA_GMAC2_PSC_ENABLE             BIT(3)
> +#define      MVNETA_GMAC2_PORT_RGMII             BIT(4)
> +#define      MVNETA_GMAC2_PORT_RESET             BIT(6)
> +#define MVNETA_GMAC_STATUS                       0x2c10
> +#define      MVNETA_GMAC_LINK_UP                 BIT(0)
> +#define      MVNETA_GMAC_SPEED_1000              BIT(1)
> +#define      MVNETA_GMAC_SPEED_100               BIT(2)
> +#define      MVNETA_GMAC_FULL_DUPLEX             BIT(3)
> +#define      MVNETA_GMAC_RX_FLOW_CTRL_ENABLE     BIT(4)
> +#define      MVNETA_GMAC_TX_FLOW_CTRL_ENABLE     BIT(5)
> +#define      MVNETA_GMAC_RX_FLOW_CTRL_ACTIVE     BIT(6)
> +#define      MVNETA_GMAC_TX_FLOW_CTRL_ACTIVE     BIT(7)
> +#define MVNETA_GMAC_AUTONEG_CONFIG               0x2c0c
> +#define      MVNETA_GMAC_FORCE_LINK_DOWN         BIT(0)
> +#define      MVNETA_GMAC_FORCE_LINK_PASS         BIT(1)
> +#define      MVNETA_GMAC_CONFIG_MII_SPEED        BIT(5)
> +#define      MVNETA_GMAC_CONFIG_GMII_SPEED       BIT(6)
> +#define      MVNETA_GMAC_CONFIG_FULL_DUPLEX      BIT(12)
> +#define MVNETA_MIB_COUNTERS_BASE                 0x3080
> +#define      MVNETA_MIB_LATE_COLLISION           0x7c
> +#define MVNETA_DA_FILT_SPEC_MCAST                0x3400
> +#define MVNETA_DA_FILT_OTH_MCAST                 0x3500
> +#define MVNETA_DA_FILT_UCAST_BASE                0x3600
> +#define MVNETA_TXQ_BASE_ADDR_REG(q)              (0x3c00 + ((q) << 2))
> +#define MVNETA_TXQ_SIZE_REG(q)                   (0x3c20 + ((q) << 2))
> +#define      MVNETA_TXQ_SENT_THRESH_ALL_MASK     0x3fff0000
> +#define      MVNETA_TXQ_SENT_THRESH_MASK(coal)   ((coal) << 16)
> +#define MVNETA_TXQ_UPDATE_REG(q)                 (0x3c60 + ((q) << 2))
> +#define      MVNETA_TXQ_DEC_SENT_SHIFT           16
> +#define MVNETA_TXQ_STATUS_REG(q)                 (0x3c40 + ((q) << 2))
> +#define      MVNETA_TXQ_SENT_DESC_SHIFT          16
> +#define      MVNETA_TXQ_SENT_DESC_MASK           0x3fff0000
> +#define MVNETA_PORT_TX_RESET                     0x3cf0
> +#define      MVNETA_PORT_TX_DMA_RESET            BIT(0)
> +#define MVNETA_TX_MTU                            0x3e0c
> +#define MVNETA_TX_TOKEN_SIZE                     0x3e14
> +#define      MVNETA_TX_TOKEN_SIZE_MAX            0xffffffff
> +#define MVNETA_TXQ_TOKEN_SIZE_REG(q)             (0x3e40 + ((q) << 2))
> +#define      MVNETA_TXQ_TOKEN_SIZE_MAX           0x7fffffff
> +
> +#define MVNETA_CAUSE_TXQ_SENT_DESC_ALL_MASK     0xff
> +
> +/* Descriptor ring Macros */
> +#define MVNETA_QUEUE_NEXT_DESC(q, index)       \
> +       (((index) < (q)->last_desc) ? ((index) + 1) : 0)
> +
> +/* Various constants */
> +
> +/* Coalescing */
> +#define MVNETA_TXDONE_COAL_PKTS                16
> +#define MVNETA_RX_COAL_PKTS            32
> +#define MVNETA_RX_COAL_USEC            100
> +
> +/* Timer */
> +#define MVNETA_TX_DONE_TIMER_PERIOD    10
> +
> +/* Napi polling weight */
> +#define MVNETA_RX_POLL_WEIGHT          64
> +
> +#define MVNETA_MH_SIZE                 2
> +
> +#define MVNETA_CPU_D_CACHE_LINE_SIZE    32
> +#define MVNETA_ETH_CRC_SIZE            4
> +#define MVNETA_TX_CSUM_MAX_SIZE                9800
> +#define MVNETA_ACC_MODE_EXT            1
> +
> +/* Timeout constants */
> +#define MVNETA_TX_DISABLE_TIMEOUT_MSEC 1000
> +#define MVNETA_RX_DISABLE_TIMEOUT_MSEC 1000
> +#define MVNETA_TX_FIFO_EMPTY_TIMEOUT   10000
> +
> +#define MVNETA_TX_MTU_MAX              0x3ffff
> +
> +/* Max number of Rx descriptors */
> +#define MVNETA_MAX_RXD 128
> +
> +/* Max number of Tx descriptors */
> +#define MVNETA_MAX_TXD 532
> +
> +/* descriptor aligned size */
> +#define MVNETA_DESC_ALIGNED_SIZE       32
> +
> +#define MVNETA_RX_PKT_SIZE(mtu) \
> +       ALIGN((mtu) + 2 + 4 + ETH_HLEN + 4, MVNETA_CPU_D_CACHE_LINE_SIZE)
> +
> +#define MVNETA_RX_BUF_SIZE(pkt_size)   ((pkt_size) + NET_SKB_PAD)
> +
> +struct mvneta_stats {
> +       struct  u64_stats_sync syncp;
> +       u64     packets;
> +       u64     bytes;
> +};
> +
> +struct mvneta_port {
> +       int pkt_size;
> +       void __iomem *base;
> +       struct mvneta_rx_queue *rxqs;
> +       struct mvneta_tx_queue *txqs;
> +       struct timer_list tx_done_timer;
> +       struct net_device *dev;
> +
> +       u32 cause_rx_tx;
> +       struct napi_struct napi;
> +
> +       /* Flags */
> +       unsigned long flags;
> +#define MVNETA_F_TX_DONE_TIMER_BIT  0
> +
> +       /* Napi weight */
> +       int weight;
> +
> +       /* Core clock */
> +       unsigned int clk_rate_hz;
> +       u8 mcast_count[256];
> +       u16 tx_ring_size;
> +       u16 rx_ring_size;
> +       struct mvneta_stats tx_stats;
> +       struct mvneta_stats rx_stats;
> +
> +       struct mii_bus *mii_bus;
> +       struct phy_device *phy_dev;
> +       phy_interface_t phy_interface;
> +       unsigned int link;
> +       unsigned int duplex;
> +       unsigned int speed;
> +};
> +
> +/*
> + * The mvneta_tx_desc and mvneta_rx_desc structures describe the
> + * layout of the transmit and reception DMA descriptors, and their
> + * layout is therefore defined by the hardware design
> + */
> +struct mvneta_tx_desc {
> +       u32  command;           /* Options used by HW for packet transmitting.*/
> +#define MVNETA_TX_L3_OFF_SHIFT 0
> +#define MVNETA_TX_IP_HLEN_SHIFT        8
> +#define MVNETA_TX_L4_UDP       BIT(16)
> +#define MVNETA_TX_L3_IP6       BIT(17)
> +#define MVNETA_TXD_IP_CSUM     BIT(18)
> +#define MVNETA_TXD_Z_PAD       BIT(19)
> +#define MVNETA_TXD_L_DESC      BIT(20)
> +#define MVNETA_TXD_F_DESC      BIT(21)
> +#define MVNETA_TXD_FLZ_DESC    (MVNETA_TXD_Z_PAD  | \
> +                                MVNETA_TXD_L_DESC | \
> +                                MVNETA_TXD_F_DESC)
> +#define MVNETA_TX_L4_CSUM_FULL BIT(30)
> +#define MVNETA_TX_L4_CSUM_NOT  BIT(31)
> +
> +       u16  reserverd1;        /* csum_l4 (for future use)             */
> +       u16  data_size;         /* Data size of transmitted packet in bytes */
> +       u32  buf_phys_addr;     /* Physical addr of transmitted buffer  */
> +       u32  reserved2;         /* hw_cmd - (for future use, PMT)       */
> +       u32  reserved3[4];      /* Reserved - (for future use)          */
> +};
> +
> +struct mvneta_rx_desc {
> +       u32  status;            /* Info about received packet           */
> +#define MVNETA_RXD_ERR_CRC             0x0
> +#define MVNETA_RXD_ERR_SUMMARY         BIT(16)
> +#define MVNETA_RXD_ERR_OVERRUN         BIT(17)
> +#define MVNETA_RXD_ERR_LEN             BIT(18)
> +#define MVNETA_RXD_ERR_RESOURCE                (BIT(17) | BIT(18))
> +#define MVNETA_RXD_ERR_CODE_MASK       (BIT(17) | BIT(18))
> +#define MVNETA_RXD_L3_IP4              BIT(25)
> +#define MVNETA_RXD_FIRST_LAST_DESC     (BIT(26) | BIT(27))
> +#define MVNETA_RXD_L4_CSUM_OK          BIT(30)
> +
> +       u16  reserved1;         /* pnc_info - (for future use, PnC)     */
> +       u16  data_size;         /* Size of received packet in bytes     */
> +       u32  buf_phys_addr;     /* Physical address of the buffer       */
> +       u32  reserved2;         /* pnc_flow_id  (for future use, PnC)   */
> +       u32  buf_cookie;        /* cookie for access to RX buffer in rx path */
> +       u16  reserved3;         /* prefetch_cmd, for future use         */
> +       u16  reserved4;         /* csum_l4 - (for future use, PnC)      */
> +       u32  reserved5;         /* pnc_extra PnC (for future use, PnC)  */
> +       u32  reserved6;         /* hw_cmd (for future use, PnC and HWF) */
> +};
> +
> +struct mvneta_tx_queue {
> +       /* Number of this TX queue, in the range 0-7 */
> +       u8 id;
> +
> +       /* Number of TX DMA descriptors in the descriptor ring */
> +       int size;
> +
> +       /* Number of currently used TX DMA descriptor in the
> +        * descriptor ring */
> +       int count;
> +
> +       /* Array of transmitted skb */
> +       struct sk_buff **tx_skb;
> +
> +       /* Index of last TX DMA descriptor that was inserted */
> +       int txq_put_index;
> +
> +       /* Index of the TX DMA descriptor to be cleaned up */
> +       int txq_get_index;
> +
> +       u32 done_pkts_coal;
> +
> +       /* Virtual address of the TX DMA descriptors array */
> +       struct mvneta_tx_desc *descs;
> +
> +       /* DMA address of the TX DMA descriptors array */
> +       dma_addr_t descs_phys;
> +
> +       /* Index of the last TX DMA descriptor */
> +       int last_desc;
> +
> +       /* Index of the next TX DMA descriptor to process */
> +       int next_desc_to_proc;
> +};
> +
> +struct mvneta_rx_queue {
> +       /* rx queue number, in the range 0-7 */
> +       u8 id;
> +
> +       /* num of rx descriptors in the rx descriptor ring */
> +       int size;
> +
> +       /* counter of times when mvneta_refill() failed */
> +       int missed;
> +
> +       u32 pkts_coal;
> +       u32 time_coal;
> +
> +       /* Virtual address of the RX DMA descriptors array */
> +       struct mvneta_rx_desc *descs;
> +
> +       /* DMA address of the RX DMA descriptors array */
> +       dma_addr_t descs_phys;
> +
> +       /* Index of the last RX DMA descriptor */
> +       int last_desc;
> +
> +       /* Index of the next RX DMA descriptor to process */
> +       int next_desc_to_proc;
> +};
> +
> +static int rxq_number = 8;
> +static int txq_number = 8;
> +
> +static int rxq_def;
> +static int txq_def;
> +
> +#define MVNETA_DRIVER_NAME "mvneta"
> +#define MVNETA_DRIVER_VERSION "1.0"
> +
> +/* Utility/helper methods */
> +
> +/* Write helper method */
> +static void mvreg_write(struct mvneta_port *pp, u32 offset, u32 data)
> +{
> +       writel(data, pp->base + offset);
> +}
> +
> +/* Read helper method */
> +static u32 mvreg_read(struct mvneta_port *pp, u32 offset)
> +{
> +       return readl(pp->base + offset);
> +}
> +
> +/* Increment txq get counter */
> +static void mvneta_txq_inc_get(struct mvneta_tx_queue *txq)
> +{
> +       txq->txq_get_index++;
> +       if (txq->txq_get_index == txq->size)
> +               txq->txq_get_index = 0;
> +}
> +
> +/* Increment txq put counter */
> +static void mvneta_txq_inc_put(struct mvneta_tx_queue *txq)
> +{
> +       txq->txq_put_index++;
> +       if (txq->txq_put_index == txq->size)
> +               txq->txq_put_index = 0;
> +}
> +
> +
> +/* Clear all MIB counters */
> +static void mvneta_mib_counters_clear(struct mvneta_port *pp)
> +{
> +       int i;
> +       u32 dummy;
> +
> +       /* Perform dummy reads from MIB counters */
> +       for (i = 0; i < MVNETA_MIB_LATE_COLLISION; i += 4)
> +               dummy = mvreg_read(pp, (MVNETA_MIB_COUNTERS_BASE + i));
> +}
> +
> +/* Get System Network Statistics */
> +struct rtnl_link_stats64 *mvneta_get_stats64(struct net_device *dev,
> +                                            struct rtnl_link_stats64 *stats)
> +{
> +       struct mvneta_port *pp = netdev_priv(dev);
> +       unsigned int start;
> +
> +       memset(stats, 0, sizeof(struct rtnl_link_stats64));
> +
> +       do {
> +               start = u64_stats_fetch_begin_bh(&pp->rx_stats.syncp);
> +               stats->rx_packets = pp->rx_stats.packets;
> +               stats->rx_bytes = pp->rx_stats.bytes;
> +       } while (u64_stats_fetch_retry_bh(&pp->rx_stats.syncp, start));
> +
> +
> +       do {
> +               start = u64_stats_fetch_begin_bh(&pp->tx_stats.syncp);
> +               stats->tx_packets = pp->tx_stats.packets;
> +               stats->tx_bytes = pp->tx_stats.bytes;
> +       } while (u64_stats_fetch_retry_bh(&pp->tx_stats.syncp, start));
> +
> +       stats->rx_errors        = dev->stats.rx_errors;
> +       stats->rx_dropped       = dev->stats.rx_dropped;
> +
> +       stats->tx_dropped       = dev->stats.tx_dropped;
> +
> +       return stats;
> +}
> +
> +/* Rx descriptors helper methods */
> +
> +/* Add number of descriptors ready to receive new packets */
> +static void mvneta_rxq_non_occup_desc_add(struct mvneta_port *pp,
> +                                         struct mvneta_rx_queue *rxq,
> +                                         int ndescs)
> +{
> +       /* Only MVNETA_RXQ_ADD_NON_OCCUPIED_MAX (255) descriptors can
> +        * be added at once */
> +       while (ndescs > MVNETA_RXQ_ADD_NON_OCCUPIED_MAX) {
> +               mvreg_write(pp, MVNETA_RXQ_STATUS_UPDATE_REG(rxq->id),
> +                           (MVNETA_RXQ_ADD_NON_OCCUPIED_MAX <<
> +                            MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT));
> +               ndescs -= MVNETA_RXQ_ADD_NON_OCCUPIED_MAX;
> +       }
> +
> +       mvreg_write(pp, MVNETA_RXQ_STATUS_UPDATE_REG(rxq->id),
> +                   (ndescs << MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT));
> +}
> +
> +/* Get number of RX descriptors occupied by received packets */
> +static int mvneta_rxq_busy_desc_num_get(struct mvneta_port *pp,
> +                                       struct mvneta_rx_queue *rxq)
> +{
> +       u32 val;
> +
> +       val = mvreg_read(pp, MVNETA_RXQ_STATUS_REG(rxq->id));
> +       return val & MVNETA_RXQ_OCCUPIED_ALL_MASK;
> +}
> +
> +/*
> + * Update num of rx desc called upon return from rx path or
> + * from mvneta_rxq_drop_pkts().
> + */
> +static void mvneta_rxq_desc_num_update(struct mvneta_port *pp,
> +                                      struct mvneta_rx_queue *rxq,
> +                                      int rx_done, int rx_filled)
> +{
> +       u32 val;
> +
> +       if ((rx_done <= 0xff) && (rx_filled <= 0xff)) {
> +               val = rx_done |
> +                 (rx_filled << MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT);
> +               mvreg_write(pp, MVNETA_RXQ_STATUS_UPDATE_REG(rxq->id), val);
> +               return;
> +       }
> +
> +       /* Only 255 descriptors can be added at once */
> +       while ((rx_done > 0) || (rx_filled > 0)) {
> +               if (rx_done <= 0xff) {
> +                       val = rx_done;
> +                       rx_done = 0;
> +               } else {
> +                       val = 0xff;
> +                       rx_done -= 0xff;
> +               }
> +               if (rx_filled <= 0xff) {
> +                       val |= rx_filled << MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT;
> +                       rx_filled = 0;
> +               } else {
> +                       val |= 0xff << MVNETA_RXQ_ADD_NON_OCCUPIED_SHIFT;
> +                       rx_filled -= 0xff;
> +               }
> +               mvreg_write(pp, MVNETA_RXQ_STATUS_UPDATE_REG(rxq->id), val);
> +       }
> +}
> +
> +/* Get pointer to next RX descriptor to be processed by SW */
> +static struct mvneta_rx_desc *
> +mvneta_rxq_next_desc_get(struct mvneta_rx_queue *rxq)
> +{
> +       int rx_desc = rxq->next_desc_to_proc;
> +       rxq->next_desc_to_proc = MVNETA_QUEUE_NEXT_DESC(rxq, rx_desc);
> +       return rxq->descs + rx_desc;
> +}
> +
> +/* Change maximum receive size of the port. */
> +static void mvneta_max_rx_size_set(struct mvneta_port *pp, int max_rx_size)
> +{
> +       u32 val;
> +
> +       val =  mvreg_read(pp, MVNETA_GMAC_CTRL_0);
> +       val &= ~MVNETA_GMAC_MAX_RX_SIZE_MASK;
> +       val |= ((max_rx_size - MVNETA_MH_SIZE) / 2) <<
> +               MVNETA_GMAC_MAX_RX_SIZE_SHIFT;
> +       mvreg_write(pp, MVNETA_GMAC_CTRL_0, val);
> +}
> +
> +
> +/* Set rx queue offset */
> +static void mvneta_rxq_offset_set(struct mvneta_port *pp,
> +                                 struct mvneta_rx_queue *rxq,
> +                                 int offset)
> +{
> +       u32 val;
> +
> +       val = mvreg_read(pp, MVNETA_RXQ_CONFIG_REG(rxq->id));
> +       val &= ~MVNETA_RXQ_PKT_OFFSET_ALL_MASK;
> +
> +       /* Offset is in */
> +       val |= MVNETA_RXQ_PKT_OFFSET_MASK(offset >> 3);
> +       mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val);
> +}
> +
> +
> +/* Tx descriptors helper methods */
> +
> +/* Update HW with number of TX descriptors to be sent */
> +static void mvneta_txq_pend_desc_add(struct mvneta_port *pp,
> +                                    struct mvneta_tx_queue *txq,
> +                                    int pend_desc)
> +{
> +       u32 val;
> +
> +       /* Only 255 descriptors can be added at once ; Assume caller
> +          process TX desriptors in quanta less than 256 */
> +       val = pend_desc;
> +       mvreg_write(pp, MVNETA_TXQ_UPDATE_REG(txq->id), val);
> +}
> +
> +/* Get pointer to next TX descriptor to be processed (send) by HW */
> +static struct mvneta_tx_desc *
> +mvneta_txq_next_desc_get(struct mvneta_tx_queue *txq)
> +{
> +       int tx_desc = txq->next_desc_to_proc;
> +       txq->next_desc_to_proc = MVNETA_QUEUE_NEXT_DESC(txq, tx_desc);
> +       return txq->descs + tx_desc;
> +}
> +
> +/* Release the last allocated TX descriptor. Useful to handle DMA
> + * mapping failures in the TX path. */
> +static void mvneta_txq_desc_put(struct mvneta_tx_queue *txq)
> +{
> +       if (txq->next_desc_to_proc == 0)
> +               txq->next_desc_to_proc = txq->last_desc - 1;
> +       else
> +               txq->next_desc_to_proc--;
> +}
> +
> +/* Set rxq buf size */
> +static void mvneta_rxq_buf_size_set(struct mvneta_port *pp,
> +                                   struct mvneta_rx_queue *rxq,
> +                                   int buf_size)
> +{
> +       u32 val;
> +
> +       val = mvreg_read(pp, MVNETA_RXQ_SIZE_REG(rxq->id));
> +
> +       val &= ~MVNETA_RXQ_BUF_SIZE_MASK;
> +       val |= ((buf_size >> 3) << MVNETA_RXQ_BUF_SIZE_SHIFT);
> +
> +       mvreg_write(pp, MVNETA_RXQ_SIZE_REG(rxq->id), val);
> +}
> +
> +/* Disable buffer management (BM) */
> +static void mvneta_rxq_bm_disable(struct mvneta_port *pp,
> +                                 struct mvneta_rx_queue *rxq)
> +{
> +       u32 val;
> +
> +       val = mvreg_read(pp, MVNETA_RXQ_CONFIG_REG(rxq->id));
> +       val &= ~MVNETA_RXQ_HW_BUF_ALLOC;
> +       mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val);
> +}
> +
> +
> +
> +/* Sets the RGMII Enable bit (RGMIIEn) in port MAC control register */
> +static void __devinit mvneta_gmac_rgmii_set(struct mvneta_port *pp, int enable)
> +{
> +       u32  val;
> +
> +       val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
> +
> +       if (enable)
> +               val |= MVNETA_GMAC2_PORT_RGMII;
> +       else
> +               val &= ~MVNETA_GMAC2_PORT_RGMII;
> +
> +       mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
> +}
> +
> +/* Config SGMII port */
> +static void __devinit mvneta_port_sgmii_config(struct mvneta_port *pp)
> +{
> +       u32 val;
> +
> +       val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
> +       val |= MVNETA_GMAC2_PSC_ENABLE;
> +       mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
> +}
> +
> +/* Start the Ethernet port RX and TX activity */
> +static void mvneta_port_up(struct mvneta_port *pp)
> +{
> +       int queue;
> +       u32 q_map;
> +
> +       /* Enable all initialized TXs. */
> +       mvneta_mib_counters_clear(pp);
> +       q_map = 0;
> +       for (queue = 0; queue < txq_number; queue++) {
> +               struct mvneta_tx_queue *txq = &pp->txqs[queue];
> +               if (txq->descs != NULL)
> +                       q_map |= (1 << queue);
> +       }
> +       mvreg_write(pp, MVNETA_TXQ_CMD, q_map);
> +
> +       /* Enable all initialized RXQs. */
> +       q_map = 0;
> +       for (queue = 0; queue < rxq_number; queue++) {
> +               struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
> +               if (rxq->descs != NULL)
> +                       q_map |= (1 << queue);
> +       }
> +
> +       mvreg_write(pp, MVNETA_RXQ_CMD, q_map);
> +}
> +
> +/* Stop the Ethernet port activity */
> +static void mvneta_port_down(struct mvneta_port *pp)
> +{
> +       u32 val;
> +       int count;
> +
> +       /* Stop Rx port activity. Check port Rx activity. */
> +       val = mvreg_read(pp, MVNETA_RXQ_CMD) & MVNETA_RXQ_ENABLE_MASK;
> +
> +       /* Issue stop command for active channels only */
> +       if (val != 0)
> +               mvreg_write(pp, MVNETA_RXQ_CMD,
> +                           val << MVNETA_RXQ_DISABLE_SHIFT);
> +
> +       /* Wait for all Rx activity to terminate. */
> +       count = 0;
> +       do {
> +               if (count++ >= MVNETA_RX_DISABLE_TIMEOUT_MSEC) {
> +                       netdev_warn(pp->dev,
> +                                   "TIMEOUT for RX stopped ! rx_queue_cmd: 0x08%x\n",
> +                                   val);
> +                       break;
> +               }
> +               mdelay(1);
> +
> +               val = mvreg_read(pp, MVNETA_RXQ_CMD);
> +       } while (val & 0xff);
> +
> +       /* Stop Tx port activity. Check port Tx activity. Issue stop
> +          command for active channels only  */
> +       val = (mvreg_read(pp, MVNETA_TXQ_CMD)) & MVNETA_TXQ_ENABLE_MASK;
> +
> +       if (val != 0)
> +               mvreg_write(pp, MVNETA_TXQ_CMD,
> +                           (val << MVNETA_TXQ_DISABLE_SHIFT));
> +
> +       /* Wait for all Tx activity to terminate. */
> +       count = 0;
> +       do {
> +               if (count++ >= MVNETA_TX_DISABLE_TIMEOUT_MSEC) {
> +                       netdev_warn(pp->dev,
> +                                   "TIMEOUT for TX stopped status=0x%08x\n",
> +                                   val);
> +                       break;
> +               }
> +               mdelay(1);
> +
> +               /* Check TX Command reg that all Txqs are stopped */
> +               val = mvreg_read(pp, MVNETA_TXQ_CMD);
> +
> +       } while (val & 0xff);
> +
> +       /* Double check to verify that TX FIFO is empty */
> +       count = 0;
> +       do {
> +               if (count++ >= MVNETA_TX_FIFO_EMPTY_TIMEOUT) {
> +                       netdev_warn(pp->dev,
> +                                   "TX FIFO empty timeout status=0x08%x", val);
> +                       break;
> +               }
> +               mdelay(1);
> +
> +               val = mvreg_read(pp, MVNETA_PORT_STATUS);
> +       } while (!(val & MVNETA_TX_FIFO_EMPTY) &&
> +                (val & MVNETA_TX_IN_PRGRS));
> +
> +       udelay(200);
> +}
> +
> +/* Enable the port by setting the port enable bit of the MAC control register */
> +static void mvneta_port_enable(struct mvneta_port *pp)
> +{
> +       u32 val;
> +
> +       /* Enable port */
> +       val = mvreg_read(pp, MVNETA_GMAC_CTRL_0);
> +       val |= MVNETA_GMAC0_PORT_ENABLE;
> +       mvreg_write(pp, MVNETA_GMAC_CTRL_0, val);
> +}
> +
> +/* Disable the port and wait for about 200 usec before retuning */
> +static void mvneta_port_disable(struct mvneta_port *pp)
> +{
> +       u32 val;
> +
> +       /* Reset the Enable bit in the Serial Control Register */
> +       val = mvreg_read(pp, MVNETA_GMAC_CTRL_0);
> +       val &= ~MVNETA_GMAC0_PORT_ENABLE;
> +       mvreg_write(pp, MVNETA_GMAC_CTRL_0, val);
> +
> +       udelay(200);
> +}
> +
> +/* Multicast tables methods */
> +
> +/* Set all entries in Unicast MAC Table; queue==-1 means reject all */
> +static void mvneta_set_ucast_table(struct mvneta_port *pp, int queue)
> +{
> +       int offset;
> +       u32 val;
> +
> +       if (queue == -1) {
> +               val = 0;
> +       } else {
> +               val = 0x1 | (queue << 1);
> +               val |= (val << 24) | (val << 16) | (val << 8);
> +       }
> +
> +       for (offset = 0; offset <= 0xc; offset += 4)
> +               mvreg_write(pp, MVNETA_DA_FILT_UCAST_BASE + offset, val);
> +}
> +
> +/* Set all entries in Special Multicast MAC Table; queue==-1 means reject all */
> +static void mvneta_set_special_mcast_table(struct mvneta_port *pp, int queue)
> +{
> +       int offset;
> +       u32 val;
> +
> +       if (queue == -1) {
> +               val = 0;
> +       } else {
> +               val = 0x1 | (queue << 1);
> +               val |= (val << 24) | (val << 16) | (val << 8);
> +       }
> +
> +       for (offset = 0; offset <= 0xfc; offset += 4)
> +               mvreg_write(pp, MVNETA_DA_FILT_SPEC_MCAST + offset, val);
> +
> +}
> +
> +/* Set all entries in Other Multicast MAC Table. queue==-1 means reject all */
> +static void mvneta_set_other_mcast_table(struct mvneta_port *pp, int queue)
> +{
> +       int offset;
> +       u32 val;
> +
> +       if (queue == -1) {
> +               memset(pp->mcast_count, 0, sizeof(pp->mcast_count));
> +               val = 0;
> +       } else {
> +               memset(pp->mcast_count, 1, sizeof(pp->mcast_count));
> +               val = 0x1 | (queue << 1);
> +               val |= (val << 24) | (val << 16) | (val << 8);
> +       }
> +
> +       for (offset = 0; offset <= 0xfc; offset += 4)
> +               mvreg_write(pp, MVNETA_DA_FILT_OTH_MCAST + offset, val);
> +}
> +
> +/* This method sets defaults to the NETA port:
> + *     Clears interrupt Cause and Mask registers.
> + *     Clears all MAC tables.
> + *     Sets defaults to all registers.
> + *     Resets RX and TX descriptor rings.
> + *     Resets PHY.
> + * This method can be called after mvneta_port_down() to return the port
> + *     settings to defaults.
> + */
> +static void mvneta_defaults_set(struct mvneta_port *pp)
> +{
> +       int cpu;
> +       int queue;
> +       u32 val;
> +
> +       /* Clear all Cause registers */
> +       mvreg_write(pp, MVNETA_INTR_NEW_CAUSE, 0);
> +       mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0);
> +       mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
> +
> +       /* Mask all interrupts */
> +       mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
> +       mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
> +       mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
> +       mvreg_write(pp, MVNETA_INTR_ENABLE, 0);
> +
> +       /* Enable MBUS Retry bit16 */
> +       mvreg_write(pp, MVNETA_MBUS_RETRY, 0x20);
> +
> +       /* Set CPU queue access map - all CPUs have access to all RX
> +          queues and to all TX queues */
> +       for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++)
> +               mvreg_write(pp, MVNETA_CPU_MAP(cpu),
> +                           (MVNETA_CPU_RXQ_ACCESS_ALL_MASK |
> +                            MVNETA_CPU_TXQ_ACCESS_ALL_MASK));
> +
> +       /* Reset RX and TX DMAs */
> +       mvreg_write(pp, MVNETA_PORT_RX_RESET, MVNETA_PORT_RX_DMA_RESET);
> +       mvreg_write(pp, MVNETA_PORT_TX_RESET, MVNETA_PORT_TX_DMA_RESET);
> +
> +       /* Disable Legacy WRR, Disable EJP, Release from reset */
> +       mvreg_write(pp, MVNETA_TXQ_CMD_1, 0);
> +       for (queue = 0; queue < txq_number; queue++) {
> +               mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(queue), 0);
> +               mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(queue), 0);
> +       }
> +
> +       mvreg_write(pp, MVNETA_PORT_TX_RESET, 0);
> +       mvreg_write(pp, MVNETA_PORT_RX_RESET, 0);
> +
> +       /* Set Port Acceleration Mode */
> +       val = MVNETA_ACC_MODE_EXT;
> +       mvreg_write(pp, MVNETA_ACC_MODE, val);
> +
> +       /* Update val of portCfg register accordingly with all RxQueue types */
> +       val = MVNETA_PORT_CONFIG_DEFL_VALUE(rxq_def);
> +       mvreg_write(pp, MVNETA_PORT_CONFIG, val);
> +
> +       val = 0;
> +       mvreg_write(pp, MVNETA_PORT_CONFIG_EXTEND, val);
> +       mvreg_write(pp, MVNETA_RX_MIN_FRAME_SIZE, 64);
> +
> +       /* Build PORT_SDMA_CONFIG_REG */
> +       val = 0;
> +
> +       /* Default burst size */
> +       val |= MVNETA_TX_BRST_SZ_MASK(MVNETA_SDMA_BRST_SIZE_16);
> +       val |= MVNETA_RX_BRST_SZ_MASK(MVNETA_SDMA_BRST_SIZE_16);
> +
> +       val |= (MVNETA_RX_NO_DATA_SWAP | MVNETA_TX_NO_DATA_SWAP |
> +               MVNETA_NO_DESC_SWAP);
> +
> +       /* Assign port SDMA configuration */
> +       mvreg_write(pp, MVNETA_SDMA_CONFIG, val);
> +
> +       mvneta_set_ucast_table(pp, -1);
> +       mvneta_set_special_mcast_table(pp, -1);
> +       mvneta_set_other_mcast_table(pp, -1);
> +
> +       /* Set port interrupt enable register - default enable all */
> +       mvreg_write(pp, MVNETA_INTR_ENABLE,
> +                   (MVNETA_RXQ_INTR_ENABLE_ALL_MASK
> +                    | MVNETA_TXQ_INTR_ENABLE_ALL_MASK));
> +}
> +
> +/* Set max sizes for tx queues */
> +static void mvneta_txq_max_tx_size_set(struct mvneta_port *pp, int max_tx_size)
> +
> +{
> +       u32 val, size, mtu;
> +       int queue;
> +
> +       mtu = max_tx_size * 8;
> +       if (mtu > MVNETA_TX_MTU_MAX)
> +               mtu = MVNETA_TX_MTU_MAX;
> +
> +       /* Set MTU */
> +       val = mvreg_read(pp, MVNETA_TX_MTU);
> +       val &= ~MVNETA_TX_MTU_MAX;
> +       val |= mtu;
> +       mvreg_write(pp, MVNETA_TX_MTU, val);
> +
> +       /* TX token size and all TXQs token size must be larger that MTU */
> +       val = mvreg_read(pp, MVNETA_TX_TOKEN_SIZE);
> +
> +       size = val & MVNETA_TX_TOKEN_SIZE_MAX;
> +       if (size < mtu) {
> +               size = mtu;
> +               val &= ~MVNETA_TX_TOKEN_SIZE_MAX;
> +               val |= size;
> +               mvreg_write(pp, MVNETA_TX_TOKEN_SIZE, val);
> +       }
> +       for (queue = 0; queue < txq_number; queue++) {
> +               val = mvreg_read(pp, MVNETA_TXQ_TOKEN_SIZE_REG(queue));
> +
> +               size = val & MVNETA_TXQ_TOKEN_SIZE_MAX;
> +               if (size < mtu) {
> +                       size = mtu;
> +                       val &= ~MVNETA_TXQ_TOKEN_SIZE_MAX;
> +                       val |= size;
> +                       mvreg_write(pp, MVNETA_TXQ_TOKEN_SIZE_REG(queue), val);
> +               }
> +       }
> +}
> +
> +/* Set unicast address */
> +static int mvneta_set_ucast_addr(struct mvneta_port *pp, u8 last_nibble,
> +                               int queue)
> +{
> +       unsigned int unicast_reg;
> +       unsigned int tbl_offset;
> +       unsigned int reg_offset;
> +
> +       /* Locate the Unicast table entry */
> +       last_nibble = (0xf & last_nibble);
> +
> +       /* offset from unicast tbl base */
> +       tbl_offset = (last_nibble / 4) * 4;
> +
> +       /* offset within the above reg  */
> +       reg_offset = last_nibble % 4;
> +
> +       unicast_reg = mvreg_read(pp, (MVNETA_DA_FILT_UCAST_BASE + tbl_offset));
> +
> +       if (queue == -1) {
> +               /* Clear accepts frame bit at specified unicast DA tbl entry */
> +               unicast_reg &= ~(0xff << (8 * reg_offset));
> +       } else {
> +               unicast_reg &= ~(0xff << (8 * reg_offset));
> +               unicast_reg |= ((0x01 | (queue << 1)) << (8 * reg_offset));
> +       }
> +
> +       mvreg_write(pp, (MVNETA_DA_FILT_UCAST_BASE + tbl_offset), unicast_reg);
> +       return 1;
> +}
> +
> +/* Set mac address */
> +static int mvneta_mac_addr_set(struct mvneta_port *pp, unsigned char *addr,
> +                              int queue)
> +{
> +       unsigned int mac_h;
> +       unsigned int mac_l;
> +
> +       if (queue >= 1) {
> +               netdev_err(pp->dev, "RX queue #%d is out of range\n", queue);
> +               return -EINVAL;
> +       }
> +
> +       if (queue != -1) {
> +               mac_l = (addr[4] << 8) | (addr[5]);
> +               mac_h = (addr[0] << 24) | (addr[1] << 16) |
> +                       (addr[2] << 8) | (addr[3] << 0);
> +
> +               mvreg_write(pp, MVNETA_MAC_ADDR_LOW, mac_l);
> +               mvreg_write(pp, MVNETA_MAC_ADDR_HIGH, mac_h);
> +       }
> +
> +       /* Accept frames of this address */
> +       mvneta_set_ucast_addr(pp, addr[5], queue);
> +
> +       return 0;
> +}
> +
> +/* Mask interrupts */
> +static void mvneta_interrupts_mask(void *priv)
> +{
> +       struct mvneta_port *pp = priv;
> +
> +       /* Mask all ethernet port interrupts */
> +       mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
> +       mvreg_write(pp, MVNETA_INTR_OLD_MASK, 0);
> +       mvreg_write(pp, MVNETA_INTR_MISC_MASK, 0);
> +}
> +
> +/* Unmask interrupts */
> +static void mvneta_interrupts_unmask(void *priv)
> +{
> +       struct mvneta_port *pp = priv;
> +
> +       mvreg_write(pp, MVNETA_INTR_NEW_MASK,
> +                   MVNETA_RX_INTR_MASK(rxq_number));
> +}
> +
> +/*
> + * Set the number of packets that will be received before
> + * RX interrupt will be generated by HW.
> + */
> +static void mvneta_rx_pkts_coal_set(struct mvneta_port *pp,
> +                                   struct mvneta_rx_queue *rxq, u32 value)
> +{
> +       mvreg_write(pp, MVNETA_RXQ_THRESHOLD_REG(rxq->id),
> +                   value | MVNETA_RXQ_NON_OCCUPIED(0));
> +       rxq->pkts_coal = value;
> +}
> +
> +/*
> + * Set the time delay in usec before
> + * RX interrupt will be generated by HW.
> + */
> +static void mvneta_rx_time_coal_set(struct mvneta_port *pp,
> +                                   struct mvneta_rx_queue *rxq, u32 value)
> +{
> +       u32 val = (pp->clk_rate_hz / 1000000) * value;
> +
> +       mvreg_write(pp, MVNETA_RXQ_TIME_COAL_REG(rxq->id), val);
> +       rxq->time_coal = value;
> +}
> +
> +/* Set threshold for TX_DONE pkts coalescing */
> +static void mvneta_tx_done_pkts_coal_set(struct mvneta_port *pp,
> +                                        struct mvneta_tx_queue *txq, u32 value)
> +{
> +       u32 val;
> +
> +       val = mvreg_read(pp, MVNETA_TXQ_SIZE_REG(txq->id));
> +
> +       val &= ~MVNETA_TXQ_SENT_THRESH_ALL_MASK;
> +       val |= MVNETA_TXQ_SENT_THRESH_MASK(value);
> +
> +       mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), val);
> +
> +       txq->done_pkts_coal = value;
> +}
> +
> +/* Trigger tx done timer in MVNETA_TX_DONE_TIMER_PERIOD msecs */
> +static void mvneta_add_tx_done_timer(struct mvneta_port *pp)
> +{
> +       if (test_and_set_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags) == 0) {
> +               pp->tx_done_timer.expires = jiffies +
> +                       msecs_to_jiffies(MVNETA_TX_DONE_TIMER_PERIOD);
> +               add_timer(&pp->tx_done_timer);
> +       }
> +}
> +
> +
> +/* Handle rx descriptor fill by setting buf_cookie and buf_phys_addr */
> +static void mvneta_rx_desc_fill(struct mvneta_rx_desc *rx_desc,
> +                               u32 phys_addr, u32 cookie)
> +{
> +       rx_desc->buf_cookie = cookie;
> +       rx_desc->buf_phys_addr = phys_addr;
> +}
> +
> +/* Decrement sent descriptors counter */
> +static void mvneta_txq_sent_desc_dec(struct mvneta_port *pp,
> +                                    struct mvneta_tx_queue *txq,
> +                                    int sent_desc)
> +{
> +       u32 val;
> +
> +       /* Only 255 TX descriptors can be updated at once */
> +       while (sent_desc > 0xff) {
> +               val = 0xff << MVNETA_TXQ_DEC_SENT_SHIFT;
> +               mvreg_write(pp, MVNETA_TXQ_UPDATE_REG(txq->id), val);
> +               sent_desc = sent_desc - 0xff;
> +       }
> +
> +       val = sent_desc << MVNETA_TXQ_DEC_SENT_SHIFT;
> +       mvreg_write(pp, MVNETA_TXQ_UPDATE_REG(txq->id), val);
> +}
> +
> +/* Get number of TX descriptors already sent by HW */
> +static int mvneta_txq_sent_desc_num_get(struct mvneta_port *pp,
> +                                       struct mvneta_tx_queue *txq)
> +{
> +       u32 val;
> +       int sent_desc;
> +
> +       val = mvreg_read(pp, MVNETA_TXQ_STATUS_REG(txq->id));
> +       sent_desc = (val & MVNETA_TXQ_SENT_DESC_MASK) >>
> +               MVNETA_TXQ_SENT_DESC_SHIFT;
> +
> +       return sent_desc;
> +}
> +
> +/*
> + * Get number of sent descriptors and decrement counter.
> + *  The number of sent descriptors is returned.
> + */
> +static int mvneta_txq_sent_desc_proc(struct mvneta_port *pp,
> +                                    struct mvneta_tx_queue *txq)
> +{
> +       int sent_desc;
> +
> +       /* Get number of sent descriptors */
> +       sent_desc = mvneta_txq_sent_desc_num_get(pp, txq);
> +
> +       /* Decrement sent descriptors counter */
> +       if (sent_desc)
> +               mvneta_txq_sent_desc_dec(pp, txq, sent_desc);
> +
> +       return sent_desc;
> +}
> +
> +/* Set TXQ descriptors fields relevant for CSUM calculation */
> +static u32 mvneta_txq_desc_csum(int l3_offs, int l3_proto,
> +                               int ip_hdr_len, int l4_proto)
> +{
> +       u32 command;
> +
> +       /* Fields: L3_offset, IP_hdrlen, L3_type, G_IPv4_chk,
> +          G_L4_chk, L4_type; required only for checksum
> +          calculation */
> +       command =  l3_offs    << MVNETA_TX_L3_OFF_SHIFT;
> +       command |= ip_hdr_len << MVNETA_TX_IP_HLEN_SHIFT;
> +
> +       if (l3_proto == swab16(ETH_P_IP))
> +               command |= MVNETA_TXD_IP_CSUM;
> +       else
> +               command |= MVNETA_TX_L3_IP6;
> +
> +       if (l4_proto == IPPROTO_TCP)
> +               command |=  MVNETA_TX_L4_CSUM_FULL;
> +       else if (l4_proto == IPPROTO_UDP)
> +               command |= MVNETA_TX_L4_UDP | MVNETA_TX_L4_CSUM_FULL;
> +       else
> +               command |= MVNETA_TX_L4_CSUM_NOT;
> +
> +       return command;
> +}
> +
> +
> +/* Display more error info */
> +static void mvneta_rx_error(struct mvneta_port *pp,
> +                           struct mvneta_rx_desc *rx_desc)
> +{
> +       u32 status = rx_desc->status;
> +
> +       if ((status & MVNETA_RXD_FIRST_LAST_DESC)
> +           != MVNETA_RXD_FIRST_LAST_DESC) {
> +               netdev_err(pp->dev,
> +                          "bad rx status %08x (buffer oversize), size=%d\n",
> +                          rx_desc->status, rx_desc->data_size);
> +               return;
> +       }
> +
> +       switch (status & MVNETA_RXD_ERR_CODE_MASK) {
> +       case MVNETA_RXD_ERR_CRC:
> +               netdev_err(pp->dev, "bad rx status %08x (crc error), size=%d\n",
> +                          status, rx_desc->data_size);
> +               break;
> +       case MVNETA_RXD_ERR_OVERRUN:
> +               netdev_err(pp->dev, "bad rx status %08x (overrun error), size=%d\n",
> +                          status, rx_desc->data_size);
> +               break;
> +       case MVNETA_RXD_ERR_LEN:
> +               netdev_err(pp->dev, "bad rx status %08x (max frame length error), size=%d\n",
> +                          status, rx_desc->data_size);
> +               break;
> +       case MVNETA_RXD_ERR_RESOURCE:
> +               netdev_err(pp->dev, "bad rx status %08x (resource error), size=%d\n",
> +                          status, rx_desc->data_size);
> +               break;
> +       }
> +}
> +
> +/* Handle RX checksum offload */
> +static void mvneta_rx_csum(struct mvneta_port *pp,
> +                          struct mvneta_rx_desc *rx_desc,
> +                          struct sk_buff *skb)
> +{
> +       if ((rx_desc->status & MVNETA_RXD_L3_IP4) &&
> +           (rx_desc->status & MVNETA_RXD_L4_CSUM_OK)) {
> +               skb->csum = 0;
> +               skb->ip_summed = CHECKSUM_UNNECESSARY;
> +               return;
> +       }
> +
> +       skb->ip_summed = CHECKSUM_NONE;
> +}
> +
> +/* Return tx queue pointer (find last set bit) according to causeTxDone reg */
> +static struct mvneta_tx_queue *mvneta_tx_done_policy(struct mvneta_port *pp,
> +                                                    u32 cause)
> +{
> +       int queue;
> +       queue = fls(cause) - 1;
> +       if (queue < 0 || queue >= txq_number)
> +               return NULL;
> +       return &pp->txqs[queue];
> +}
> +
> +/* Free tx queue skbuffs */
> +static void mvneta_txq_bufs_free(struct mvneta_port *pp,
> +                                struct mvneta_tx_queue *txq, int num)
> +{
> +       int i;
> +
> +       for (i = 0; i < num; i++) {
> +               struct mvneta_tx_desc *tx_desc = txq->descs +
> +                       txq->txq_get_index;
> +               struct sk_buff *skb = txq->tx_skb[txq->txq_get_index];
> +
> +               mvneta_txq_inc_get(txq);
> +
> +               if (!skb)
> +                       continue;
> +
> +               dma_unmap_single(pp->dev->dev.parent, tx_desc->buf_phys_addr,
> +                                tx_desc->data_size, DMA_TO_DEVICE);
> +               dev_kfree_skb_any(skb);
> +       }
> +}
> +
> +/* Handle end of transmission */
> +static int mvneta_txq_done(struct mvneta_port *pp,
> +                          struct mvneta_tx_queue *txq)
> +{
> +       struct netdev_queue *nq = netdev_get_tx_queue(pp->dev, txq->id);
> +       int tx_done;
> +
> +       tx_done = mvneta_txq_sent_desc_proc(pp, txq);
> +       if (tx_done == 0)
> +               return tx_done;
> +       mvneta_txq_bufs_free(pp, txq, tx_done);
> +
> +       txq->count -= tx_done;
> +
> +       if (netif_tx_queue_stopped(nq)) {
> +               if (txq->size - txq->count >= MAX_SKB_FRAGS + 1)
> +                       netif_tx_wake_queue(nq);
> +       }
> +
> +       return tx_done;
> +}
> +
> +/* Refill processing */
> +static int mvneta_rx_refill(struct mvneta_port *pp,
> +                           struct mvneta_rx_desc *rx_desc)
> +
> +{
> +       dma_addr_t phys_addr;
> +       struct sk_buff *skb;
> +
> +       skb = netdev_alloc_skb(pp->dev, pp->pkt_size);
> +       if (!skb)
> +               return 1;
> +
> +       phys_addr = dma_map_single(pp->dev->dev.parent, skb->head,
> +                                  MVNETA_RX_BUF_SIZE(pp->pkt_size),
> +                                  DMA_FROM_DEVICE);
> +       if (unlikely(dma_mapping_error(pp->dev->dev.parent,
> +                                      phys_addr))) {
> +               dev_kfree_skb(skb);
> +               return 1;
> +       }
> +
> +       mvneta_rx_desc_fill(rx_desc, phys_addr, (u32)skb);
> +
> +       return 0;
> +}
> +
> +/* Handle tx checksum */
> +static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb)
> +{
> +       if (skb->ip_summed == CHECKSUM_PARTIAL) {
> +               int ip_hdr_len = 0;
> +               u8 l4_proto;
> +
> +               if (skb->protocol == htons(ETH_P_IP)) {
> +                       struct iphdr *ip4h = ip_hdr(skb);
> +
> +                       /* Calculate IPv4 checksum and L4 checksum */
> +                       ip_hdr_len = ip4h->ihl;
> +                       l4_proto = ip4h->protocol;
> +               } else if (skb->protocol == htons(ETH_P_IPV6)) {
> +                       struct ipv6hdr *ip6h = ipv6_hdr(skb);
> +
> +                       /* Read l4_protocol from one of IPv6 extra headers */
> +                       if (skb_network_header_len(skb) > 0)
> +                               ip_hdr_len = (skb_network_header_len(skb) >> 2);
> +                       l4_proto = ip6h->nexthdr;
> +               } else
> +                       return MVNETA_TX_L4_CSUM_NOT;
> +
> +               return mvneta_txq_desc_csum(skb_network_offset(skb),
> +                               skb->protocol, ip_hdr_len, l4_proto);
> +       }
> +
> +       return MVNETA_TX_L4_CSUM_NOT;
> +}
> +
> +/*
> + * Returns rx queue pointer (find last set bit) according to causeRxTx
> + * value
> + */
> +static struct mvneta_rx_queue *mvneta_rx_policy(struct mvneta_port *pp,
> +                                               u32 cause)
> +{
> +       int queue = fls(cause >> 8) - 1;
> +       if (queue < 0 || queue >= rxq_number)
> +               return NULL;
> +       return &pp->rxqs[queue];
> +}
> +
> +/* Drop packets received by the RXQ and free buffers */
> +static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
> +                                struct mvneta_rx_queue *rxq)
> +{
> +       int rx_done, i;
> +
> +       rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq);
> +       for (i = 0; i < rxq->size; i++) {
> +               struct mvneta_rx_desc *rx_desc = rxq->descs + i;
> +               struct sk_buff *skb = (struct sk_buff *)rx_desc->buf_cookie;
> +               dev_kfree_skb_any(skb);
> +               dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
> +                                rx_desc->data_size, DMA_FROM_DEVICE);
> +       }
> +
> +       if (rx_done)
> +               mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done);
> +}
> +
> +/* Main rx processing */
> +static int mvneta_rx(struct mvneta_port *pp, int rx_todo,
> +                    struct mvneta_rx_queue *rxq)
> +{
> +       struct net_device *dev = pp->dev;
> +       int rx_done, rx_filled;
> +
> +       /* Get number of received packets */
> +       rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq);
> +
> +       if (rx_todo > rx_done)
> +               rx_todo = rx_done;
> +
> +       rx_done = 0;
> +       rx_filled = 0;
> +
> +       /* Fairness NAPI loop */
> +       while (rx_done < rx_todo) {
> +               struct mvneta_rx_desc *rx_desc = mvneta_rxq_next_desc_get(rxq);
> +               struct sk_buff *skb;
> +               u32 rx_status;
> +               int rx_bytes, err;
> +
> +               prefetch(rx_desc);
> +               rx_done++;
> +               rx_filled++;
> +               rx_status = rx_desc->status;
> +               skb = (struct sk_buff *)rx_desc->buf_cookie;
> +
> +               if (((rx_status & MVNETA_RXD_FIRST_LAST_DESC)
> +                    != MVNETA_RXD_FIRST_LAST_DESC)
> +                   || (rx_status & MVNETA_RXD_ERR_SUMMARY)) {
> +                       dev->stats.rx_errors++;
> +                       mvneta_rx_error(pp, rx_desc);
> +                       mvneta_rx_desc_fill(rx_desc, rx_desc->buf_phys_addr,
> +                                           (u32)skb);
> +                       continue;
> +               }
> +
> +               dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
> +                                rx_desc->data_size, DMA_FROM_DEVICE);
> +
> +               rx_bytes = rx_desc->data_size -
> +                       (MVNETA_ETH_CRC_SIZE + MVNETA_MH_SIZE);
> +               u64_stats_update_begin(&pp->rx_stats.syncp);
> +               pp->rx_stats.packets++;
> +               pp->rx_stats.bytes += rx_bytes;
> +               u64_stats_update_end(&pp->rx_stats.syncp);
> +
> +               /* Linux processing */
> +               skb_reserve(skb, MVNETA_MH_SIZE);
> +               skb_put(skb, rx_bytes);
> +
> +               skb->protocol = eth_type_trans(skb, dev);
> +
> +               mvneta_rx_csum(pp, rx_desc, skb);
> +
> +               napi_gro_receive(&pp->napi, skb);
> +
> +               /* Refill processing */
> +               err = mvneta_rx_refill(pp, rx_desc);
> +               if (err) {
> +                       netdev_err(pp->dev, "Linux processing - Can't refill\n");
> +                       rxq->missed++;
> +                       rx_filled--;
> +               }
> +       }
> +
> +       /* Update rxq management counters */
> +       mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_filled);
> +
> +       return rx_done;
> +}
> +
> +/* Handle tx fragmentation processing */
> +static int mvneta_tx_frag_process(struct mvneta_port *pp, struct sk_buff *skb,
> +                                 struct mvneta_tx_queue *txq)
> +{
> +       struct mvneta_tx_desc *tx_desc;
> +       int i, j;
> +
> +       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
> +               skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
> +               void *addr = page_address(frag->page.p) + frag->page_offset;
> +
> +               tx_desc = mvneta_txq_next_desc_get(txq);
> +               tx_desc->data_size = frag->size;
> +
> +               tx_desc->buf_phys_addr =
> +                       dma_map_single(pp->dev->dev.parent, addr,
> +                                      tx_desc->data_size, DMA_TO_DEVICE);
> +
> +               if (dma_mapping_error(pp->dev->dev.parent,
> +                                     tx_desc->buf_phys_addr)) {
> +                       mvneta_txq_desc_put(txq);
> +                       goto error;
> +               }
> +
> +               if (i == (skb_shinfo(skb)->nr_frags - 1)) {
> +                       /* Last descriptor */
> +                       tx_desc->command = (MVNETA_TXD_L_DESC |
> +                                           MVNETA_TXD_Z_PAD);
> +
> +                       txq->tx_skb[txq->txq_put_index] = skb;
> +
> +                       mvneta_txq_inc_put(txq);
> +               } else {
> +                       /* Descriptor in the middle: Not First, Not Last */
> +                       tx_desc->command = 0;
> +
> +                       txq->tx_skb[txq->txq_put_index] = NULL;
> +                       mvneta_txq_inc_put(txq);
> +               }
> +       }
> +
> +       return 0;
> +
> +error:
> +       /* Release all descriptors that were used to map fragments of
> +        * this packet, as well as the corresponding DMA mappings */
> +       for (j = i - 1; j >= 0; j--) {
> +               tx_desc = txq->descs + j;
> +               dma_unmap_single(pp->dev->dev.parent,
> +                                tx_desc->buf_phys_addr,
> +                                tx_desc->data_size,
> +                                DMA_TO_DEVICE);
> +               mvneta_txq_desc_put(txq);
> +       }
> +
> +       return -ENOMEM;
> +}
> +
> +/* Main tx processing */
> +static int mvneta_tx(struct sk_buff *skb, struct net_device *dev)
> +{
> +       struct mvneta_port *pp = netdev_priv(dev);
> +       struct mvneta_tx_queue *txq = &pp->txqs[txq_def];
> +       struct netdev_queue *nq;
> +       struct mvneta_tx_desc *tx_desc;
> +       int frags = 0;
> +       u32 tx_cmd;
> +
> +       if (!netif_running(dev))
> +               goto out;
> +
> +       frags = skb_shinfo(skb)->nr_frags + 1;
> +       nq    = netdev_get_tx_queue(dev, txq_def);
> +
> +       /* Get a descriptor for the first part of the packet */
> +       tx_desc = mvneta_txq_next_desc_get(txq);
> +
> +       tx_cmd = mvneta_skb_tx_csum(pp, skb);
> +
> +       tx_desc->data_size = skb_headlen(skb);
> +
> +       tx_desc->buf_phys_addr = dma_map_single(dev->dev.parent, skb->data,
> +                                               tx_desc->data_size,
> +                                               DMA_TO_DEVICE);
> +       if (unlikely(dma_mapping_error(dev->dev.parent,
> +                                      tx_desc->buf_phys_addr))) {
> +               mvneta_txq_desc_put(txq);
> +               frags = 0;
> +               goto out;
> +       }
> +
> +       if (frags == 1) {
> +               /* First and Last descriptor */
> +               tx_cmd |= MVNETA_TXD_FLZ_DESC;
> +               tx_desc->command = tx_cmd;
> +               txq->tx_skb[txq->txq_put_index] = skb;
> +               mvneta_txq_inc_put(txq);
> +       } else {
> +               /* First but not Last */
> +               tx_cmd |= MVNETA_TXD_F_DESC;
> +               txq->tx_skb[txq->txq_put_index] = NULL;
> +               mvneta_txq_inc_put(txq);
> +               tx_desc->command = tx_cmd;
> +               /* Continue with other skb fragments */
> +               if (mvneta_tx_frag_process(pp, skb, txq)) {
> +                       dma_unmap_single(dev->dev.parent,
> +                                        tx_desc->buf_phys_addr,
> +                                        tx_desc->data_size,
> +                                        DMA_TO_DEVICE);
> +                       mvneta_txq_desc_put(txq);
> +                       frags = 0;
> +                       goto out;
> +               }
> +       }
> +
> +       txq->count += frags;
> +       mvneta_txq_pend_desc_add(pp, txq, frags);
> +
> +       if (txq->size - txq->count < MAX_SKB_FRAGS + 1)
> +               netif_tx_stop_queue(nq);
> +
> +out:
> +       if (frags > 0) {
> +               u64_stats_update_begin(&pp->tx_stats.syncp);
> +               pp->tx_stats.packets++;
> +               pp->tx_stats.bytes += skb->len;
> +               u64_stats_update_end(&pp->tx_stats.syncp);
> +
> +       } else {
> +               dev->stats.tx_dropped++;
> +               dev_kfree_skb_any(skb);
> +       }
> +
> +       if (txq->count >= MVNETA_TXDONE_COAL_PKTS)
> +               mvneta_txq_done(pp, txq);
> +
> +       /* If after calling mvneta_txq_done, count equals
> +               frags, we need to set the timer */
> +       if (txq->count == frags && frags > 0)
> +               mvneta_add_tx_done_timer(pp);
> +
> +       return NETDEV_TX_OK;
> +}
> +
> +
> +/* Free tx resources, when resetting a port */
> +static void mvneta_txq_done_force(struct mvneta_port *pp,
> +                                 struct mvneta_tx_queue *txq)
> +
> +{
> +       int tx_done = txq->count;
> +       mvneta_txq_bufs_free(pp, txq, tx_done);
> +
> +       /* reset txq */
> +       txq->count = 0;
> +       txq->txq_put_index = 0;
> +       txq->txq_get_index = 0;
> +}
> +
> +/* handle tx done - called from tx done timer callback */
> +static u32 mvneta_tx_done_gbe(struct mvneta_port *pp, u32 cause_tx_done,
> +                             int *tx_todo)
> +{
> +       struct mvneta_tx_queue *txq;
> +       u32 tx_done = 0;
> +       struct netdev_queue *nq;
> +
> +       *tx_todo = 0;
> +       while (cause_tx_done != 0) {
> +               txq = mvneta_tx_done_policy(pp, cause_tx_done);
> +               if (!txq)
> +                       break;
> +
> +               nq = netdev_get_tx_queue(pp->dev, txq->id);
> +               __netif_tx_lock(nq, smp_processor_id());
> +
> +               if (txq->count) {
> +                       tx_done += mvneta_txq_done(pp, txq);
> +                       *tx_todo += txq->count;
> +               }
> +
> +               __netif_tx_unlock(nq);
> +               cause_tx_done &= ~((1 << txq->id));
> +       }
> +
> +       return tx_done;
> +}
> +
> +/*
> + * Compute crc8 of the specified address, using a unique algorithm ,
> + * according to hw spec, different than generic crc8 algorithm
> + */
> +static int mvneta_addr_crc(unsigned char *addr)
> +{
> +       int crc = 0;
> +       int i;
> +
> +       for (i = 0; i < ETH_ALEN; i++) {
> +               int j;
> +
> +               crc = (crc ^ addr[i]) << 8;
> +               for (j = 7; j >= 0; j--) {
> +                       if (crc & (0x100 << j))
> +                               crc ^= 0x107 << j;
> +               }
> +       }
> +
> +       return crc;
> +}
> +
> +/* This method controls the net device special MAC multicast support.
> + * The Special Multicast Table for MAC addresses supports MAC of the form
> + * 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
> + * The MAC DA[7:0] bits are used as a pointer to the Special Multicast
> + * Table entries in the DA-Filter table. This method set the Special
> + * Multicast Table appropriate entry.
> + */
> +static void mvneta_set_special_mcast_addr(struct mvneta_port *pp,
> +                                         unsigned char last_byte,
> +                                         int queue)
> +{
> +       unsigned int smc_table_reg;
> +       unsigned int tbl_offset;
> +       unsigned int reg_offset;
> +
> +       /* Register offset from SMC table base    */
> +       tbl_offset = (last_byte / 4);
> +       /* Entry offset within the above reg */
> +       reg_offset = last_byte % 4;
> +
> +       smc_table_reg = mvreg_read(pp, (MVNETA_DA_FILT_SPEC_MCAST
> +                                       + tbl_offset * 4));
> +
> +       if (queue == -1)
> +               smc_table_reg &= ~(0xff << (8 * reg_offset));
> +       else {
> +               smc_table_reg &= ~(0xff << (8 * reg_offset));
> +               smc_table_reg |= ((0x01 | (queue << 1)) << (8 * reg_offset));
> +       }
> +
> +       mvreg_write(pp, MVNETA_DA_FILT_SPEC_MCAST + tbl_offset * 4,
> +                   smc_table_reg);
> +}
> +
> +/* This method controls the network device Other MAC multicast support.
> + * The Other Multicast Table is used for multicast of another type.
> + * A CRC-8 is used as an index to the Other Multicast Table entries
> + * in the DA-Filter table.
> + * The method gets the CRC-8 value from the calling routine and
> + * sets the Other Multicast Table appropriate entry according to the
> + * specified CRC-8 .
> + */
> +static void mvneta_set_other_mcast_addr(struct mvneta_port *pp,
> +                                       unsigned char crc8,
> +                                       int queue)
> +{
> +       unsigned int omc_table_reg;
> +       unsigned int tbl_offset;
> +       unsigned int reg_offset;
> +
> +       tbl_offset = (crc8 / 4) * 4; /* Register offset from OMC table base */
> +       reg_offset = crc8 % 4;       /* Entry offset within the above reg   */
> +
> +       omc_table_reg = mvreg_read(pp, MVNETA_DA_FILT_OTH_MCAST + tbl_offset);
> +
> +       if (queue == -1) {
> +               /* Clear accepts frame bit at specified Other DA table entry */
> +               omc_table_reg &= ~(0xff << (8 * reg_offset));
> +       } else {
> +               omc_table_reg &= ~(0xff << (8 * reg_offset));
> +               omc_table_reg |= ((0x01 | (queue << 1)) << (8 * reg_offset));
> +       }
> +
> +       mvreg_write(pp, MVNETA_DA_FILT_OTH_MCAST + tbl_offset, omc_table_reg);
> +}
> +
> +/* The network device supports multicast using two tables:
> + *    1) Special Multicast Table for MAC addresses of the form
> + *       0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
> + *       The MAC DA[7:0] bits are used as a pointer to the Special Multicast
> + *       Table entries in the DA-Filter table.
> + *    2) Other Multicast Table for multicast of another type. A CRC-8 value
> + *       is used as an index to the Other Multicast Table entries in the
> + *       DA-Filter table.
> + */
> +static int mvneta_mcast_addr_set(struct mvneta_port *pp, unsigned char *p_addr,
> +                                int queue)
> +{
> +       unsigned char crc_result = 0;
> +
> +       if (memcmp(p_addr, "\x01\x00\x5e\x00\x00", 5) == 0) {
> +               mvneta_set_special_mcast_addr(pp, p_addr[5], queue);
> +               return 0;
> +       }
> +
> +       crc_result = mvneta_addr_crc(p_addr);
> +       if (queue == -1) {
> +               if (pp->mcast_count[crc_result] == 0) {
> +                       netdev_info(pp->dev, "No valid Mcast for crc8=0x%02x\n",
> +                                   crc_result);
> +                       return -EINVAL;
> +               }
> +
> +               pp->mcast_count[crc_result]--;
> +               if (pp->mcast_count[crc_result] != 0) {
> +                       netdev_info(pp->dev,
> +                                   "After delete there are %d valid Mcast for crc8=0x%02x\n",
> +                                   pp->mcast_count[crc_result], crc_result);
> +                       return -EINVAL;
> +               }
> +       } else
> +               pp->mcast_count[crc_result]++;
> +
> +       mvneta_set_other_mcast_addr(pp, crc_result, queue);
> +
> +       return 0;
> +}
> +
> +/* Configure Fitering mode of Ethernet port */
> +static void mvneta_rx_unicast_promisc_set(struct mvneta_port *pp,
> +                                         int is_promisc)
> +{
> +       u32 port_cfg_reg, val;
> +
> +       port_cfg_reg = mvreg_read(pp, MVNETA_PORT_CONFIG);
> +
> +       val = mvreg_read(pp, MVNETA_TYPE_PRIO);
> +
> +       /* Set / Clear UPM bit in port configuration register */
> +       if (is_promisc) {
> +               /* Accept all Unicast addresses */
> +               port_cfg_reg |= MVNETA_UNI_PROMISC_MODE;
> +               val |= MVNETA_FORCE_UNI;
> +               mvreg_write(pp, MVNETA_MAC_ADDR_LOW, 0xffff);
> +               mvreg_write(pp, MVNETA_MAC_ADDR_HIGH, 0xffffffff);
> +       } else {
> +               /* Reject all Unicast addresses */
> +               port_cfg_reg &= ~MVNETA_UNI_PROMISC_MODE;
> +               val &= ~MVNETA_FORCE_UNI;
> +       }
> +
> +       mvreg_write(pp, MVNETA_PORT_CONFIG, port_cfg_reg);
> +       mvreg_write(pp, MVNETA_TYPE_PRIO, val);
> +}
> +
> +/* register unicast and multicast addresses */
> +static void mvneta_set_rx_mode(struct net_device *dev)
> +{
> +       struct mvneta_port *pp = netdev_priv(dev);
> +       struct netdev_hw_addr *ha;
> +       int queue = 0;
> +
> +       if (dev->flags & IFF_PROMISC) {
> +               /* Accept all: Multicast + Unicast */
> +               mvneta_rx_unicast_promisc_set(pp, 1);
> +               mvneta_set_ucast_table(pp, queue);
> +               mvneta_set_special_mcast_table(pp, queue);
> +               mvneta_set_other_mcast_table(pp, queue);
> +       } else {
> +               /* Accept single Unicast */
> +               mvneta_rx_unicast_promisc_set(pp, 0);
> +               mvneta_set_ucast_table(pp, -1);
> +               if ((mvneta_mac_addr_set(pp, dev->dev_addr, queue)) != 0)
> +                       netdev_err(dev, "mvneta_mac_addr_set failed\n");
> +
> +               if (dev->flags & IFF_ALLMULTI) {
> +                       /* Accept all multicast */
> +                       mvneta_set_special_mcast_table(pp, queue);
> +                       mvneta_set_other_mcast_table(pp, queue);
> +               } else {
> +                       /* Accept only initialized multicast */
> +                       mvneta_set_special_mcast_table(pp, -1);
> +                       mvneta_set_other_mcast_table(pp, -1);
> +
> +                       if (!netdev_mc_empty(dev)) {
> +                               netdev_for_each_mc_addr(ha, dev) {
> +                                       mvneta_mcast_addr_set(pp, ha->addr,
> +                                                             queue);
> +                               }
> +                       }
> +               }
> +       }
> +}
> +
> +/* Interrupt handling - the callback for request_irq() */
> +static irqreturn_t mvneta_isr(int irq, void *dev_id)
> +{
> +       struct mvneta_port *pp = (struct mvneta_port *)dev_id;
> +
> +       /* Mask all interrupts */
> +       mvreg_write(pp, MVNETA_INTR_NEW_MASK, 0);
> +
> +       /* Verify that the device not already on the polling list */
> +       if (napi_schedule_prep(&pp->napi))
> +               __napi_schedule(&pp->napi);
> +
> +       return IRQ_HANDLED;
> +}
> +
> +/* NAPI handler
> + * Bits 0 - 7 of the causeRxTx register indicate that are transmitted
> + * packets on the corresponding TXQ (Bit 0 is for TX queue 1).
> + * Bits 8 -15 of the cause Rx Tx register indicate that are received
> + * packets on the corresponding RXQ (Bit 8 is for RX queue 0).
> + * Each CPU has its own causeRxTx register
> + */
> +static int mvneta_poll(struct napi_struct *napi, int budget)
> +{
> +       int rx_done = 0;
> +       u32 cause_rx_tx;
> +       unsigned long flags;
> +       struct mvneta_port *pp = netdev_priv(napi->dev);
> +
> +       if (!netif_running(pp->dev)) {
> +               napi_complete(napi);
> +               return rx_done;
> +       }
> +
> +       /* Read cause register */
> +       cause_rx_tx = mvreg_read(pp, MVNETA_INTR_NEW_CAUSE) &
> +               MVNETA_RX_INTR_MASK(rxq_number);
> +
> +       /*
> +        * For the case where the last mvneta_poll did not process all
> +        * RX packets
> +        */
> +       cause_rx_tx |= pp->cause_rx_tx;
> +       if (rxq_number > 1) {
> +               while ((cause_rx_tx != 0) && (budget > 0)) {
> +                       int count;
> +                       struct mvneta_rx_queue *rxq;
> +                       /* get rx queue number from cause_rx_tx */
> +                       rxq = mvneta_rx_policy(pp, cause_rx_tx);
> +                       if (!rxq)
> +                               break;
> +
> +                       /* process the packet in that rx queue */
> +                       count = mvneta_rx(pp, budget, rxq);
> +                       rx_done += count;
> +                       budget -= count;
> +                       if (budget > 0) {
> +                               /* set off the rx bit of the corresponding bit
> +                                 in the cause rx tx register, so that next
> +                                 iteration will find the next rx queue where
> +                                 packets are received on */
> +                               cause_rx_tx &= ~((1 << rxq->id) << 8);
> +                       }
> +               }
> +       } else {
> +               rx_done = mvneta_rx(pp, budget, &pp->rxqs[rxq_def]);
> +               budget -= rx_done;
> +       }
> +
> +       if (budget > 0) {
> +               cause_rx_tx = 0;
> +               napi_complete(napi);
> +               local_irq_save(flags);
> +               mvreg_write(pp, MVNETA_INTR_NEW_MASK,
> +                           MVNETA_RX_INTR_MASK(rxq_number));
> +               local_irq_restore(flags);
> +       }
> +
> +       pp->cause_rx_tx = cause_rx_tx;
> +       return rx_done;
> +}
> +
> +/* tx done timer callback */
> +static void mvneta_tx_done_timer_callback(unsigned long data)
> +{
> +       struct net_device *dev = (struct net_device *)data;
> +       struct mvneta_port *pp = netdev_priv(dev);
> +       int tx_done = 0, tx_todo = 0;
> +
> +       if (!netif_running(dev))
> +               return ;
> +
> +       clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
> +
> +       tx_done = mvneta_tx_done_gbe(pp,
> +                                    (((1 << txq_number) - 1) &
> +                                     MVNETA_CAUSE_TXQ_SENT_DESC_ALL_MASK),
> +                                    &tx_todo);
> +       if (tx_todo > 0)
> +               mvneta_add_tx_done_timer(pp);
> +}
> +
> +/* Handle rxq fill: allocates rxq skbs; called when initializing a port */
> +static int mvneta_rxq_fill(struct mvneta_port *pp, struct mvneta_rx_queue *rxq,
> +                          int num)
> +{
> +       int i;
> +       struct net_device *dev = pp->dev;
> +
> +       for (i = 0; i < num; i++) {
> +               struct sk_buff *skb;
> +               struct mvneta_rx_desc *rx_desc;
> +               unsigned long phys_addr;
> +
> +               skb = dev_alloc_skb(pp->pkt_size);
> +               if (!skb) {
> +                       netdev_err(dev, "%s:rxq %d, %d of %d buffs  filled\n",
> +                               __func__, rxq->id, i, num);
> +                       break;
> +               }
> +
> +               rx_desc = rxq->descs + i;
> +               memset(rx_desc, 0, sizeof(struct mvneta_rx_desc));
> +               phys_addr = dma_map_single(dev->dev.parent, skb->head,
> +                                          MVNETA_RX_BUF_SIZE(pp->pkt_size),
> +                                          DMA_FROM_DEVICE);
> +               if (unlikely(dma_mapping_error(dev->dev.parent, phys_addr))) {
> +                       dev_kfree_skb(skb);
> +                       break;
> +               }
> +
> +               mvneta_rx_desc_fill(rx_desc, phys_addr, (u32)skb);
> +       }
> +
> +       /* Add this number of RX descriptors as non occupied (ready to
> +          get packets) */
> +       mvneta_rxq_non_occup_desc_add(pp, rxq, i);
> +
> +       return i;
> +}
> +
> +/* Free all packets pending transmit from all TXQs and reset TX port */
> +static void mvneta_tx_reset(struct mvneta_port *pp)
> +{
> +       int queue;
> +
> +       /* free the skb's in the hal tx ring */
> +       for (queue = 0; queue < txq_number; queue++)
> +               mvneta_txq_done_force(pp, &pp->txqs[queue]);
> +
> +       mvreg_write(pp, MVNETA_PORT_TX_RESET, MVNETA_PORT_TX_DMA_RESET);
> +       mvreg_write(pp, MVNETA_PORT_TX_RESET, 0);
> +}
> +
> +static void mvneta_rx_reset(struct mvneta_port *pp)
> +{
> +       mvreg_write(pp, MVNETA_PORT_RX_RESET, MVNETA_PORT_RX_DMA_RESET);
> +       mvreg_write(pp, MVNETA_PORT_RX_RESET, 0);
> +}
> +
> +/* Rx/Tx queue initialization/cleanup methods */
> +
> +/* Create a specified RX queue */
> +static int mvneta_rxq_init(struct mvneta_port *pp,
> +                          struct mvneta_rx_queue *rxq)
> +
> +{
> +       rxq->size = pp->rx_ring_size;
> +
> +       /* Allocate memory for RX descriptors */
> +       rxq->descs = dma_alloc_coherent(pp->dev->dev.parent,
> +                                       rxq->size * MVNETA_DESC_ALIGNED_SIZE,
> +                                       &rxq->descs_phys,
> +                                       GFP_KERNEL);
> +       if (rxq->descs == NULL) {
> +               netdev_err(pp->dev,
> +                          "rxQ=%d: Can't allocate %d bytes for %d RX descr\n",
> +                          rxq->id, rxq->size * MVNETA_DESC_ALIGNED_SIZE,
> +                          rxq->size);
> +               return -ENOMEM;
> +       }
> +
> +       BUG_ON(rxq->descs !=
> +              PTR_ALIGN(rxq->descs, MVNETA_CPU_D_CACHE_LINE_SIZE));
> +
> +       rxq->last_desc = rxq->size - 1;
> +
> +       /* Set Rx descriptors queue starting address */
> +       mvreg_write(pp, MVNETA_RXQ_BASE_ADDR_REG(rxq->id), rxq->descs_phys);
> +       mvreg_write(pp, MVNETA_RXQ_SIZE_REG(rxq->id), rxq->size);
> +
> +       /* Set Offset */
> +       mvneta_rxq_offset_set(pp, rxq, NET_SKB_PAD);
> +
> +       /* Set coalescing pkts and time */
> +       mvneta_rx_pkts_coal_set(pp, rxq, rxq->pkts_coal);
> +       mvneta_rx_time_coal_set(pp, rxq, rxq->time_coal);
> +
> +       /* Fill RXQ with buffers from RX pool */
> +       mvneta_rxq_buf_size_set(pp, rxq, MVNETA_RX_BUF_SIZE(pp->pkt_size));
> +       mvneta_rxq_bm_disable(pp, rxq);
> +       mvneta_rxq_fill(pp, rxq, rxq->size);
> +
> +       return 0;
> +}
> +
> +/* Cleanup Rx queue */
> +static void mvneta_rxq_deinit(struct mvneta_port *pp,
> +                             struct mvneta_rx_queue *rxq)
> +{
> +       mvneta_rxq_drop_pkts(pp, rxq);
> +
> +       if (rxq->descs)
> +               dma_free_coherent(pp->dev->dev.parent,
> +                                 rxq->size * MVNETA_DESC_ALIGNED_SIZE,
> +                                 rxq->descs,
> +                                 rxq->descs_phys);
> +
> +       rxq->descs             = NULL;
> +       rxq->last_desc         = 0;
> +       rxq->next_desc_to_proc = 0;
> +       rxq->descs_phys        = 0;
> +}
> +
> +/* Create and initialize a tx queue */
> +static int mvneta_txq_init(struct mvneta_port *pp,
> +                          struct mvneta_tx_queue *txq)
> +{
> +       txq->size = pp->tx_ring_size;
> +
> +       /* Allocate memory for TX descriptors */
> +       txq->descs = dma_alloc_coherent(pp->dev->dev.parent,
> +                                       txq->size * MVNETA_DESC_ALIGNED_SIZE,
> +                                       &txq->descs_phys,
> +                                       DMA_BIDIRECTIONAL);
> +       if (txq->descs == NULL) {
> +               netdev_err(pp->dev,
> +                          "txQ=%d: Can't allocate %d bytes for %d TX descr\n",
> +                          txq->id, txq->size * MVNETA_DESC_ALIGNED_SIZE,
> +                          txq->size);
> +               return -ENOMEM;
> +       }
> +
> +       /* Make sure descriptor address is cache line size aligned  */
> +       BUG_ON(txq->descs !=
> +              PTR_ALIGN(txq->descs, MVNETA_CPU_D_CACHE_LINE_SIZE));
> +
> +       txq->last_desc = txq->size - 1;
> +
> +       /* Set maximum bandwidth for enabled TXQs */
> +       mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(txq->id), 0x03ffffff);
> +       mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(txq->id), 0x3fffffff);
> +
> +       /* Set Tx descriptors queue starting address */
> +       mvreg_write(pp, MVNETA_TXQ_BASE_ADDR_REG(txq->id), txq->descs_phys);
> +       mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), txq->size);
> +
> +       txq->tx_skb = kmalloc(txq->size * sizeof(*txq->tx_skb),
> +                             GFP_KERNEL);
> +       if (txq->tx_skb == NULL) {
> +               dma_free_coherent(pp->dev->dev.parent,
> +                                 txq->size * MVNETA_DESC_ALIGNED_SIZE,
> +                                 txq->descs, txq->descs_phys);
> +               return -ENOMEM;
> +       }
> +       mvneta_tx_done_pkts_coal_set(pp, txq, txq->done_pkts_coal);
> +
> +       return 0;
> +}
> +
> +/* Free allocated resources when mvneta_txq_init() fails to allocate memory*/
> +static void mvneta_txq_deinit(struct mvneta_port *pp,
> +                             struct mvneta_tx_queue *txq)
> +{
> +       kfree(txq->tx_skb);
> +
> +       if (txq->descs)
> +               dma_free_coherent(pp->dev->dev.parent,
> +                                 txq->size * MVNETA_DESC_ALIGNED_SIZE,
> +                                 txq->descs,
> +                                 txq->descs_phys);
> +
> +       txq->descs             = NULL;
> +       txq->last_desc         = 0;
> +       txq->next_desc_to_proc = 0;
> +       txq->descs_phys        = 0;
> +
> +       /* Set minimum bandwidth for disabled TXQs */
> +       mvreg_write(pp, MVETH_TXQ_TOKEN_CFG_REG(txq->id), 0);
> +       mvreg_write(pp, MVETH_TXQ_TOKEN_COUNT_REG(txq->id), 0);
> +
> +       /* Set Tx descriptors queue starting address and size */
> +       mvreg_write(pp, MVNETA_TXQ_BASE_ADDR_REG(txq->id), 0);
> +       mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), 0);
> +}
> +
> +/* Cleanup all Tx queues */
> +static void mvneta_cleanup_txqs(struct mvneta_port *pp)
> +{
> +       int queue;
> +       for (queue = 0; queue < txq_number; queue++)
> +               mvneta_txq_deinit(pp, &pp->txqs[queue]);
> +}
> +
> +/* Cleanup all Rx queues */
> +static void mvneta_cleanup_rxqs(struct mvneta_port *pp)
> +{
> +       int queue;
> +       for (queue = 0; queue < rxq_number; queue++)
> +               mvneta_rxq_deinit(pp, &pp->rxqs[queue]);
> +}
> +
> +
> +/* Init all Rx queues */
> +static int mvneta_setup_rxqs(struct mvneta_port *pp)
> +{
> +       int queue;
> +
> +       for (queue = 0; queue < rxq_number; queue++) {
> +               int err = mvneta_rxq_init(pp, &pp->rxqs[queue]);
> +               if (err) {
> +                       netdev_err(pp->dev,
> +                                  "%s: can't create RxQ rxq=%d\n",
> +                                  __func__, queue);
> +                       mvneta_cleanup_rxqs(pp);
> +                       return -ENODEV;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +/* Init all tx queues */
> +static int mvneta_setup_txqs(struct mvneta_port *pp)
> +{
> +       int queue;
> +
> +       for (queue = 0; queue < txq_number; queue++) {
> +               int err = mvneta_txq_init(pp, &pp->txqs[queue]);
> +               if (err) {
> +                       netdev_err(pp->dev,
> +                                  "%s: can't create TxQ txq=%d\n",
> +                                  __func__, queue);
> +                       mvneta_cleanup_txqs(pp);
> +                       return err;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static void mvneta_start_dev(struct mvneta_port *pp)
> +{
> +       mvneta_max_rx_size_set(pp, pp->pkt_size);
> +       mvneta_txq_max_tx_size_set(pp, pp->pkt_size);
> +
> +       /* start the Rx/Tx activity */
> +       mvneta_port_enable(pp);
> +
> +       /* Enable polling on the port */
> +       napi_enable(&pp->napi);
> +
> +       /* Unmask interrupts */
> +       mvneta_interrupts_unmask(pp);
> +       smp_call_function_many(cpu_online_mask,
> +                              mvneta_interrupts_unmask,
> +                              pp, 1);
> +
> +       phy_start(pp->phy_dev);
> +       netif_tx_start_all_queues(pp->dev);
> +}
> +
> +static void mvneta_stop_dev(struct mvneta_port *pp)
> +{
> +       phy_stop(pp->phy_dev);
> +
> +       napi_disable(&pp->napi);
> +
> +       /* Stop upper layer */
> +       netif_carrier_off(pp->dev);
> +
> +       mvneta_port_down(pp);
> +       netif_tx_stop_all_queues(pp->dev);
> +
> +       /* Stop the port activity */
> +       mvneta_port_disable(pp);
> +
> +       /* Clear all ethernet port interrupts */
> +       mvreg_write(pp, MVNETA_INTR_MISC_CAUSE, 0);
> +       mvreg_write(pp, MVNETA_INTR_OLD_CAUSE, 0);
> +
> +       /* Mask all interrupts */
> +       mvneta_interrupts_mask(pp);
> +       smp_call_function_many(cpu_online_mask, mvneta_interrupts_mask,
> +                              pp, 1);
> +
> +       /* Reset TX port here. */
> +       mvneta_tx_reset(pp);
> +       mvneta_rx_reset(pp);
> +}
> +
> +/* tx timeout callback - display a message and stop/start the network device */
> +static void mvneta_tx_timeout(struct net_device *dev)
> +{
> +       struct mvneta_port *pp = netdev_priv(dev);
> +       netdev_info(dev, "tx timeout\n");
> +       mvneta_stop_dev(pp);
> +       mvneta_start_dev(pp);
> +}
> +
> +/* Return positive if MTU is valid */
> +static int mvneta_check_mtu_valid(struct net_device *dev, int mtu)
> +{
> +       if (mtu < 68) {
> +               netdev_err(dev, "cannot change mtu to less than 68\n");
> +               return -EINVAL;
> +       }
> +
> +       if (mtu > 9676 /* 9700 - 20 and rounding to 8 */) {
> +               netdev_info(dev, "Illegal MTU value %d, round to 9676", mtu);
> +               mtu = 9676;
> +       }
> +
> +       if (!IS_ALIGNED(MVNETA_RX_PKT_SIZE(mtu), 8)) {
> +               netdev_info(dev, "Illegal MTU value %d, rounding to %d",
> +                       mtu, ALIGN(MVNETA_RX_PKT_SIZE(mtu), 8));
> +               mtu = ALIGN(MVNETA_RX_PKT_SIZE(mtu), 8);
> +       }
> +
> +       return mtu;
> +}
> +
> +/* Change the device mtu */
> +static int mvneta_change_mtu(struct net_device *dev, int mtu)
> +{
> +       struct mvneta_port *pp = netdev_priv(dev);
> +       int ret;
> +
> +       mtu = mvneta_check_mtu_valid(dev, mtu);
> +       if (mtu < 0)
> +               return -EINVAL;
> +
> +       dev->mtu = mtu;
> +
> +       if (!netif_running(dev))
> +               return 0;
> +
> +       /*
> +        * The interface is running, so we have to force a
> +        * reallocation of the RXQs
> +        */
> +       mvneta_stop_dev(pp);
> +
> +       mvneta_cleanup_txqs(pp);
> +       mvneta_cleanup_rxqs(pp);
> +
> +       pp->pkt_size = MVNETA_RX_PKT_SIZE(pp->dev->mtu);
> +
> +       ret = mvneta_setup_rxqs(pp);
> +       if (ret) {
> +               netdev_err(pp->dev, "unable to setup rxqs after MTU change\n");
> +               return ret;
> +       }
> +
> +       mvneta_setup_txqs(pp);
> +
> +       mvneta_start_dev(pp);
> +       mvneta_port_up(pp);
> +
> +       return 0;
> +}
> +
> +/* Handle setting mac address */
> +static int mvneta_set_mac_addr(struct net_device *dev, void *addr)
> +{
> +       struct mvneta_port *pp = netdev_priv(dev);
> +       u8 *mac = addr + 2;
> +       int i, ret;
> +
> +       if (netif_running(dev))
> +               return -EBUSY;
> +
> +       /* Remove previous address table entry */
> +       ret = mvneta_mac_addr_set(pp, dev->dev_addr, -1);
> +       if (ret < 0)
> +               return ret;
> +
> +       /* Set new addr in hw */
> +       ret = mvneta_mac_addr_set(pp, mac, rxq_def);
> +       if (ret < 0)
> +               return ret;
> +
> +       /* Set addr in the device */
> +       for (i = 0; i < ETH_ALEN; i++)
> +               dev->dev_addr[i] = mac[i];
> +
> +       return 0;
> +}
> +
> +/* MDIO / phylib functions */
> +
> +static int mvneta_mdio_read(struct mii_bus *bus, int mii_id,
> +                           int regnum)
> +{
> +       struct mvneta_port *pp = bus->priv;
> +       int count;
> +       u32 val;
> +
> +       /* Wait for the SMI register to be ready for another
> +        * operation */
> +       count = 0;
> +       while (1) {
> +               val = mvreg_read(pp, MVNETA_SMI);
> +               if (!(val & MVNETA_SMI_BUSY))
> +                       break;
> +
> +               if (count > 100) {
> +                       netdev_err(pp->dev, "Timeout: SMI busy for too long\n");
> +                       return -ETIMEDOUT;
> +               }
> +
> +               udelay(10);
> +               count++;
> +       }
> +
> +       mvreg_write(pp, MVNETA_SMI,
> +                   ((mii_id << MVNETA_SMI_PHY_ADDR_SHIFT) |
> +                   (regnum << MVNETA_SMI_PHY_REG_SHIFT)  |
> +                    MVNETA_SMI_READ_OPERATION));
> +
> +       /* Wait for the value to become available */
> +       count = 0;
> +       while (1) {
> +               val = mvreg_read(pp, MVNETA_SMI);
> +               if (val & MVNETA_SMI_READ_VALID)
> +                       break;
> +
> +               if (count > 100) {
> +                       netdev_err(pp->dev, "Timeout when reading PHY\n");
> +                       return -ETIMEDOUT;
> +               }
> +
> +               udelay(10);
> +               count++;
> +       }
> +
> +       return val & 0xFFFF;
> +}
> +
> +static int mvneta_mdio_write(struct mii_bus *bus, int mii_id,
> +                            int regnum, u16 value)
> +{
> +       struct mvneta_port *pp = bus->priv;
> +       int count;
> +       u32 val;
> +
> +       /* Wait for the SMI register to be ready for another
> +        * operation */
> +       count = 0;
> +       while (1) {
> +               val = mvreg_read(pp, MVNETA_SMI);
> +               if (!(val & MVNETA_SMI_BUSY))
> +                       break;
> +
> +               if (count > 100) {
> +                       netdev_err(pp->dev, "Timeout: SMI busy for too long\n");
> +                       return -ETIMEDOUT;
> +               }
> +
> +               udelay(10);
> +               count++;
> +       }
> +
> +       mvreg_write(pp, MVNETA_SMI,
> +                   ((mii_id << MVNETA_SMI_PHY_ADDR_SHIFT) |
> +                    (regnum << MVNETA_SMI_PHY_REG_SHIFT)  |
> +                    MVNETA_SMI_WRITE_OPERATION            |
> +                    (value << MVNETA_SMI_DATA_SHIFT)));
> +
> +       return 0;
> +}
> +
> +static int mvneta_mdio_reset(struct mii_bus *bus)
> +{
> +       return 0;
> +}
> +
> +
> +static void mvneta_adjust_link(struct net_device *ndev)
> +{
> +       struct mvneta_port *pp = netdev_priv(ndev);
> +       struct phy_device *phydev = pp->phy_dev;
> +       int status_change = 0;
> +
> +       if (phydev->link) {
> +               if ((pp->speed != phydev->speed) ||
> +                   (pp->duplex != phydev->duplex)) {
> +                       u32 val;
> +
> +                       val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
> +                       val &= ~(MVNETA_GMAC_CONFIG_MII_SPEED |
> +                                MVNETA_GMAC_CONFIG_GMII_SPEED |
> +                                MVNETA_GMAC_CONFIG_FULL_DUPLEX);
> +
> +                       if (phydev->duplex)
> +                               val |= MVNETA_GMAC_CONFIG_FULL_DUPLEX;
> +
> +                       if (phydev->speed == SPEED_1000)
> +                               val |= MVNETA_GMAC_CONFIG_GMII_SPEED;
> +                       else
> +                               val |= MVNETA_GMAC_CONFIG_MII_SPEED;
> +
> +                       mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
> +
> +                       pp->duplex = phydev->duplex;
> +                       pp->speed  = phydev->speed;
> +               }
> +       }
> +
> +       if (phydev->link != pp->link) {
> +               if (!phydev->link) {
> +                       pp->duplex = -1;
> +                       pp->speed = 0;
> +               }
> +
> +               pp->link = phydev->link;
> +               status_change = 1;
> +       }
> +
> +       if (status_change) {
> +               if (phydev->link) {
> +                       u32 val = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG);
> +                       val |= (MVNETA_GMAC_FORCE_LINK_PASS |
> +                               MVNETA_GMAC_FORCE_LINK_DOWN);
> +                       mvreg_write(pp, MVNETA_GMAC_AUTONEG_CONFIG, val);
> +                       mvneta_port_up(pp);
> +                       netdev_info(pp->dev, "link up\n");
> +               } else {
> +                       mvneta_port_down(pp);
> +                       netdev_info(pp->dev, "link down\n");
> +               }
> +       }
> +}
> +
> +static int mvneta_mdio_probe(struct mvneta_port *pp)
> +{
> +       int ret;
> +       struct phy_device *phy_dev;
> +
> +       phy_dev = phy_find_first(pp->mii_bus);
> +       if (!phy_dev) {
> +               netdev_err(pp->dev, "no PHY found\n");
> +               return -ENODEV;
> +       }
> +
> +       ret = phy_connect_direct(pp->dev, phy_dev, mvneta_adjust_link, 0,
> +                                    pp->phy_interface);
> +       if (ret) {
> +               netdev_err(pp->dev, "could not attach to PHY\n");
> +               return ret;
> +       }
> +
> +       phy_dev->supported &= PHY_GBIT_FEATURES;
> +       phy_dev->advertising = phy_dev->supported;
> +
> +       pp->phy_dev = phy_dev;
> +       pp->link    = 0;
> +       pp->duplex  = 0;
> +       pp->speed   = 0;
> +
> +       return 0;
> +}
> +
> +static void mvneta_mdio_remove(struct mvneta_port *pp)
> +{
> +       phy_disconnect(pp->phy_dev);
> +       pp->phy_dev = NULL;
> +}
> +
> +static int mvneta_open(struct net_device *dev)
> +{
> +       struct mvneta_port *pp = netdev_priv(dev);
> +       int ret;
> +
> +       ret = mvneta_mac_addr_set(pp, dev->dev_addr, rxq_def);
> +       if (ret < 0) {
> +               netdev_err(dev, "mvneta_mac_addr_set failed\n");
> +               goto mac_addr_set_failure;
> +       }
> +
> +       pp->pkt_size = MVNETA_RX_PKT_SIZE(pp->dev->mtu);
> +
> +       ret = mvneta_setup_rxqs(pp);
> +       if (ret)
> +               goto rxqs_setup_failure;
> +
> +       ret = mvneta_setup_txqs(pp);
> +       if (ret)
> +               goto txqs_setup_failure;
> +
> +       /* Connect to port interrupt line */
> +       ret = request_irq(pp->dev->irq, mvneta_isr, IRQF_DISABLED,
> +                         MVNETA_DRIVER_NAME, pp);
> +       if (ret) {
> +               netdev_err(pp->dev, "cannot request irq %d\n", pp->dev->irq);
> +               goto request_irq_failure;
> +       }
> +
> +       /* In default link is down */
> +       netif_carrier_off(pp->dev);
> +
> +       ret = mvneta_mdio_probe(pp);
> +       if (ret < 0) {
> +               netdev_err(dev, "cannot probe MDIO bus\n");
> +               goto mdio_probe_failure;
> +       }
> +
> +       mvneta_start_dev(pp);
> +
> +       return 0;
> +
> +mdio_probe_failure:
> +       free_irq(pp->dev->irq, pp);
> +request_irq_failure:
> +       mvneta_cleanup_txqs(pp);
> +txqs_setup_failure:
> +       mvneta_cleanup_rxqs(pp);
> +rxqs_setup_failure:
> +mac_addr_set_failure:
> +       return ret;
> +}
> +
> +/* Stop the port, free port interrupt line */
> +static int mvneta_stop(struct net_device *dev)
> +{
> +       struct mvneta_port *pp = netdev_priv(dev);
> +
> +       mvneta_stop_dev(pp);
> +       mvneta_cleanup_rxqs(pp);
> +       mvneta_cleanup_txqs(pp);
> +       del_timer(&pp->tx_done_timer);
> +       clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
> +       free_irq(dev->irq, pp);
> +       mvneta_mdio_remove(pp);
> +
> +       return 0;
> +}
> +
> +/* Ethtool methods */
> +
> +/* Get settings (phy address, speed) for ethtools */
> +int mvneta_ethtool_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
> +{
> +       struct mvneta_port *pp = netdev_priv(dev);
> +
> +       if (!pp->phy_dev)
> +               return -ENODEV;
> +
> +       return phy_ethtool_gset(pp->phy_dev, cmd);
> +}
> +
> +/* Set settings (phy address, speed) for ethtools */
> +int mvneta_ethtool_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
> +{
> +       struct mvneta_port *pp = netdev_priv(dev);
> +
> +       if (!pp->phy_dev)
> +               return -ENODEV;
> +
> +       return phy_ethtool_sset(pp->phy_dev, cmd);
> +}
> +
> +/* Set interrupt coalescing for ethtools */
> +static int mvneta_ethtool_set_coalesce(struct net_device *dev,
> +                                      struct ethtool_coalesce *c)
> +{
> +       int queue;
> +       struct mvneta_port *pp = netdev_priv(dev);
> +
> +       for (queue = 0; queue < rxq_number; queue++) {
> +               struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
> +               rxq->time_coal = c->rx_coalesce_usecs;
> +               rxq->pkts_coal = c->rx_max_coalesced_frames;
> +               mvneta_rx_pkts_coal_set(pp, rxq, rxq->pkts_coal);
> +               mvneta_rx_time_coal_set(pp, rxq, rxq->time_coal);
> +       }
> +
> +       for (queue = 0; queue < txq_number; queue++) {
> +               struct mvneta_tx_queue *txq = &pp->txqs[queue];
> +               txq->done_pkts_coal = c->tx_max_coalesced_frames;
> +               mvneta_tx_done_pkts_coal_set(pp, txq, txq->done_pkts_coal);
> +       }
> +
> +       return 0;
> +}
> +
> +/* get coalescing for ethtools */
> +static int mvneta_ethtool_get_coalesce(struct net_device *dev,
> +                              struct ethtool_coalesce *c)
> +{
> +       struct mvneta_port *pp = netdev_priv(dev);
> +
> +       c->rx_coalesce_usecs        = pp->rxqs[0].time_coal;
> +       c->rx_max_coalesced_frames  = pp->rxqs[0].pkts_coal;
> +
> +       c->tx_max_coalesced_frames =  pp->txqs[0].done_pkts_coal;
> +       return 0;
> +}
> +
> +
> +static void mvneta_ethtool_get_drvinfo(struct net_device *dev,
> +                                   struct ethtool_drvinfo *drvinfo)
> +{
> +       strlcpy(drvinfo->driver, MVNETA_DRIVER_NAME,
> +               sizeof(drvinfo->driver));
> +       strlcpy(drvinfo->version, MVNETA_DRIVER_VERSION,
> +               sizeof(drvinfo->version));
> +       strlcpy(drvinfo->bus_info, dev_name(&dev->dev),
> +               sizeof(drvinfo->bus_info));
> +}
> +
> +
> +static void mvneta_ethtool_get_ringparam(struct net_device *netdev,
> +                               struct ethtool_ringparam *ring)
> +{
> +       struct mvneta_port *pp = netdev_priv(netdev);
> +
> +       ring->rx_max_pending = MVNETA_MAX_RXD;
> +       ring->tx_max_pending = MVNETA_MAX_TXD;
> +       ring->rx_pending = pp->rx_ring_size;
> +       ring->tx_pending = pp->tx_ring_size;
> +}
> +
> +static int mvneta_ethtool_set_ringparam(struct net_device *dev,
> +                              struct ethtool_ringparam *ring)
> +{
> +       struct mvneta_port *pp = netdev_priv(dev);
> +
> +       if ((ring->rx_pending == 0) || (ring->tx_pending == 0))
> +               return -EINVAL;
> +       pp->rx_ring_size = ring->rx_pending < MVNETA_MAX_RXD ?
> +               ring->rx_pending : MVNETA_MAX_RXD;
> +       pp->tx_ring_size = ring->tx_pending < MVNETA_MAX_TXD ?
> +               ring->tx_pending : MVNETA_MAX_TXD;
> +
> +       if (netif_running(dev)) {
> +               mvneta_stop(dev);
> +               if (mvneta_open(dev)) {
> +                       netdev_err(dev,
> +                                  "error on opening device after ring param change\n");
> +                       return -ENOMEM;
> +               }
> +       }
> +
> +       return 0;
> +}
> +
> +static const struct net_device_ops mvneta_netdev_ops = {
> +       .ndo_open = mvneta_open,
> +       .ndo_stop = mvneta_stop,
> +       .ndo_start_xmit = mvneta_tx,
> +       .ndo_set_rx_mode = mvneta_set_rx_mode,
> +       .ndo_set_mac_address = mvneta_set_mac_addr,
> +       .ndo_change_mtu = mvneta_change_mtu,
> +       .ndo_tx_timeout = mvneta_tx_timeout,
> +       .ndo_get_stats64 = mvneta_get_stats64,
> +};
> +
> +const struct ethtool_ops mvneta_eth_tool_ops = {
> +       .get_link = ethtool_op_get_link,
> +       .get_settings = mvneta_ethtool_get_settings,
> +       .set_settings = mvneta_ethtool_set_settings,
> +       .set_coalesce = mvneta_ethtool_set_coalesce,
> +       .get_coalesce = mvneta_ethtool_get_coalesce,
> +       .get_drvinfo  = mvneta_ethtool_get_drvinfo,
> +       .get_ringparam  = mvneta_ethtool_get_ringparam,
> +       .set_ringparam  = mvneta_ethtool_set_ringparam,
> +};
> +
> +/* Initialize hw */
> +static int __devinit mvneta_init(struct mvneta_port *pp, int phy_addr)
> +{
> +       int queue, i, ret = 0;
> +
> +       /* Disable port */
> +       mvneta_port_disable(pp);
> +
> +       /* Set port default values */
> +       mvneta_defaults_set(pp);
> +
> +       pp->txqs = kzalloc(txq_number * sizeof(struct mvneta_tx_queue),
> +                          GFP_KERNEL);
> +       if (!pp->txqs) {
> +               netdev_err(pp->dev, "out of memory in allocating tx queue\n");
> +               ret = -ENOMEM;
> +               goto txqs_alloc_failure;
> +       }
> +
> +       /* Initialize TX descriptor rings */
> +       for (queue = 0; queue < txq_number; queue++) {
> +               struct mvneta_tx_queue *txq = &pp->txqs[queue];
> +               txq->id = queue;
> +               txq->size = pp->tx_ring_size;
> +               txq->done_pkts_coal = MVNETA_TXDONE_COAL_PKTS;
> +       }
> +
> +       pp->rxqs = kzalloc(rxq_number * sizeof(struct mvneta_rx_queue),
> +                          GFP_KERNEL);
> +       if (!pp->rxqs) {
> +               netdev_err(pp->dev, "out of memory in allocating rx queue\n");
> +               ret = -ENOMEM;
> +               goto rxqs_alloc_failure;
> +       }
> +
> +       /* Create Rx descriptor rings */
> +       for (queue = 0; queue < rxq_number; queue++) {
> +               struct mvneta_rx_queue *rxq = &pp->rxqs[queue];
> +               rxq->id = queue;
> +               rxq->size = pp->rx_ring_size;
> +               rxq->pkts_coal = MVNETA_RX_COAL_PKTS;
> +               rxq->time_coal = MVNETA_RX_COAL_USEC;
> +       }
> +
> +       pp->mii_bus = mdiobus_alloc();
> +       if (!pp->mii_bus) {
> +               netdev_err(pp->dev, "Cannot allocate MDIO bus\n");
> +               ret = -ENOMEM;
> +               goto mdiobus_alloc_failure;
> +       }
> +
> +       pp->mii_bus->name = "mvneta_mii_bus";
> +       pp->mii_bus->read = mvneta_mdio_read;
> +       pp->mii_bus->write = mvneta_mdio_write;
> +       pp->mii_bus->reset = mvneta_mdio_reset;
> +       snprintf(pp->mii_bus->id, MII_BUS_ID_SIZE, "%s-mii",
> +                dev_name(pp->dev->dev.parent));
> +       pp->mii_bus->priv = pp;
> +       pp->mii_bus->parent = pp->dev->dev.parent;
> +       pp->mii_bus->phy_mask = ~(1 << phy_addr);
> +
> +       pp->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
> +       if (!pp->mii_bus->irq) {
> +               netdev_err(pp->dev, "Cannot allocate PHY IRQ array\n");
> +               ret = -ENOMEM;
> +               goto mdiobus_irq_alloc_failure;
> +       }
> +
> +       for (i = 0; i < PHY_MAX_ADDR; i++)
> +               pp->mii_bus->irq[i] = PHY_POLL;
> +
> +       ret = mdiobus_register(pp->mii_bus);
> +       if (ret < 0) {
> +               netdev_err(pp->dev, "Cannot register MDIO bus (%d)\n", ret);
> +               goto mdiobus_register_failure;
> +       }
> +
> +       return 0;
> +
> +mdiobus_register_failure:
> +       kfree(pp->mii_bus->irq);
> +mdiobus_irq_alloc_failure:
> +       mdiobus_free(pp->mii_bus);
> +mdiobus_alloc_failure:
> +       kfree(pp->rxqs);
> +rxqs_alloc_failure:
> +       kfree(pp->txqs);
> +txqs_alloc_failure:
> +       return ret;
> +}
> +
> +static void __devexit mvneta_deinit(struct mvneta_port *pp)
> +{
> +       mdiobus_unregister(pp->mii_bus);
> +       kfree(pp->mii_bus->irq);
> +       mdiobus_free(pp->mii_bus);
> +       kfree(pp->txqs);
> +       kfree(pp->rxqs);
> +}
> +
> +/* platform glue : initialize decoding windows */
> +static void __devinit mvneta_conf_mbus_windows(struct mvneta_port *pp,
> +                               const struct mbus_dram_target_info *dram)
> +{
> +       u32 win_enable;
> +       u32 win_protect;
> +       int i;
> +
> +       for (i = 0; i < 6; i++) {
> +               mvreg_write(pp, MVNETA_WIN_BASE(i), 0);
> +               mvreg_write(pp, MVNETA_WIN_SIZE(i), 0);
> +
> +               if (i < 4)
> +                       mvreg_write(pp, MVNETA_WIN_REMAP(i), 0);
> +       }
> +
> +       win_enable = 0x3f;
> +       win_protect = 0;
> +
> +       for (i = 0; i < dram->num_cs; i++) {
> +               const struct mbus_dram_window *cs = dram->cs + i;
> +               mvreg_write(pp, MVNETA_WIN_BASE(i),
> +                           (cs->base & 0xffff0000) |
> +                           (cs->mbus_attr << 8) |
> +                           dram->mbus_dram_target_id);
> +
> +               mvreg_write(pp, MVNETA_WIN_SIZE(i),
> +                           (cs->size - 1) & 0xffff0000);
> +
> +               win_enable &= ~(1 << i);
> +               win_protect |= 3 << (2 * i);
> +       }
> +
> +       mvreg_write(pp, MVNETA_BASE_ADDR_ENABLE, win_enable);
> +}
> +
> +/* Power up the port */
> +static void __devinit mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
> +{
> +       u32 val;
> +
> +       /* MAC Cause register should be cleared */
> +       mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0);
> +
> +       if (phy_mode == PHY_INTERFACE_MODE_SGMII)
> +               mvneta_port_sgmii_config(pp);
> +
> +       mvneta_gmac_rgmii_set(pp, 1);
> +
> +       /* Cancel Port Reset */
> +       val = mvreg_read(pp, MVNETA_GMAC_CTRL_2);
> +       val &= ~MVNETA_GMAC2_PORT_RESET;
> +       mvreg_write(pp, MVNETA_GMAC_CTRL_2, val);
> +
> +       while ((mvreg_read(pp, MVNETA_GMAC_CTRL_2) &
> +               MVNETA_GMAC2_PORT_RESET) != 0)
> +               continue;
> +}
> +
> +/* Device initialization routine */
> +static int __devinit mvneta_probe(struct platform_device *pdev)
> +{
> +       int err = -EINVAL;
> +       struct mvneta_port *pp;
> +       struct net_device *dev;
> +       u32 phy_addr, clk_rate_hz;
> +       int phy_mode;
> +       const char *mac_addr;
> +       const struct mbus_dram_target_info *dram_target_info;
> +       struct device_node *dn = pdev->dev.of_node;
> +
> +       dev = alloc_etherdev_mq(sizeof(struct mvneta_port), 8);
> +       if (!dev)
> +               return -ENOMEM;
> +
> +       dev->irq = irq_of_parse_and_map(dn, 0);
> +       if (dev->irq == 0) {
> +               err = -EINVAL;
> +               goto err_irq;
> +       }
> +
> +       if (of_property_read_u32(dn, "phy-addr", &phy_addr) != 0) {
> +               dev_err(&pdev->dev, "could not read phy-addr\n");
> +               err = -ENODEV;
> +               goto err_node;
> +       }
> +
> +       phy_mode = of_get_phy_mode(dn);
> +       if (phy_mode < 0) {
> +               dev_err(&pdev->dev, "wrong phy-mode\n");
> +               err = -EINVAL;
> +               goto err_node;
> +       }
> +
> +       if (of_property_read_u32(dn, "clock-frequency", &clk_rate_hz) != 0) {
> +               dev_err(&pdev->dev, "could not read clock-frequency\n");
> +               err = -EINVAL;
> +               goto err_node;
> +       }
> +
> +       mac_addr = of_get_mac_address(dn);
> +
> +       if (!mac_addr || !is_valid_ether_addr(mac_addr))
> +               eth_hw_addr_random(dev);
> +       else
> +               memcpy(dev->dev_addr, mac_addr, ETH_ALEN);
> +
> +       dev->tx_queue_len = MVNETA_MAX_TXD;
> +       dev->watchdog_timeo = 5 * HZ;
> +       dev->netdev_ops = &mvneta_netdev_ops;
> +
> +       SET_ETHTOOL_OPS(dev, &mvneta_eth_tool_ops);
> +
> +       pp = netdev_priv(dev);
> +
> +       pp->tx_done_timer.function = mvneta_tx_done_timer_callback;
> +       init_timer(&pp->tx_done_timer);
> +       clear_bit(MVNETA_F_TX_DONE_TIMER_BIT, &pp->flags);
> +
> +       pp->weight = MVNETA_RX_POLL_WEIGHT;
> +       pp->clk_rate_hz = clk_rate_hz;
> +       pp->phy_interface = phy_mode;
> +
> +       pp->base = of_iomap(dn, 0);
> +       if (pp->base == NULL) {
> +               err = -ENOMEM;
> +               goto err_node;
> +       }
> +
> +       pp->tx_done_timer.data = (unsigned long)dev;
> +
> +       pp->tx_ring_size = MVNETA_MAX_TXD;
> +       pp->rx_ring_size = MVNETA_MAX_RXD;
> +
> +       pp->dev = dev;
> +       SET_NETDEV_DEV(dev, &pdev->dev);
> +
> +       if (mvneta_init(pp, phy_addr)) {
> +               dev_err(&pdev->dev, "can't init eth hal\n");
> +               err = -ENODEV;
> +               goto err_base;
> +       }
> +       mvneta_port_power_up(pp, phy_mode);
> +
> +       dram_target_info = mv_mbus_dram_info();
> +       if (dram_target_info)
> +               mvneta_conf_mbus_windows(pp, dram_target_info);
> +
> +       netif_napi_add(dev, &pp->napi, mvneta_poll, pp->weight);
> +
> +       if (register_netdev(dev)) {
> +               dev_err(&pdev->dev, "failed to register\n");
> +               err = ENOMEM;
> +               goto err_base;
> +       }
> +
> +       dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
> +       dev->hw_features =  NETIF_F_SG | NETIF_F_IP_CSUM;
> +       dev->priv_flags |= IFF_UNICAST_FLT;
> +
> +       dev_info(&pdev->dev, "%s, mac: %pM\n", dev->name,
> +                dev->dev_addr);
> +
> +       platform_set_drvdata(pdev, pp->dev);
> +
> +       return 0;
> +err_base:
> +       iounmap(pp->base);
> +err_node:
> +       irq_dispose_mapping(dev->irq);
> +err_irq:
> +       free_netdev(dev);
> +       return err;
> +}
> +
> +/* Device removal routine */
> +static int __devexit mvneta_remove(struct platform_device *pdev)
> +{
> +       struct net_device  *dev = platform_get_drvdata(pdev);
> +       struct mvneta_port *pp = netdev_priv(dev);
> +
> +       iounmap(pp->base);
> +
> +       unregister_netdev(dev);
> +       irq_dispose_mapping(dev->irq);
> +       free_netdev(dev);
> +       mvneta_deinit(pp);
> +
> +       platform_set_drvdata(pdev, NULL);
> +
> +       return 0;
> +}
> +
> +static const struct of_device_id mvneta_match[] = {
> +       { .compatible = "marvell,armada-370-neta" },
> +       { }
> +};
> +MODULE_DEVICE_TABLE(of, mvneta_match);
> +
> +static struct platform_driver mvneta_driver = {
> +       .probe = mvneta_probe,
> +       .remove = __devexit_p(mvneta_remove),
> +       .driver = {
> +               .name = MVNETA_DRIVER_NAME,
> +               .of_match_table = mvneta_match,
> +       },
> +};
> +
> +module_platform_driver(mvneta_driver);
> +
> +MODULE_DESCRIPTION("Marvell NETA Ethernet Driver - www.marvell.com");
> +MODULE_AUTHOR("Rami Rosen <rosenr@marvell.com>, Thomas Petazzoni <thomas.petazzoni@free-electrons.com>");
> +MODULE_LICENSE("GPL");
> +
> +module_param(rxq_number, int, S_IRUGO);
> +module_param(txq_number, int, S_IRUGO);
> +
> +module_param(rxq_def, int, S_IRUGO);
> +module_param(txq_def, int, S_IRUGO);
> --
> 1.7.9.5
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



-- 
Nobuhiro Iwamatsu
   iwamatsu at {nigauri.org / debian.org}
   GPG ID: 40AD1FA6

^ permalink raw reply

* [PATCH v4 2/2] mx2_camera: Fix regression caused by clock conversion
From: Fabio Estevam @ 2012-10-30 12:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351598606-8485-1-git-send-email-fabio.estevam@freescale.com>

Since mx27 transitioned to the commmon clock framework in 3.5, the correct way
to acquire the csi clock is to get csi_ahb and csi_per clocks separately.

By not doing so the camera sensor does not probe correctly:

soc-camera-pdrv soc-camera-pdrv.0: Probing soc-camera-pdrv.0
mx2-camera mx2-camera.0: Camera driver attached to camera 0
ov2640 0-0030: Product ID error fb:fb
mx2-camera mx2-camera.0: Camera driver detached from camera 0
mx2-camera mx2-camera.0: MX2 Camera (CSI) driver probed, clock frequency: 66500000

Adapt the mx2_camera driver to the new clock framework and make it functional
again.

Tested-by: Ga?tan Carlier <gcembed@gmail.com>
Tested-by: Javier Martin <javier.martin@vista-silicon.com>
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
---
Changes since v3:
- Drop unneeded clk_unprepare calls as pointed out by Guennadi
Changes since v2:
- Fix clock error handling code as pointed out by Russell King
Changes since v1:
- Rebased against linux-next 20121008.
 drivers/media/platform/soc_camera/mx2_camera.c |   39 ++++++++++++++++++------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/soc_camera/mx2_camera.c b/drivers/media/platform/soc_camera/mx2_camera.c
index e575ae8..558f6a3 100644
--- a/drivers/media/platform/soc_camera/mx2_camera.c
+++ b/drivers/media/platform/soc_camera/mx2_camera.c
@@ -278,7 +278,8 @@ struct mx2_camera_dev {
 	struct device		*dev;
 	struct soc_camera_host	soc_host;
 	struct soc_camera_device *icd;
-	struct clk		*clk_csi, *clk_emma_ahb, *clk_emma_ipg;
+	struct clk		*clk_emma_ahb, *clk_emma_ipg;
+	struct clk		*clk_csi_ahb, *clk_csi_per;
 
 	void __iomem		*base_csi, *base_emma;
 
@@ -464,7 +465,8 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev)
 {
 	unsigned long flags;
 
-	clk_disable_unprepare(pcdev->clk_csi);
+	clk_disable_unprepare(pcdev->clk_csi_ahb);
+	clk_disable_unprepare(pcdev->clk_csi_per);
 	writel(0, pcdev->base_csi + CSICR1);
 	if (is_imx27_camera(pcdev)) {
 		writel(0, pcdev->base_emma + PRP_CNTL);
@@ -492,10 +494,14 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
 	if (pcdev->icd)
 		return -EBUSY;
 
-	ret = clk_prepare_enable(pcdev->clk_csi);
+	ret = clk_prepare_enable(pcdev->clk_csi_ahb);
 	if (ret < 0)
 		return ret;
 
+	ret = clk_prepare_enable(pcdev->clk_csi_per);
+	if (ret < 0)
+		goto exit_csi_ahb;
+
 	csicr1 = CSICR1_MCLKEN;
 
 	if (is_imx27_camera(pcdev))
@@ -512,6 +518,11 @@ static int mx2_camera_add_device(struct soc_camera_device *icd)
 		 icd->devnum);
 
 	return 0;
+
+exit_csi_ahb:
+	clk_disable_unprepare(pcdev->clk_csi_ahb);
+
+	return ret;
 }
 
 static void mx2_camera_remove_device(struct soc_camera_device *icd)
@@ -1772,10 +1783,17 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
 		break;
 	}
 
-	pcdev->clk_csi = devm_clk_get(&pdev->dev, "ahb");
-	if (IS_ERR(pcdev->clk_csi)) {
-		dev_err(&pdev->dev, "Could not get csi clock\n");
-		err = PTR_ERR(pcdev->clk_csi);
+	pcdev->clk_csi_ahb = devm_clk_get(&pdev->dev, "ahb");
+	if (IS_ERR(pcdev->clk_csi_ahb)) {
+		dev_err(&pdev->dev, "Could not get csi ahb clock\n");
+		err = PTR_ERR(pcdev->clk_csi_ahb);
+		goto exit;
+	}
+
+	pcdev->clk_csi_per = devm_clk_get(&pdev->dev, "per");
+	if (IS_ERR(pcdev->clk_csi_per)) {
+		dev_err(&pdev->dev, "Could not get csi per clock\n");
+		err = PTR_ERR(pcdev->clk_csi_per);
 		goto exit;
 	}
 
@@ -1785,12 +1803,13 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
 
 		pcdev->platform_flags = pcdev->pdata->flags;
 
-		rate = clk_round_rate(pcdev->clk_csi, pcdev->pdata->clk * 2);
+		rate = clk_round_rate(pcdev->clk_csi_per,
+						pcdev->pdata->clk * 2);
 		if (rate <= 0) {
 			err = -ENODEV;
 			goto exit;
 		}
-		err = clk_set_rate(pcdev->clk_csi, rate);
+		err = clk_set_rate(pcdev->clk_csi_per, rate);
 		if (err < 0)
 			goto exit;
 	}
@@ -1848,7 +1867,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev)
 		goto exit_free_emma;
 
 	dev_info(&pdev->dev, "MX2 Camera (CSI) driver probed, clock frequency: %ld\n",
-			clk_get_rate(pcdev->clk_csi));
+			clk_get_rate(pcdev->clk_csi_per));
 
 	return 0;
 
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v4 1/2] ARM: clk-imx27: Add missing clock for mx2-camera
From: Fabio Estevam @ 2012-10-30 12:03 UTC (permalink / raw)
  To: linux-arm-kernel

During the clock conversion for mx27 the "per4_gate" clock was missed to get
registered as a dependency of mx2-camera driver.

In the old mx27 clock driver we used to have:

DEFINE_CLOCK1(csi_clk, 0, NULL, 0, parent, &csi_clk1, &per4_clk);

,so does the same in the new clock driver

Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Changes since v3:
- Use imx27-camera.0 instead of mx2-camera.0, due to recent changes in the
imx27 clock (commit 27b76486a3: media: mx2_camera: remove cpu_is_xxx by using platform_device_id)

 arch/arm/mach-imx/clk-imx27.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c
index 585ab25..2880bd9 100644
--- a/arch/arm/mach-imx/clk-imx27.c
+++ b/arch/arm/mach-imx/clk-imx27.c
@@ -224,6 +224,7 @@ int __init mx27_clocks_init(unsigned long fref)
 	clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx21-fb.0");
 	clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx21-fb.0");
 	clk_register_clkdev(clk[csi_ahb_gate], "ahb", "imx27-camera.0");
+	clk_register_clkdev(clk[per4_gate], "per", "imx27-camera.0");
 	clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc");
 	clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc");
 	clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc");
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 00/13] ARM: OMAP: remove prcm.[ch]
From: Paul Walmsley @ 2012-10-30 11:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <508E5B65.2020800@ti.com>

On Mon, 29 Oct 2012, Vaibhav Hiremath wrote:

> 
> 
> On 10/26/2012 4:51 AM, Paul Walmsley wrote:
> > Remove arch/arm/mach-omap2/prcm.c and
> > arch/arm/plat-omap/include/plat/prcm.h.  This is in preparation for
> > moving the PRM/CM code to drivers/, although to be fair, these files
> > should have been removed a long time ago.
> > 
> > Intended for 3.8 cleanup.  Applies on top of the existing PRM/CM split
> > cleanup series, and the WDTIMER cleanup series.
> > 
> 
> Paul,
> 
> By any chance you have branch available with these patches, so that I
> can validate them here at my end?

The current version is at

git://git.pwsan.com/linux-2.6

in the branch

prcm_cleanup_b_3.8


- Paul

^ permalink raw reply

* [PATCH V2 3/3] clocksource: time-armada-370-xp converted to clk framework
From: Mike Turquette @ 2012-10-30 11:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349125926-16144-4-git-send-email-gregory.clement@free-electrons.com>

Quoting Gregory CLEMENT (2012-10-01 14:12:06)
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>

I'm not sure this patch should go through me.  Perhaps John Stultz?

Regards,
Mike

^ permalink raw reply

* [PATCHv2] Input: omap4-keypad: Add pinctrl support
From: Felipe Balbi @ 2012-10-30 11:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121030112410.GM4511@opensource.wolfsonmicro.com>

Hi,

On Tue, Oct 30, 2012 at 11:24:10AM +0000, Mark Brown wrote:
> > This is why I think hiding things from drivers makes no sense. Also
> > consider the situations Linus W exposed on another subthread. If you
> > change ordering of certain calls, you will really break the
> > functionality of the IP. Because we can't make sure this won't work
> > automagically in all cases (just like we can't make sure $size memory
> > allocation is enough for all drivers) we don't hide that from the
> > driver. We require driver to manage its resources properly.
> 
> We need some place to put the SoC integration; power domains seem like
> the obvious place to me but YMMV.  Nothing about having this out of the

except that pin muxing has nothing to do with power domain. To me that
sounds like an abuse of the API.

> drivers requires that this be done by individual subsystems in isolation
> from each other.  Half the point here is that for the reusable IPs this
> stuff often isn't driver specific at all, it's often more about the SoC
> integration than it is about the driver and so you'll get a consistent
> pattern for most IPs on the SoC.

and all of that SoC-specific detail is already hidden behind power
domains, runtime PM, pinctrl, clk API, regulator framework, etc.

> > How can you make sure that this will work for at least 50% of the
> > drivers ? You just can't. We don't know the implementation details of
> > every arch/soc/platform supported by Linux today to make that decision.
> 
> Well, we've managed to get along for rather a long time with essentially
> all architectures implementing this stuff by doing static setup for the
> pins on boot.  That does suggest we can get a reasonably long way with

and this is one of the issues we're all trying to solve today so we have
single zImage approach for the ARM port.

> something simple, and it does seem to match up with how things usually
> look at an electrical level too.

simple ? I really doubt it. Just look at the amount of code duplication
the ARM port had (still has in some places) to handle platform-specific
details.

It turned out that drivers weren't very portable when they had to do
platform-specific initialization, we were all abusing platform_data to
pass strings and/or function pointers down to drivers and so on.

I'm concerned if we hide pinctrl under e.g. power domains (as said
above, it sounds like an abuse of the API to me) we will end up with a
situation like above. Maybe not as bad, but still weird-looking.

> It seems fairly obvious that if we need to add identical bolier plate
> code to lots of drivers we're doing something wrong, it's just churn for
> little practical gain and a problem if we ever decide to change how this
> stuff works in the future.

I wouldn't consider it boilerplate if you remember that each driver
might have different requirements regarding how all of those details
need to be handled.

We have to consider power consumption, ordering of calls, proper IP
setup, IP reuse on multiple platforms (even multiple ARCHes), etc etc,
and to get that right outside of the driver - who's the only class that
actually knows what it needs to do with its resources - will just be too
complex and error-prone.

I would strongly suggest starting with explicit calls to pinctrl, clk
API, etc and if we can really prove later that 95% of the users are
"standard", then we can factor code out, but making that assumption now
is quite risky IMHO.

-- 
balbi
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121030/6920f961/attachment-0001.sig>

^ permalink raw reply

* OMAP baseline test results for v3.7-rc3
From: Paul Walmsley @ 2012-10-30 11:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <508FB226.20604@mimc.co.uk>

cc Vaibhav Hiremath

On Tue, 30 Oct 2012, Mark Jackson wrote:

> At what point is booting from MMC on the BeagleBone going to start working ?
> 
> I only ask, since, by default, a new BeagleBone is setup to boot from 
> MMC, so anyone testing a new kernel will probably expect the same setup 
> to work.

BeagleBone boots initramfs from MMC now, which is what mine was shipped to 
do.  Are you asking about rootfs on MMC?  If so, Vaibhav would have a 
better sense of this than I.


- Paul

^ permalink raw reply

* [PATCH V2 1/3] clk: mvebu: add armada-370-xp specific clocks
From: Gregory CLEMENT @ 2012-10-30 11:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121030112025.18780.88390@nucleus>

On 10/30/2012 12:20 PM, Mike Turquette wrote:
> Quoting Gregory CLEMENT (2012-10-01 14:12:04)
>> Add Armada 370/XP specific clocks: core clocks and CPU clocks.
>>
>> The CPU clocks are only for Armada XP for the SMP mode.
>>
>> The core clocks are clocks which have their rate set during reset. The
>> code was written with the other SoCs of the mvebu family in
>> mind. Adding them should be pretty straight forward. For a new
>> SoC, only 3 binding have to be added:
>> - one to provide the tclk frequency
>> - one to provde the pclk frequency
>> - and one to provide the ratio between the pclk and the children
>>   clocks
>>
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> 
> Thanks for sending v2 Gregory.  Functionally this series looks good but
> unfortunately there are a few style and white space nitpicks below.

Hi Mike,

You don't review the last version: I have sent a third version tow weeks
ago (October th 15th). But all your comment should applied for this last
version.

The changelog was
V2 -> V3:
- Rebased on top of v3.7-rc1
- Fixed a typo in device trees
- Fixed warning from checkpatch

Thanks for your review, I will send a new version in few hours.

> 
>> diff --git a/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt b/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
>> new file mode 100644
>> index 0000000..c524618
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/mvebu-cpu-clock.txt
>> @@ -0,0 +1,21 @@
>> +Device Tree Clock bindings for cpu clock of Marvell EBU platforms
>> +
>> +Required properties:
>> +- compatible : shall be one of the following:
>> +       "marvell,armada-xp-cpu-clockctrl" - cpu clocks for Armada XP
>> +- reg : Address and length of the clock complex register set
>> +- #clock-cells : should be set to 1.
>> +- clocks : shall be the input parent clock phandle for the clock.
>> +
>> +cpuclk: clock-complex at d0018700 {
>> +       #clock-cells = <1>;
>> +       compatible = "marvell,armada-xp-cpu-clockctrl";
>> +       reg = <0xd0018700 0xA0>;
>> +       clocks = <&coreclk 1>;
>> +}
>> +
>> +cpu at 0 {
>> +       compatible = "marvell,sheeva-v7";
> 
> Unnecessary white space before the tab in the line above.
> 
>> diff --git a/drivers/clk/mvebu/clk-core.c b/drivers/clk/mvebu/clk-core.c
>> new file mode 100644
>> index 0000000..5792cb5
>> --- /dev/null
>> +++ b/drivers/clk/mvebu/clk-core.c
>> @@ -0,0 +1,312 @@
>> +/*
>> + * Marvell EBU clock core handling defined at reset
>> + *
>> + * Copyright (C) 2012 Marvell
>> + *
>> + * Gregory CLEMENT <gregory.clement@free-electrons.com>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2.  This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +#include <linux/kernel.h>
>> +#include <linux/clk.h>
>> +#include <linux/clkdev.h>
>> +#include <linux/clk-provider.h>
>> +#include <linux/of_address.h>
>> +#include <linux/io.h>
>> +#include <linux/of.h>
>> +
>> +/* Sample At Reset is a 64 bit bitfiled split in two register of 32
>> + * bits*/
> 
> Can you make this proper comment block style per CodingStyle convention?
> 
>> +
>> +#define SARL                               0   /* Low part [0:31] */
>> +#define            SARL_AXP_PCLK_FREQ_OPT          21
>> +#define            SARL_AXP_PCLK_FREQ_OPT_MASK     0x7
>> +#define            SARL_A370_PCLK_FREQ_OPT         11
>> +#define            SARL_A370_PCLK_FREQ_OPT_MASK    0xF
>> +#define            SARL_AXP_FAB_FREQ_OPT           24
>> +#define            SARL_AXP_FAB_FREQ_OPT_MASK      0xF
>> +#define            SARL_A370_FAB_FREQ_OPT          15
>> +#define            SARL_A370_FAB_FREQ_OPT_MASK     0x1F
>> +#define            SARL_A370_TCLK_FREQ_OPT         20
>> +#define            SARL_A370_TCLK_FREQ_OPT_MASK    0x1
>> +#define SARH                               4   /* High part [32:63] */
>> +#define            SARH_AXP_PCLK_FREQ_OPT          (52-32)
>> +#define            SARH_AXP_PCLK_FREQ_OPT_MASK     0x1
>> +#define            SARH_AXP_PCLK_FREQ_OPT_SHIFT    3
>> +#define            SARH_AXP_FAB_FREQ_OPT           (51-32)
>> +#define            SARH_AXP_FAB_FREQ_OPT_MASK      0x1
>> +#define            SARH_AXP_FAB_FREQ_OPT_SHIFT     4
>> +
>> +u32 *sar_reg;
>> +int sar_reg_size;
>> +
>> +enum core_clk {
>> +       tclk, pclk, nbclk, hclk, dramclk, clk_max
>> +};
>> +
>> +struct core_clk_fn {
>> +       u32(*get_tclk_freq) (void);
>> +       u32(*get_pck_freq) (void);
>> +       const int *(*get_fab_freq_opt) (void);
>> +};
>> +
>> +/* Ratio between VCO and each of the member in the following order:
>> +   CPU clock, L2 clock, DRAM controler clock, DDR clcok */
> 
> ditto
> 
>> +static const int reset_core_ratio[32][4] = {
>> +       [0x01] = {1, 2, 2, 2},
>> +       [0x02] = {2, 2, 6, 3},
>> +       [0x03] = {2, 2, 3, 3},
>> +       [0x04] = {1, 2, 3, 3},
>> +       [0x05] = {1, 2, 4, 2},
>> +       [0x06] = {1, 1, 2, 2},
>> +       [0x07] = {2, 3, 6, 6},
>> +       [0x09] = {1, 2, 6, 3},
>> +       [0x0A] = {2, 4, 10, 5},
>> +       [0x0C] = {1, 2, 4, 4},
>> +       [0x0F] = {2, 2, 5, 5},
>> +       [0x13] = {1, 1, 2, 1},
>> +       [0x14] = {2, 3, 6, 3},
>> +       [0x1B] = {1, 1, 1, 1},
>> +};
>> +
>> +static struct clk *clks[clk_max];
>> +
>> +static struct clk_onecell_data clk_data;
>> +
>> +/* Frequency in MHz*/
>> +static u32 armada_370_pclk[] = { 400, 533, 667, 800, 1000, 1067, 1200 };
>> +
>> +static u32 armada_xp_pclk[] = { 1000, 1066, 1200, 1333, 1500, 1666,
>> +       1800, 2000, 667, 0, 800, 1600
>> +};
>> +
>> +static u32 armada_370_tclk[] = { 166, 200 };
>> +
>> +static const int *__init armada_370_get_fab_freq_opt(void)
>> +{
>> +       u8 fab_freq_opt = 0;
>> +
>> +       fab_freq_opt = ((sar_reg[0] >> SARL_A370_FAB_FREQ_OPT) &
>> +                       SARL_A370_FAB_FREQ_OPT_MASK);
>> +
>> +       if (reset_core_ratio[fab_freq_opt][0] == 0)
>> +               return NULL;
>> +       else
>> +               return reset_core_ratio[fab_freq_opt];
>> +}
>> +
>> +static u32 __init armada_370_get_pck_freq(void)
>> +{
>> +       u32 cpu_freq;
>> +       u8 cpu_freq_select = 0;
>> +
>> +       cpu_freq_select = ((sar_reg[0] >> SARL_A370_PCLK_FREQ_OPT) &
>> +                          SARL_A370_PCLK_FREQ_OPT_MASK);
>> +       if (cpu_freq_select > ARRAY_SIZE(armada_370_pclk)) {
>> +               pr_err("CPU freq select unsuported %d\n", cpu_freq_select);
>> +               cpu_freq = 0;
>> +       } else
>> +               cpu_freq = armada_370_pclk[cpu_freq_select];
>> +
>> +       return cpu_freq * 1000 * 1000;
>> +}
>> +
>> +static u32 __init armada_370_get_tclk_freq(void)
>> +{
>> +       u32 tclk_freq;
>> +       u8 tclk_freq_select = 0;
>> +
>> +       tclk_freq_select = ((sar_reg[0] >> SARL_A370_TCLK_FREQ_OPT) &
>> +                           SARL_A370_TCLK_FREQ_OPT_MASK);
>> +       if (tclk_freq_select > ARRAY_SIZE(armada_370_tclk)) {
>> +               pr_err("TCLK freq select unsuported %d\n", tclk_freq_select);
>> +               tclk_freq = 0;
>> +       } else
>> +               tclk_freq = armada_370_tclk[tclk_freq_select];
>> +
>> +       return tclk_freq * 1000 * 1000;
>> +}
>> +
>> +static const int *__init armada_xp_get_fab_freq_opt(void)
>> +{
>> +       u8 fab_freq_opt = 0;
>> +
>> +       fab_freq_opt = ((sar_reg[0] >> SARL_AXP_FAB_FREQ_OPT) &
>> +                       SARL_AXP_FAB_FREQ_OPT_MASK);
>> +       /* The upper bit is not contiguous to the other ones
>> +        * and located in the high part of the SAR
>> +        * registers */
> 
> ditto
> 
>> +       fab_freq_opt |= (((sar_reg[1] >> SARH_AXP_FAB_FREQ_OPT) &
>> +                         SARH_AXP_FAB_FREQ_OPT_MASK)
>> +                        << SARH_AXP_FAB_FREQ_OPT_SHIFT);
>> +
>> +       if (reset_core_ratio[fab_freq_opt][0] == 0)
>> +               return NULL;
>> +       else
>> +               return reset_core_ratio[fab_freq_opt];
>> +}
>> +
>> +static u32 __init armada_xp_get_pck_freq(void)
>> +{
>> +       u32 cpu_freq;
>> +       u8 cpu_freq_select = 0;
>> +
>> +       cpu_freq_select = ((sar_reg[0] >> SARL_AXP_PCLK_FREQ_OPT) &
>> +                          SARL_AXP_PCLK_FREQ_OPT_MASK);
>> +       /* The upper bit is not contiguous to the other ones
>> +        * and located in the high part of the SAR
>> +        * registers */
> 
> ditto
> 
>> +       cpu_freq_select |= (((sar_reg[1] >> SARH_AXP_PCLK_FREQ_OPT) &
>> +                            SARH_AXP_PCLK_FREQ_OPT_MASK)
>> +                           << SARH_AXP_PCLK_FREQ_OPT_SHIFT);
>> +       if (cpu_freq_select > ARRAY_SIZE(armada_xp_pclk)) {
>> +               pr_err("CPU freq select unsuported: %d\n", cpu_freq_select);
>> +               cpu_freq = 0;
>> +       } else
>> +               cpu_freq = armada_xp_pclk[cpu_freq_select];
>> +
>> +       return cpu_freq * 1000 * 1000;
>> +}
>> +
>> +/* For Armada XP TCLK frequency is fix: 250MHz */
>> +static u32 __init armada_xp_get_tclk_freq(void)
>> +{
>> +       return 250 * 1000 * 1000;
>> +}
>> +
>> +void __init of_core_clk_setup(struct device_node *node,
>> +                             struct core_clk_fn clk_fn)
>> +{
>> +       struct clk *clk;
>> +       unsigned long rate;
>> +       const char *clk_name;
>> +       int i;
>> +
>> +       /* clock 0 is tclk */
>> +       of_property_read_string_index(node, "clock-output-names", tclk,
>> +                               &clk_name);
>> +       rate = clk_fn.get_tclk_freq();
>> +       if (rate != 0)
>> +               clk = clk_register_fixed_rate(NULL, clk_name, NULL,
>> +                                             CLK_IS_ROOT, rate);
>> +       else {
>> +               pr_err("Invalid freq for %s\n", clk_name);
>> +               return;
>> +       }
>> +
>> +       if (WARN_ON(IS_ERR(clk)))
>> +               return;
>> +       clks[tclk] = clk;
>> +
>> +       /* clock 1 is pclk */
>> +       of_property_read_string_index(node, "clock-output-names", pclk,
>> +                               &clk_name);
>> +       rate = clk_fn.get_pck_freq();
>> +       if (rate != 0)
>> +               clk = clk_register_fixed_rate(NULL, clk_name, NULL,
>> +                                             CLK_IS_ROOT, rate);
>> +       else {
>> +               pr_err("Invalid freq for %s\n", clk_name);
>> +               return;
>> +       }
>> +       if (WARN_ON(IS_ERR(clk)))
>> +               return;
>> +       clks[pclk] = clk;
>> +
>> +       /* the clocks 2 to 4 are nbclk, hclk and dramclk and are all
>> +        * derivated from the clock 1: pclk */
> 
> ditto
> 
>> +
>> +       for (i = nbclk; i <= dramclk; i++) {
>> +               const int *ratio = clk_fn.get_fab_freq_opt();
>> +               const char *parent_clk_name;
>> +
>> +               of_property_read_string_index(node, "clock-output-names",
>> +                                        i, &clk_name);
>> +               of_property_read_string_index(node, "clock-output-names",
>> +                                        pclk, &parent_clk_name);
>> +
>> +               if (ratio != NULL)
>> +                       clk = clk_register_fixed_factor(NULL, clk_name,
>> +                                                       parent_clk_name, 0,
>> +                                                       ratio[0],
>> +                                                       ratio[i - nbclk + 1]);
>> +               else {
>> +                       pr_err("Invalid clk ratio for %s\n", clk_name);
>> +                       return;
>> +               }
>> +
>> +               if (WARN_ON(IS_ERR(clk)))
>> +                       return;
>> +               clks[i] = clk;
>> +       }
>> +       clk_data.clk_num = ARRAY_SIZE(clks);
>> +       clk_data.clks = clks;
>> +       of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
>> +}
>> +
>> +static struct core_clk_fn armada_370_clk_fn = {
>> +       .get_tclk_freq = armada_370_get_tclk_freq,
>> +       .get_pck_freq = armada_370_get_pck_freq,
>> +       .get_fab_freq_opt = armada_370_get_fab_freq_opt,
>> +};
>> +
>> +static struct core_clk_fn armada_xp_clk_fn = {
>> +       .get_tclk_freq = armada_xp_get_tclk_freq,
>> +       .get_pck_freq = armada_xp_get_pck_freq,
>> +       .get_fab_freq_opt = armada_xp_get_fab_freq_opt,
>> +};
>> +
>> +static const __initconst struct of_device_id clk_match[] = {
>> +       {
>> +        .compatible = "marvell,armada-370-core-clockctrl",
>> +        .data = &armada_370_clk_fn,
>> +        },
> 
> Indention is a bit weird here.  The members are just indented with one
> space and there is an extra white space in front of the closing bracket.
> Can you re-align?
> 
>> +
>> +       {
>> +        .compatible = "marvell,armada-xp-core-clockctrl",
>> +        .data = &armada_xp_clk_fn,
>> +        },
> 
> ditto
> 
>> +       {
>> +        /* sentinel */
>> +        }
> 
> ditto
> 
>> +};
>> +
>> +void __init mvebu_core_clocks_init(void)
>> +{
>> +       struct device_node *np;
>> +       struct resource res;
>> +       void __iomem *sar_base;
>> +       int i;
>> +
>> +       np = of_find_node_by_name(NULL, "mvebu-sar");
>> +
>> +       if (!np)
>> +               goto err;
>> +
>> +       if (of_address_to_resource(np, 0, &res))
>> +               goto err;
>> +
>> +       sar_reg_size = resource_size(&res);
>> +       sar_reg = kmalloc(sar_reg_size, GFP_KERNEL);
>> +
>> +       sar_base = ioremap(res.start, sar_reg_size);
>> +       if (sar_base == NULL)
>> +               goto err;
>> +       for (i = 0; i < sar_reg_size; i += sizeof(*sar_reg))
>> +               sar_reg[i] = readl(sar_base + i);
>> +
>> +       iounmap(sar_base);
>> +
>> +       for_each_matching_node(np, clk_match) {
>> +               const struct of_device_id *match = of_match_node(clk_match, np);
>> +               struct core_clk_fn *clk_fn = match->data;
>> +               of_core_clk_setup(np, *clk_fn);
>> +       }
>> +
>> +       return;
>> +err:
>> +       pr_err("%s:SAR base adresse not set in DT\n", __func__);
>> +       return;
>> +}
>> diff --git a/drivers/clk/mvebu/clk-core.h b/drivers/clk/mvebu/clk-core.h
>> new file mode 100644
>> index 0000000..a04f80b
>> --- /dev/null
>> +++ b/drivers/clk/mvebu/clk-core.h
>> @@ -0,0 +1,19 @@
>> +/*
>> + *  * Marvell EBU clock core handling defined at reset
>> + *
>> + * Copyright (C) 2012 Marvell
>> + *
>> + * Gregory CLEMENT <gregory.clement@free-electrons.com>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2.  This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +
>> +#ifndef __MVEBU_CLK_CORE_H
>> +#define __MVEBU_CLK_CORE_H
>> +
>> +void __init of_core_clk_setup(struct device_node *node);
>> +void __init mvebu_core_clocks_init(void);
>> +
>> +#endif
>> diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c
>> new file mode 100644
>> index 0000000..6b5c841
>> --- /dev/null
>> +++ b/drivers/clk/mvebu/clk-cpu.c
>> @@ -0,0 +1,155 @@
>> +/*
>> + * Marvell MVEBU CPU clock handling.
>> + *
>> + * Copyright (C) 2012 Marvell
>> + *
>> + * Gregory CLEMENT <gregory.clement@free-electrons.com>
>> + *
>> + * This file is licensed under the terms of the GNU General Public
>> + * License version 2.  This program is licensed "as is" without any
>> + * warranty of any kind, whether express or implied.
>> + */
>> +#include <linux/kernel.h>
>> +#include <linux/clk.h>
> 
> clk-provider.h includes clk.h, so this is redundant.
> 
> Regards,
> Mike
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [PATCH] [PATCH] remove pcm049 from Makefile
From: Sergei Shtylyov @ 2012-10-30 11:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351535422-4644-1-git-send-email-holzmayr@rsi-elektrotechnik.de>

Hello.

    You forgot to sign off on the patch, so it can't be applied.

WBR, Sergei

^ permalink raw reply

* [PATCH V2 2/3] clk: armada-370-xp: add support for clock framework
From: Mike Turquette @ 2012-10-30 11:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1349125926-16144-3-git-send-email-gregory.clement@free-electrons.com>

Quoting Gregory CLEMENT (2012-10-01 14:12:05)
> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>

This didn't apply cleanly to -rc3.  Can you rebase this along with the
respin of patch #1 in the series?

<snip>

> diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi
> index 71d6b5d..e75f3a2 100644
> --- a/arch/arm/boot/dts/armada-xp.dtsi
> +++ b/arch/arm/boot/dts/armada-xp.dtsi
> @@ -27,6 +27,35 @@
>                     <0xd0021870 0x58>;
>         };
>  
> +       cpus {
> +           #address-cells = <1>;
> +           #size-cells = <0>;
> +
> +           cpu at 0 {
> +               compatible = "marvell,sheeva-v7";

Extra white space in front of compatible.  Should be tabs.

Regards,
Mike

^ permalink raw reply

* [PATCH] ARM: zynq: move ttc timer code to drivers/clocksource
From: Michal Simek @ 2012-10-30 11:36 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121029185630.GA26149@beefymiracle.amer.corp.natinst.com>

On 10/29/2012 07:56 PM, Josh Cartwright wrote:
> Suggested cleanup by Arnd Bergmann.  Move the ttc timer.c code to
> drivers/clocksource, and out of the mach-zynq directory.
>
> The common.h (which only held the timer declaration) was renamed to
> xilinx_ttc.h and moved into include/linux.
>
> Signed-off-by: Josh Cartwright <josh.cartwright@ni.com>
> Cc: Arnd Bergmann <arnd@arndb.de>
> ---
>   arch/arm/mach-zynq/Makefile      |   2 +-
>   arch/arm/mach-zynq/common.c      |   2 +-
>   arch/arm/mach-zynq/common.h      |  24 ----
>   arch/arm/mach-zynq/timer.c       | 298 ---------------------------------------
>   drivers/clocksource/Makefile     |   1 +
>   drivers/clocksource/xilinx_ttc.c | 297 ++++++++++++++++++++++++++++++++++++++
>   include/linux/xilinx_ttc.h       |  24 ++++
>   7 files changed, 324 insertions(+), 324 deletions(-)
>   delete mode 100644 arch/arm/mach-zynq/common.h
>   delete mode 100644 arch/arm/mach-zynq/timer.c
>   create mode 100644 drivers/clocksource/xilinx_ttc.c
>   create mode 100644 include/linux/xilinx_ttc.h

Really?
If yes. shouldn't be there any better naming convention
especially for headers. linux/clocksource/xilinx_ttc.h.

Thanks,
Michal


-- 
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

^ permalink raw reply

* [PATCHv2] Input: omap4-keypad: Add pinctrl support
From: Mark Brown @ 2012-10-30 11:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CACRpkdaiLXVeUg1quuw3XPTenbKOjn+aWbGQezpcyvzQCtCWow@mail.gmail.com>

On Sun, Oct 28, 2012 at 09:12:52PM +0100, Linus Walleij wrote:

> The answer is that it does not know. Because drivers have
> different needs. Depending on how the hardware and
> system is done.

...

> I'm not making this up, it is a very real phenomenon on the
> Ux500 and I don't think we are unique.

> Moving this handling to bus code or anywhere else
> invariably implies that resource acquisition/release order
> does not matter, and my point is that it does.

Doing this in the buses is definitely wrong, as you say it's not bus
specific.  I do however think we can usefully do this stuff in a SoC
specific place like a power domain, keeping the SoC integration code
together and out of the drivers.  IME the SoCs where you need to do
different things for different IPs shoudl mostly still get some reuse
out of such an approach.

^ permalink raw reply

* [PATCH 0/2] ARM: OMAP: hwmod/omapd_device: Fix for resource handling in DT boot
From: Péter Ujfalusi @ 2012-10-30 11:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.DEB.2.00.1210301123310.12697@utopia.booyaka.com>

On 10/30/2012 12:25 PM, Paul Walmsley wrote:
> On Tue, 30 Oct 2012, Peter Ujfalusi wrote:
> 
>> Tony, Benoit, Paul: Not sure if this qualify for 3.7 inclusion, but for sure
>> going to help us to clean up the OMAP5 hwmod database.
> 
> It's definitely not 3.7 material, but will look at it for 3.8 merge 
> window.  The OMAP5 hwmod data isn't in mainline yet.

True, it can wait till 3.8.

-- 
P?ter

^ permalink raw reply

* [PATCH] net/at91_ether: fix the use of macb structure
From: Nicolas Ferre @ 2012-10-30 11:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <75eb5df193c504e68ebff7d6a6a88d9a1cc678cb.1351591858.git.nicolas.ferre@atmel.com>

Due to the use of common structure in at91_ether and macb drivers,
change the name of DMA descriptor structures in at91_ether as well:
dma_desc => macb_dma_desc

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
Hi,

This patch is a fix for the patch
[PATCH v3 06/10] net/macb: clean up ring buffer logic
that I have just sent.

I would prefer to merge it with the patch mentioned above
that introduces the issue. Tell me if you do it or if I
have to provide a v4 for this patch series.

 drivers/net/ethernet/cadence/at91_ether.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cadence/at91_ether.c b/drivers/net/ethernet/cadence/at91_ether.c
index b92815a..0d6392d 100644
--- a/drivers/net/ethernet/cadence/at91_ether.c
+++ b/drivers/net/ethernet/cadence/at91_ether.c
@@ -156,7 +156,7 @@ static int at91ether_start(struct net_device *dev)
 	int i;
 
 	lp->rx_ring = dma_alloc_coherent(&lp->pdev->dev,
-					MAX_RX_DESCR * sizeof(struct dma_desc),
+					MAX_RX_DESCR * sizeof(struct macb_dma_desc),
 					&lp->rx_ring_dma, GFP_KERNEL);
 	if (!lp->rx_ring) {
 		netdev_err(lp->dev, "unable to alloc rx ring DMA buffer\n");
@@ -170,7 +170,7 @@ static int at91ether_start(struct net_device *dev)
 		netdev_err(lp->dev, "unable to alloc rx data DMA buffer\n");
 
 		dma_free_coherent(&lp->pdev->dev,
-					MAX_RX_DESCR * sizeof(struct dma_desc),
+					MAX_RX_DESCR * sizeof(struct macb_dma_desc),
 					lp->rx_ring, lp->rx_ring_dma);
 		lp->rx_ring = NULL;
 		return -ENOMEM;
@@ -256,7 +256,7 @@ static int at91ether_close(struct net_device *dev)
 	netif_stop_queue(dev);
 
 	dma_free_coherent(&lp->pdev->dev,
-				MAX_RX_DESCR * sizeof(struct dma_desc),
+				MAX_RX_DESCR * sizeof(struct macb_dma_desc),
 				lp->rx_ring, lp->rx_ring_dma);
 	lp->rx_ring = NULL;
 
-- 
1.8.0

^ permalink raw reply related

* [PATCH v2] ARM: zynq: Allow UART1 to be used as DEBUG_LL console.
From: Michal Simek @ 2012-10-30 11:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351534769-22155-1-git-send-email-nbowler@elliptictech.com>

On 10/29/2012 07:19 PM, Nick Bowler wrote:
> The main UART on the Xilinx ZC702 board is UART1, located at address
> e0001000.  Add a Kconfig option to select this device as the low-level
> debugging port.  This allows the really early boot printouts to reach
> the USB serial adaptor on this board.
>
> For consistency's sake, add a choice entry for UART0 even though it is
> the the default if UART1 is not selected.
>
> Signed-off-by: Nick Bowler <nbowler@elliptictech.com>
> Tested-by: Josh Cartwright <josh.cartwright@ni.com>
> ---
> v2: rebase on newest patch series, signoff.
>
> This should apply cleanly on top of Josh Cartwright's v5 "zynq subarch
> cleanups" series.
>
>   arch/arm/Kconfig.debug                     |   17 +++++++++++++++++
>   arch/arm/mach-zynq/common.c                |    6 +++---
>   arch/arm/mach-zynq/include/mach/zynq_soc.h |   16 +++++++++++-----
>   3 files changed, 31 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
> index b0f3857b3a4c..7754d51f2b19 100644
> --- a/arch/arm/Kconfig.debug
> +++ b/arch/arm/Kconfig.debug
> @@ -132,6 +132,23 @@ choice
>   		  their output to UART1 serial port on DaVinci TNETV107X
>   		  devices.
>
> +	config DEBUG_ZYNQ_UART0
> +		bool "Kernel low-level debugging on Xilinx Zynq using UART0"
> +		depends on ARCH_ZYNQ
> +		help
> +		  Say Y here if you want the debug print routines to direct
> +		  their output to UART0 on the Zynq platform.
> +
> +	config DEBUG_ZYNQ_UART1
> +		bool "Kernel low-level debugging on Xilinx Zynq using UART1"
> +		depends on ARCH_ZYNQ
> +		help
> +		  Say Y here if you want the debug print routines to direct
> +		  their output to UART1 on the Zynq platform.
> +
> +		  If you have a ZC702 board and want early boot messages to
> +		  appear on the USB serial adaptor, select this option.
> +
>   	config DEBUG_DC21285_PORT
>   		bool "Kernel low-level debugging messages via footbridge serial port"
>   		depends on FOOTBRIDGE
> diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
> index ba8d14f78d4d..93b91059faab 100644
> --- a/arch/arm/mach-zynq/common.c
> +++ b/arch/arm/mach-zynq/common.c
> @@ -84,9 +84,9 @@ static struct map_desc io_desc[] __initdata = {
>
>   #ifdef CONFIG_DEBUG_LL
>   	{
> -		.virtual	= UART0_VIRT,
> -		.pfn		= __phys_to_pfn(UART0_PHYS),
> -		.length		= UART0_SIZE,
> +		.virtual	= LL_UART_VADDR,
> +		.pfn		= __phys_to_pfn(LL_UART_PADDR),
> +		.length		= UART_SIZE,
>   		.type		= MT_DEVICE,
>   	},
>   #endif
> diff --git a/arch/arm/mach-zynq/include/mach/zynq_soc.h b/arch/arm/mach-zynq/include/mach/zynq_soc.h
> index 1b8bf0ecbcb0..7f4f38bcada9 100644
> --- a/arch/arm/mach-zynq/include/mach/zynq_soc.h
> +++ b/arch/arm/mach-zynq/include/mach/zynq_soc.h
> @@ -25,8 +25,9 @@
>    * address that is known to work.
>    */
>   #define UART0_PHYS		0xE0000000
> -#define UART0_SIZE		SZ_4K
> -#define UART0_VIRT		0xF0001000
> +#define UART1_PHYS		0xE0001000
> +#define UART_SIZE		SZ_4K
> +#define UART_VIRT		0xF0001000
>
>   #define TTC0_PHYS		0xF8001000
>   #define TTC0_SIZE		SZ_4K
> @@ -36,12 +37,17 @@
>   #define SCU_PERIPH_SIZE		SZ_8K
>   #define SCU_PERIPH_VIRT		(TTC0_VIRT - SCU_PERIPH_SIZE)
>
> +#if IS_ENABLED(CONFIG_DEBUG_ZYNQ_UART1)
> +#	define LL_UART_PADDR	UART1_PHYS
> +#	define LL_UART_VADDR	UART_VIRT
> +#else
> +#	define LL_UART_PADDR	UART0_PHYS
> +#	define LL_UART_VADDR	UART_VIRT
> +#endif

Probably no reason to setup LL_UART_VADDR on two lines.
It is enough to set it up once.

MINOR: It is just my personal preference to use different coding style.

#if IS_ENABLED(CONFIG_DEBUG_ZYNQ_UART1)
# define LL_UART_PADDR	UART1_PHYS
#else
# define LL_UART_PADDR	UART0_PHYS
#endif

#define LL_UART_VADDR	UART_VIRT

Thanks,
Michal

-- 
Michal Simek, Ing. (M.Eng)
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel 2.6 Microblaze Linux - http://www.monstr.eu/fdt/
Microblaze U-BOOT custodian

^ permalink raw reply

* [PATCH v3 00/10] net/macb: driver enhancement concerning GEM support, ring logic and cleanup
From: Nicolas Ferre @ 2012-10-30 11:26 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cover.1351591858.git.nicolas.ferre@atmel.com>

On 10/30/2012 11:17 AM, Nicolas Ferre :
> This is an enhancement work that began several years ago. I try to catchup with
> some performance improvement that has been implemented then by Havard.
> The ring index logic and the TX error path modification are the biggest changes
> but some cleanup/debugging have been added along the way.
> The GEM revision will benefit from the Gigabit support.
> Newer pinctrl infrastructure support is added but it is optional.
> 
> The series has been tested on several Atmel AT91 SoC with the two MACB/GEM
> flavors.
> 
> v3: - rebased on net-next to take into account current effor to merge
>       at91_ether with macb drivers
>     - add additional patch to use the new pinctrl infrastructure
> v2: - modify the tx error handling: now uses a workqueue
>     - information provided by ethtool -i were not accurate: removed

David, if you feel more comfortable with a git branch (I can also 
cook a signed tag if you want), here it is:


The following changes since commit a932657f51eadb8280166e82dc7034dfbff3985a:

  net: sierra: shut up sparse restricted type warnings (2012-10-28 19:09:02 -0400)

are available in the git repository at:

  git://github.com/at91linux/linux-at91.git net-next_macb_enhancement3

for you to fetch changes up to 3269426bdd44debc00d027651f8248db9d40f3dc:

  net/macb: add pinctrl consumer support (2012-10-30 11:08:10 +0100)

----------------------------------------------------------------
Havard Skinnemoen (4):
      net/macb: memory barriers cleanup
      net/macb: change debugging messages
      net/macb: clean up ring buffer logic
      net/macb: Offset first RX buffer by two bytes

Jean-Christophe PLAGNIOL-VILLARD (1):
      net/macb: add pinctrl consumer support

Nicolas Ferre (4):
      net/macb: remove macb_get_drvinfo()
      net/macb: tx status is more than 8 bits now
      net/macb: ethtool interface: add register dump feature
      net/macb: better manage tx errors

Patrice Vilchez (1):
      net/macb: Add support for Gigabit Ethernet mode

 drivers/net/ethernet/cadence/macb.c | 446 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
 drivers/net/ethernet/cadence/macb.h |  30 ++++--
 2 files changed, 334 insertions(+), 142 deletions(-)


Thanks, best regards,
-- 
Nicolas Ferre

^ permalink raw reply

* [PATCH 0/2] ARM: OMAP: hwmod/omapd_device: Fix for resource handling in DT boot
From: Paul Walmsley @ 2012-10-30 11:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351593205-13590-1-git-send-email-peter.ujfalusi@ti.com>

On Tue, 30 Oct 2012, Peter Ujfalusi wrote:

> Tony, Benoit, Paul: Not sure if this qualify for 3.7 inclusion, but for sure
> going to help us to clean up the OMAP5 hwmod database.

It's definitely not 3.7 material, but will look at it for 3.8 merge 
window.  The OMAP5 hwmod data isn't in mainline yet.


- Paul

^ permalink raw reply

* [PATCH v2 2/2] ARM: OMAP: omap_device: Correct resource handling for DT boot
From: Peter Ujfalusi @ 2012-10-30 11:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351596296-13825-1-git-send-email-peter.ujfalusi@ti.com>

When booting with DT the OF core can fill up the resources provided within
the DT blob.
The current way of handling the DT boot prevents us from removing hwmod data
for platforms only suppose to boot with DT (OMAP5 for example) since we need
to keep the whole hwmod database intact in order to have more resources in
hwmod than in DT (to be able to append the DMA resource from hwmod).

To fix this issue we just examine the OF provided resources:
If we do not have resources we use hwmod to fill them.
If we have resources we check if we already able to recive DMA resource, if
no we only append the DMA resurce from hwmod to the OF provided ones.

In this way we can start removing hwmod data for devices which have their
resources correctly configured in DT without regressions.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 arch/arm/plat-omap/omap_device.c | 84 ++++++++++++++++++++++++----------------
 1 file changed, 51 insertions(+), 33 deletions(-)

diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 915cf68..d35b468 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -560,55 +560,73 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
 	od->hwmods = hwmods;
 	od->pdev = pdev;
 
-	/* Count all resources for the device */
-	res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
-						    IORESOURCE_DMA |
-						    IORESOURCE_MEM);
 	/*
+	 * Non-DT Boot:
+	 *   Here, pdev->num_resources = 0, and we should get all the
+	 *   resources from hwmod.
+	 *
 	 * DT Boot:
 	 *   OF framework will construct the resource structure (currently
 	 *   does for MEM & IRQ resource) and we should respect/use these
 	 *   resources, killing hwmod dependency.
 	 *   If pdev->num_resources > 0, we assume that MEM & IRQ resources
 	 *   have been allocated by OF layer already (through DTB).
-	 *
-	 * Non-DT Boot:
-	 *   Here, pdev->num_resources = 0, and we should get all the
-	 *   resources from hwmod.
+	 *   As preparation for the future we examine the OF provided resources
+	 *   to see if we have DMA resources provided already. In this case
+	 *   there is no need to update the resources for the device, we use the
+	 *   OF provided ones.
 	 *
 	 * TODO: Once DMA resource is available from OF layer, we should
 	 *   kill filling any resources from hwmod.
 	 */
-	if (res_count > pdev->num_resources) {
-		/* Allocate resources memory to account for new resources */
-		res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
-		if (!res)
-			goto oda_exit3;
-
-		/*
-		 * If pdev->num_resources > 0, then assume that,
-		 * MEM and IRQ resources will only come from DT and only
-		 * fill DMA resource from hwmod layer.
-		 */
-		if (pdev->num_resources && pdev->resource) {
-			dev_dbg(&pdev->dev, "%s(): resources already allocated %d\n",
-				__func__, res_count);
-			memcpy(res, pdev->resource,
-			       sizeof(struct resource) * pdev->num_resources);
-			_od_fill_dma_resources(od, &res[pdev->num_resources]);
-		} else {
-			dev_dbg(&pdev->dev, "%s(): using resources from hwmod %d\n",
-				__func__, res_count);
-			omap_device_fill_resources(od, res);
+	if (!pdev->num_resources) {
+		/* Count all resources for the device */
+		res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
+							    IORESOURCE_DMA |
+							    IORESOURCE_MEM);
+	} else {
+		/* Take a look if we already have DMA resource via DT */
+		for (i = 0; i < pdev->num_resources; i++) {
+			struct resource *r = &pdev->resource[i];
+
+			/* We have it, no need to touch the resources */
+			if (r->flags == IORESOURCE_DMA)
+				goto have_everything;
 		}
+		/* Count only DMA resources for the device */
+		res_count = omap_device_count_resources(od, IORESOURCE_DMA);
+		/* The device has no DMA resource, no need for update */
+		if (!res_count)
+			goto have_everything;
+	
+		res_count += pdev->num_resources;
+	}
 
-		ret = platform_device_add_resources(pdev, res, res_count);
-		kfree(res);
+	/* Allocate resources memory to account for new resources */
+	res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
+	if (!res)
+		goto oda_exit3;
 
-		if (ret)
-			goto oda_exit3;
+	if (!pdev->num_resources) {
+		dev_dbg(&pdev->dev, "%s: using %d resources from hwmod\n",
+			__func__, res_count);
+		omap_device_fill_resources(od, res);
+	} else {
+		dev_dbg(&pdev->dev,
+			"%s: appending %d DMA resources from hwmod\n",
+			__func__, res_count - pdev->num_resources);
+		memcpy(res, pdev->resource,
+		       sizeof(struct resource) * pdev->num_resources);
+		_od_fill_dma_resources(od, &res[pdev->num_resources]);
 	}
 
+	ret = platform_device_add_resources(pdev, res, res_count);
+	kfree(res);
+
+	if (ret)
+		goto oda_exit3;
+
+have_everything:
 	if (!pm_lats) {
 		pm_lats = omap_default_latency;
 		pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH v2 1/2] ARM: OMAP: hwmod: Add possibility to count hwmod resources based on type
From: Peter Ujfalusi @ 2012-10-30 11:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1351596296-13825-1-git-send-email-peter.ujfalusi@ti.com>

Add flags parameter for omap_hwmod_count_resources() so users can tell which
type of resources they are interested when counting them in hwmod database.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 arch/arm/mach-omap2/omap_hwmod.c             | 27 ++++++++++++++++-----------
 arch/arm/plat-omap/include/plat/omap_hwmod.h |  2 +-
 arch/arm/plat-omap/omap_device.c             | 11 ++++++++---
 3 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index b969ab1..a79c941 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -3337,7 +3337,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
 /**
  * omap_hwmod_count_resources - count number of struct resources needed by hwmod
  * @oh: struct omap_hwmod *
- * @res: pointer to the first element of an array of struct resource to fill
+ * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
  *
  * Count the number of struct resource array elements necessary to
  * contain omap_hwmod @oh resources.  Intended to be called by code
@@ -3350,20 +3350,25 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
  * resource IDs.
  *
  */
-int omap_hwmod_count_resources(struct omap_hwmod *oh)
+int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags)
 {
-	struct omap_hwmod_ocp_if *os;
-	struct list_head *p;
-	int ret;
-	int i = 0;
+	int ret = 0;
 
-	ret = _count_mpu_irqs(oh) + _count_sdma_reqs(oh);
+	if (flags & IORESOURCE_IRQ)
+		ret += _count_mpu_irqs(oh);
 
-	p = oh->slave_ports.next;
+	if (flags & IORESOURCE_DMA)
+		ret += _count_sdma_reqs(oh);
 
-	while (i < oh->slaves_cnt) {
-		os = _fetch_next_ocp_if(&p, &i);
-		ret += _count_ocp_if_addr_spaces(os);
+	if (flags & IORESOURCE_MEM) {
+		int i = 0;
+		struct omap_hwmod_ocp_if *os;
+		struct list_head *p = oh->slave_ports.next;
+
+		while (i < oh->slaves_cnt) {
+			os = _fetch_next_ocp_if(&p, &i);
+			ret += _count_ocp_if_addr_spaces(os);
+		}
 	}
 
 	return ret;
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index b3349f7..48a6f5d 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -628,7 +628,7 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs);
 u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs);
 int omap_hwmod_softreset(struct omap_hwmod *oh);
 
-int omap_hwmod_count_resources(struct omap_hwmod *oh);
+int omap_hwmod_count_resources(struct omap_hwmod *oh, unsigned long flags);
 int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
 int omap_hwmod_fill_dma_resources(struct omap_hwmod *oh, struct resource *res);
 int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 7a7d1f2..915cf68 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -442,19 +442,21 @@ int omap_device_get_context_loss_count(struct platform_device *pdev)
 /**
  * omap_device_count_resources - count number of struct resource entries needed
  * @od: struct omap_device *
+ * @flags: Type of resources to include when counting (IRQ/DMA/MEM)
  *
  * Count the number of struct resource entries needed for this
  * omap_device @od.  Used by omap_device_build_ss() to determine how
  * much memory to allocate before calling
  * omap_device_fill_resources().  Returns the count.
  */
-static int omap_device_count_resources(struct omap_device *od)
+static int omap_device_count_resources(struct omap_device *od,
+				       unsigned long flags)
 {
 	int c = 0;
 	int i;
 
 	for (i = 0; i < od->hwmods_cnt; i++)
-		c += omap_hwmod_count_resources(od->hwmods[i]);
+		c += omap_hwmod_count_resources(od->hwmods[i], flags);
 
 	pr_debug("omap_device: %s: counted %d total resources across %d hwmods\n",
 		 od->pdev->name, c, od->hwmods_cnt);
@@ -558,7 +560,10 @@ struct omap_device *omap_device_alloc(struct platform_device *pdev,
 	od->hwmods = hwmods;
 	od->pdev = pdev;
 
-	res_count = omap_device_count_resources(od);
+	/* Count all resources for the device */
+	res_count = omap_device_count_resources(od, IORESOURCE_IRQ |
+						    IORESOURCE_DMA |
+						    IORESOURCE_MEM);
 	/*
 	 * DT Boot:
 	 *   OF framework will construct the resource structure (currently
-- 
1.7.12.4

^ permalink raw reply related

* [PATCH v2 0/2] ARM: OMAP: hwmod/omapd_device: Fix for resource handling in DT boot
From: Peter Ujfalusi @ 2012-10-30 11:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

Changes since v1:
- If the device does not have DMA resource do not try to recreate the resources

Intro mail from v1:

This series resolves the issue we currently have with the resource handling when
booting with DT.
In short: at the moment the omap_device_alloc() decides if it needs to update the
OF filled resources based on the number of resources on the device and in the
hwmod database.
This prevents us from removing hwmod data for platforms (OMAP5) which does not
support non DT boot anymore.

With this series we can make sure that the DT provided resources are used and we
only append the DMA resources to the device from hwmod.
I have added extra check to prepare us when the DMA resource can be filled via
OF. In this case we do not update the resources at all.

Tony, Benoit, Paul: Not sure if this qualify for 3.7 inclusion, but for sure
going to help us to clean up the OMAP5 hwmod database.

Regards,
Peter
---
Peter Ujfalusi (2):
  ARM: OMAP: hwmod: Add possibility to count hwmod resources based on
    type
  ARM: OMAP: omap_device: Correct resource handling for DT boot

 arch/arm/mach-omap2/omap_hwmod.c             | 27 +++++----
 arch/arm/plat-omap/include/plat/omap_hwmod.h |  2 +-
 arch/arm/plat-omap/omap_device.c             | 87 ++++++++++++++++++----------
 3 files changed, 72 insertions(+), 44 deletions(-)

-- 
1.7.12.4

^ permalink raw reply

* [PATCHv2] Input: omap4-keypad: Add pinctrl support
From: Mark Brown @ 2012-10-30 11:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20121029194901.GA30152@arwen.pp.htv.fi>

On Mon, Oct 29, 2012 at 09:49:01PM +0200, Felipe Balbi wrote:
> On Fri, Oct 26, 2012 at 05:03:16PM +0100, Mark Brown wrote:

> > You could have the driver explicitly set the flag, it would just be one
> > extra line, but it seems marginally nicer to just do it.

> You didn't get the whole picture I'm afraid. Consider the situation
> where the same e.g. keypad driver is being used on OMAP4 and OMAP5 and
> those have different requirements towards pinctrl.

No, I'm pretty certain that I do.

> Now, we need to add OMAP5 support *to the same keypad driver*.
> Unfortunately, OMAP5 needs to handle pinctrl explicitly for whatever
> reason (SW-controlled sleep mode, errata fix, whatever).

> This will mean that we will have to remove the flag from the keypad
> driver because that's not valid anymore for OMAP5.

This isn't a problem; either the pinctrl code for OMAP5 will do
something sensible for OMAP4 in which case there's no difference to the
resulting code or you're going to have to have conditional code for the
two devices anyway and you're no worse off.

> This is why I think hiding things from drivers makes no sense. Also
> consider the situations Linus W exposed on another subthread. If you
> change ordering of certain calls, you will really break the
> functionality of the IP. Because we can't make sure this won't work
> automagically in all cases (just like we can't make sure $size memory
> allocation is enough for all drivers) we don't hide that from the
> driver. We require driver to manage its resources properly.

We need some place to put the SoC integration; power domains seem like
the obvious place to me but YMMV.  Nothing about having this out of the
drivers requires that this be done by individual subsystems in isolation
from each other.  Half the point here is that for the reusable IPs this
stuff often isn't driver specific at all, it's often more about the SoC
integration than it is about the driver and so you'll get a consistent
pattern for most IPs on the SoC.

> How can you make sure that this will work for at least 50% of the
> drivers ? You just can't. We don't know the implementation details of
> every arch/soc/platform supported by Linux today to make that decision.

Well, we've managed to get along for rather a long time with essentially
all architectures implementing this stuff by doing static setup for the
pins on boot.  That does suggest we can get a reasonably long way with
something simple, and it does seem to match up with how things usually
look at an electrical level too.

It seems fairly obvious that if we need to add identical bolier plate
code to lots of drivers we're doing something wrong, it's just churn for
little practical gain and a problem if we ever decide to change how this
stuff works in the future.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20121030/89953e6b/attachment.sig>

^ permalink raw reply

* OMAP baseline test results for v3.7-rc1
From: Paul Walmsley @ 2012-10-30 11:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAORVsuWt22yRy9cHAU1u+9K7Fy4Zi95UN4wOh2DeVe61S-u5Cg@mail.gmail.com>

Hi Jean,

On Tue, 30 Oct 2012, Jean Pihet wrote:

> On Tue, Oct 30, 2012 at 5:16 AM, Paul Walmsley <paul@pwsan.com> wrote:
> > On Tue, 23 Oct 2012, Jean Pihet wrote:
> >
> >> Let me try with the same setup as yours (bootloader images,
> >> omap2pus_defconfig, angstrom roots).
> >
> > Had any luck reproducing this one that Aaro & I are seeing?
> Unfortunately not. I could not reproduce the issue on my side, using
> an ES2.1 Beagleboard with the latest l-o kernel and your bootloader
> and rootfs images.
> Is there some specific to enable in order to reproduce the issue?

Could you please post a bootlog from your terminal program, similar to 

http://www.pwsan.com/omap/testlogs/test_v3.7-rc3/20121028162003/boot/3530es3beagle/3530es3beagle_log.txt

?


- Paul

^ permalink raw reply

* [PATCH V2] ARM: mx28: Skip OCOTP FEC MAC setup if in DT
From: Shawn Guo @ 2012-10-30 11:21 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <201210301146.34506.marex@denx.de>

On Tue, Oct 30, 2012 at 11:46:34AM +0100, Marek Vasut wrote:
> Dear Shawn Guo,
> 
> > On Fri, Oct 26, 2012 at 12:01:58PM +0200, Marek Vasut wrote:
> > > Can we apply this for 3.7?
> > 
> > You meant for 3.8?
> 
> 3.7 would be nice, but it's too late now.
> 
Applied for 3.8.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox