Merge branches 'at91', 'ep93xx', 'etm', 'ks8695', 'nuc', 'u300' and 'u8500' into...
authorRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 5 Dec 2009 10:35:18 +0000 (10:35 +0000)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 5 Dec 2009 10:35:18 +0000 (10:35 +0000)
279 files changed:
.gitignore
Documentation/fb/framebuffer.txt
Documentation/filesystems/caching/fscache.txt
Documentation/filesystems/caching/netfs-api.txt
Documentation/slow-work.txt
MAINTAINERS
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/Makefile
arch/arm/common/dmabounce.c
arch/arm/configs/at91rm9200dk_defconfig
arch/arm/configs/nuc910_defconfig [new file with mode: 0644]
arch/arm/configs/nuc950_defconfig [new file with mode: 0644]
arch/arm/configs/nuc960_defconfig [new file with mode: 0644]
arch/arm/configs/u8500_defconfig [new file with mode: 0644]
arch/arm/configs/w90p910_defconfig [deleted file]
arch/arm/include/asm/cacheflush.h
arch/arm/include/asm/dma-mapping.h
arch/arm/include/asm/hardware/coresight.h [new file with mode: 0644]
arch/arm/include/asm/kmap_types.h
arch/arm/include/asm/memory.h
arch/arm/include/asm/pgtable.h
arch/arm/include/asm/swab.h
arch/arm/include/asm/system.h
arch/arm/kernel/Makefile
arch/arm/kernel/etm.c [new file with mode: 0644]
arch/arm/kernel/signal.c
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/at91sam9g45_devices.c
arch/arm/mach-at91/board-eco920.c [new file with mode: 0644]
arch/arm/mach-at91/board-sam9m10g45ek.c
arch/arm/mach-at91/cpuidle.c [new file with mode: 0644]
arch/arm/mach-at91/include/mach/board.h
arch/arm/mach-at91/pm.c
arch/arm/mach-at91/pm.h [new file with mode: 0644]
arch/arm/mach-bcmring/include/mach/io.h
arch/arm/mach-iop13xx/include/mach/memory.h
arch/arm/mach-ks8695/include/mach/memory.h
arch/arm/mach-nomadik/Kconfig
arch/arm/mach-nomadik/Makefile
arch/arm/mach-nomadik/board-nhk8815.c
arch/arm/mach-nomadik/include/mach/mtu.h [deleted file]
arch/arm/mach-nomadik/include/mach/setup.h
arch/arm/mach-nomadik/timer.c [deleted file]
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/clock34xx.c
arch/arm/mach-omap2/emu.c [new file with mode: 0644]
arch/arm/mach-pxa/cpufreq-pxa2xx.c
arch/arm/mach-pxa/cpufreq-pxa3xx.c
arch/arm/mach-pxa/spitz.c
arch/arm/mach-u300/Makefile
arch/arm/mach-u300/i2c.c
arch/arm/mach-u300/mmc.c
arch/arm/mach-u300/regulator.c [new file with mode: 0644]
arch/arm/mach-ux500/Kconfig [new file with mode: 0644]
arch/arm/mach-ux500/Makefile [new file with mode: 0644]
arch/arm/mach-ux500/Makefile.boot [new file with mode: 0644]
arch/arm/mach-ux500/board-mop500.c [new file with mode: 0644]
arch/arm/mach-ux500/clock.c [new file with mode: 0644]
arch/arm/mach-ux500/cpu-u8500.c [new file with mode: 0644]
arch/arm/mach-ux500/headsmp.S [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/clkdev.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/debug-macro.S [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/entry-macro.S [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/hardware.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/io.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/irqs.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/memory.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/setup.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/smp.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/system.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/timex.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/uncompress.h [new file with mode: 0644]
arch/arm/mach-ux500/include/mach/vmalloc.h [new file with mode: 0644]
arch/arm/mach-ux500/localtimer.c [new file with mode: 0644]
arch/arm/mach-ux500/platsmp.c [new file with mode: 0644]
arch/arm/mach-w90x900/dev.c
arch/arm/mm/Kconfig
arch/arm/mm/Makefile
arch/arm/mm/cache-l2x0.c
arch/arm/mm/copypage-v6.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/fault-armv.c
arch/arm/mm/flush.c
arch/arm/mm/mm.h
arch/arm/mm/mmu.c
arch/arm/mm/vmregion.c [new file with mode: 0644]
arch/arm/mm/vmregion.h [new file with mode: 0644]
arch/arm/plat-nomadik/Kconfig [new file with mode: 0644]
arch/arm/plat-nomadik/Makefile [new file with mode: 0644]
arch/arm/plat-nomadik/include/plat/mtu.h [new file with mode: 0644]
arch/arm/plat-nomadik/timer.c [new file with mode: 0644]
arch/arm/plat-omap/include/mach/memory.h
arch/arm/tools/mach-types
arch/blackfin/kernel/bfin_dma_5xx.c
arch/blackfin/kernel/cplb-mpu/cplbinit.c
arch/blackfin/kernel/process.c
arch/blackfin/kernel/ptrace.c
arch/blackfin/mach-bf518/include/mach/anomaly.h
arch/blackfin/mach-bf527/include/mach/anomaly.h
arch/blackfin/mach-bf533/include/mach/anomaly.h
arch/blackfin/mach-bf537/include/mach/anomaly.h
arch/blackfin/mach-bf538/include/mach/anomaly.h
arch/blackfin/mach-bf548/include/mach/anomaly.h
arch/blackfin/mach-bf561/atomic.S
arch/blackfin/mach-bf561/include/mach/anomaly.h
arch/blackfin/mach-common/arch_checks.c
arch/blackfin/mach-common/smp.c
arch/parisc/kernel/unwind.c
arch/parisc/kernel/vmlinux.lds.S
arch/powerpc/include/asm/kmap_types.h
arch/sparc/mm/init_64.h
arch/x86/kernel/acpi/processor.c
crypto/async_tx/Kconfig
crypto/async_tx/async_pq.c
crypto/async_tx/async_xor.c
crypto/gcm.c
drivers/acpi/acpica/acpredef.h
drivers/acpi/blacklist.c
drivers/acpi/sleep.c
drivers/ata/sata_fsl.c
drivers/base/power/runtime.c
drivers/block/cciss.c
drivers/char/agp/intel-agp.c
drivers/char/keyboard.c
drivers/crypto/padlock-aes.c
drivers/dma/Kconfig
drivers/dma/dmaengine.c
drivers/dma/ioat/dca.c
drivers/dma/ioat/dma.h
drivers/dma/ioat/dma_v2.c
drivers/dma/ioat/dma_v3.c
drivers/dma/ioat/hw.h
drivers/dma/ioat/registers.h
drivers/dma/shdma.c
drivers/firewire/ohci.c
drivers/gpu/drm/Kconfig
drivers/gpu/drm/drm_edid.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/drm_gem.c
drivers/gpu/drm/drm_mm.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/i915/intel_crt.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/radeon/atom.c
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_agp.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_device.c
drivers/gpu/drm/radeon/rv515.c
drivers/i2c/busses/i2c-pnx.c
drivers/i2c/chips/tsl2550.c
drivers/i2c/i2c-core.c
drivers/ide/ide-ioctls.c
drivers/ieee802154/fakehard.c
drivers/media/common/ir-functions.c
drivers/media/dvb/dvb-usb/cxusb.c
drivers/media/dvb/siano/Kconfig
drivers/media/radio/radio-gemtek-pci.c
drivers/media/video/davinci/vpif_display.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/mx1_camera.c
drivers/media/video/mx3_camera.c
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/soc_camera.c
drivers/media/video/videobuf-dma-contig.c
drivers/misc/eeprom/at24.c
drivers/mmc/host/mmci.c
drivers/net/Kconfig
drivers/net/arm/ep93xx_eth.c
drivers/net/au1000_eth.c
drivers/net/b44.c
drivers/net/davinci_emac.c
drivers/net/e100.c
drivers/net/e1000e/e1000.h
drivers/net/e1000e/ethtool.c
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/netdev.c
drivers/net/e1000e/phy.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ks8851_mll.c
drivers/net/macvlan.c
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_hdr.h
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/r8169.c
drivers/net/smc91x.c
drivers/net/smsc9420.c
drivers/net/stmmac/stmmac_main.c
drivers/net/stmmac/stmmac_timer.c
drivers/net/stmmac/stmmac_timer.h
drivers/net/usb/hso.c
drivers/net/veth.c
drivers/net/wan/cosa.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/platform/x86/acerhdf.c
drivers/platform/x86/thinkpad_acpi.c
drivers/scsi/hosts.c
drivers/scsi/scsi_scan.c
drivers/scsi/scsi_sysfs.c
drivers/scsi/sd_dif.c
drivers/serial/suncore.c
drivers/serial/suncore.h
drivers/serial/sunhv.c
drivers/serial/sunsab.c
drivers/serial/sunsu.c
drivers/serial/sunzilog.c
drivers/staging/go7007/s2250-board.c
drivers/staging/go7007/s2250-loader.h [new file with mode: 0644]
drivers/staging/octeon/ethernet-mdio.c
drivers/staging/octeon/ethernet-spi.c
drivers/staging/octeon/ethernet.c
drivers/watchdog/pnx4008_wdt.c
fs/9p/cache.c
fs/afs/file.c
fs/cachefiles/interface.c
fs/cachefiles/namei.c
fs/cachefiles/rdwr.c
fs/cifs/CHANGES
fs/cifs/cifsfs.c
fs/cifs/dir.c
fs/fscache/Kconfig
fs/fscache/Makefile
fs/fscache/cache.c
fs/fscache/cookie.c
fs/fscache/internal.h
fs/fscache/main.c
fs/fscache/object-list.c [new file with mode: 0644]
fs/fscache/object.c
fs/fscache/operation.c
fs/fscache/page.c
fs/fscache/proc.c
fs/fscache/stats.c
fs/fuse/dir.c
fs/gfs2/main.c
fs/gfs2/recovery.c
fs/jffs2/read.c
fs/nfs/fscache.c
include/linux/fscache-cache.h
include/linux/fscache.h
include/linux/slow-work.h
include/net/mac80211.h
include/net/sctp/structs.h
include/scsi/scsi_device.h
init/Kconfig
kernel/Makefile
kernel/slow-work-proc.c [new file with mode: 0644]
kernel/slow-work.c
kernel/slow-work.h [new file with mode: 0644]
lib/radix-tree.c
mm/backing-dev.c
net/core/pktgen.c
net/ipv4/ip_fragment.c
net/mac80211/agg-rx.c
net/mac80211/agg-tx.c
net/mac80211/ht.c
net/mac80211/ieee80211_i.h
net/mac80211/util.c
net/netfilter/nf_log.c
net/netfilter/xt_limit.c
net/netfilter/xt_osf.c
net/rfkill/core.c
net/sctp/outqueue.c
net/sctp/sm_sideeffect.c
net/sctp/transport.c
scripts/kconfig/Makefile
scripts/kconfig/streamline_config.pl
sound/arm/aaci.c
sound/soc/codecs/tlv320aic23.c
sound/soc/soc-dapm.c

index b93fb7e..946c7ec 100644 (file)
@@ -25,6 +25,7 @@
 *.elf
 *.bin
 *.gz
+*.bz2
 *.lzma
 *.patch
 *.gcno
index b3e3a03..fe79e3c 100644 (file)
@@ -312,10 +312,8 @@ and to the following documentation:
 8. Mailing list
 ---------------
 
-There are several frame buffer device related mailing lists at SourceForge:
-  - linux-fbdev-announce@lists.sourceforge.net, for announcements,
-  - linux-fbdev-user@lists.sourceforge.net, for generic user support,
-  - linux-fbdev-devel@lists.sourceforge.net, for project developers.
+There is a frame buffer device related mailing list at kernel.org:
+linux-fbdev@vger.kernel.org.
 
 Point your web browser to http://sourceforge.net/projects/linux-fbdev/ for
 subscription information and archive browsing.
index 9e94b94..a91e2e2 100644 (file)
@@ -235,6 +235,7 @@ proc files.
                neg=N   Number of negative lookups made
                pos=N   Number of positive lookups made
                crt=N   Number of objects created by lookup
+               tmo=N   Number of lookups timed out and requeued
        Updates n=N     Number of update cookie requests seen
                nul=N   Number of upd reqs given a NULL parent
                run=N   Number of upd reqs granted CPU time
@@ -250,8 +251,10 @@ proc files.
                ok=N    Number of successful alloc reqs
                wt=N    Number of alloc reqs that waited on lookup completion
                nbf=N   Number of alloc reqs rejected -ENOBUFS
+               int=N   Number of alloc reqs aborted -ERESTARTSYS
                ops=N   Number of alloc reqs submitted
                owt=N   Number of alloc reqs waited for CPU time
+               abt=N   Number of alloc reqs aborted due to object death
        Retrvls n=N     Number of retrieval (read) requests seen
                ok=N    Number of successful retr reqs
                wt=N    Number of retr reqs that waited on lookup completion
@@ -261,6 +264,7 @@ proc files.
                oom=N   Number of retr reqs failed -ENOMEM
                ops=N   Number of retr reqs submitted
                owt=N   Number of retr reqs waited for CPU time
+               abt=N   Number of retr reqs aborted due to object death
        Stores  n=N     Number of storage (write) requests seen
                ok=N    Number of successful store reqs
                agn=N   Number of store reqs on a page already pending storage
@@ -268,12 +272,37 @@ proc files.
                oom=N   Number of store reqs failed -ENOMEM
                ops=N   Number of store reqs submitted
                run=N   Number of store reqs granted CPU time
+               pgs=N   Number of pages given store req processing time
+               rxd=N   Number of store reqs deleted from tracking tree
+               olm=N   Number of store reqs over store limit
+       VmScan  nos=N   Number of release reqs against pages with no pending store
+               gon=N   Number of release reqs against pages stored by time lock granted
+               bsy=N   Number of release reqs ignored due to in-progress store
+               can=N   Number of page stores cancelled due to release req
        Ops     pend=N  Number of times async ops added to pending queues
                run=N   Number of times async ops given CPU time
                enq=N   Number of times async ops queued for processing
+               can=N   Number of async ops cancelled
+               rej=N   Number of async ops rejected due to object lookup/create failure
                dfr=N   Number of async ops queued for deferred release
                rel=N   Number of async ops released
                gc=N    Number of deferred-release async ops garbage collected
+       CacheOp alo=N   Number of in-progress alloc_object() cache ops
+               luo=N   Number of in-progress lookup_object() cache ops
+               luc=N   Number of in-progress lookup_complete() cache ops
+               gro=N   Number of in-progress grab_object() cache ops
+               upo=N   Number of in-progress update_object() cache ops
+               dro=N   Number of in-progress drop_object() cache ops
+               pto=N   Number of in-progress put_object() cache ops
+               syn=N   Number of in-progress sync_cache() cache ops
+               atc=N   Number of in-progress attr_changed() cache ops
+               rap=N   Number of in-progress read_or_alloc_page() cache ops
+               ras=N   Number of in-progress read_or_alloc_pages() cache ops
+               alp=N   Number of in-progress allocate_page() cache ops
+               als=N   Number of in-progress allocate_pages() cache ops
+               wrp=N   Number of in-progress write_page() cache ops
+               ucp=N   Number of in-progress uncache_page() cache ops
+               dsp=N   Number of in-progress dissociate_pages() cache ops
 
 
  (*) /proc/fs/fscache/histogram
@@ -299,6 +328,87 @@ proc files.
      jiffy range covered, and the SECS field the equivalent number of seconds.
 
 
+===========
+OBJECT LIST
+===========
+
+If CONFIG_FSCACHE_OBJECT_LIST is enabled, the FS-Cache facility will maintain a
+list of all the objects currently allocated and allow them to be viewed
+through:
+
+       /proc/fs/fscache/objects
+
+This will look something like:
+
+       [root@andromeda ~]# head /proc/fs/fscache/objects
+       OBJECT   PARENT   STAT CHLDN OPS OOP IPR EX READS EM EV F S | NETFS_COOKIE_DEF TY FL NETFS_DATA       OBJECT_KEY, AUX_DATA
+       ======== ======== ==== ===== === === === == ===== == == = = | ================ == == ================ ================
+          17e4b        2 ACTV     0   0   0   0  0     0 7b  4 0 8 | NFS.fh           DT  0 ffff88001dd82820 010006017edcf8bbc93b43298fdfbe71e50b57b13a172c0117f38472, e567634700000000000000000000000063f2404a000000000000000000000000c9030000000000000000000063f2404a
+          1693a        2 ACTV     0   0   0   0  0     0 7b  4 0 8 | NFS.fh           DT  0 ffff88002db23380 010006017edcf8bbc93b43298fdfbe71e50b57b1e0162c01a2df0ea6, 420ebc4a000000000000000000000000420ebc4a0000000000000000000000000e1801000000000000000000420ebc4a
+
+where the first set of columns before the '|' describe the object:
+
+       COLUMN  DESCRIPTION
+       ======= ===============================================================
+       OBJECT  Object debugging ID (appears as OBJ%x in some debug messages)
+       PARENT  Debugging ID of parent object
+       STAT    Object state
+       CHLDN   Number of child objects of this object
+       OPS     Number of outstanding operations on this object
+       OOP     Number of outstanding child object management operations
+       IPR
+       EX      Number of outstanding exclusive operations
+       READS   Number of outstanding read operations
+       EM      Object's event mask
+       EV      Events raised on this object
+       F       Object flags
+       S       Object slow-work work item flags
+
+and the second set of columns describe the object's cookie, if present:
+
+       COLUMN          DESCRIPTION
+       =============== =======================================================
+       NETFS_COOKIE_DEF Name of netfs cookie definition
+       TY              Cookie type (IX - index, DT - data, hex - special)
+       FL              Cookie flags
+       NETFS_DATA      Netfs private data stored in the cookie
+       OBJECT_KEY      Object key      } 1 column, with separating comma
+       AUX_DATA        Object aux data } presence may be configured
+
+The data shown may be filtered by attaching the a key to an appropriate keyring
+before viewing the file.  Something like:
+
+               keyctl add user fscache:objlist <restrictions> @s
+
+where <restrictions> are a selection of the following letters:
+
+       K       Show hexdump of object key (don't show if not given)
+       A       Show hexdump of object aux data (don't show if not given)
+
+and the following paired letters:
+
+       C       Show objects that have a cookie
+       c       Show objects that don't have a cookie
+       B       Show objects that are busy
+       b       Show objects that aren't busy
+       W       Show objects that have pending writes
+       w       Show objects that don't have pending writes
+       R       Show objects that have outstanding reads
+       r       Show objects that don't have outstanding reads
+       S       Show objects that have slow work queued
+       s       Show objects that don't have slow work queued
+
+If neither side of a letter pair is given, then both are implied.  For example:
+
+       keyctl add user fscache:objlist KB @s
+
+shows objects that are busy, and lists their object keys, but does not dump
+their auxiliary data.  It also implies "CcWwRrSs", but as 'B' is given, 'b' is
+not implied.
+
+By default all objects and all fields will be shown.
+
+
 =========
 DEBUGGING
 =========
index 2666b1e..1902c57 100644 (file)
@@ -641,7 +641,7 @@ data file must be retired (see the relinquish cookie function below).
 
 Furthermore, note that this does not cancel the asynchronous read or write
 operation started by the read/alloc and write functions, so the page
-invalidation and release functions must use:
+invalidation functions must use:
 
        bool fscache_check_page_write(struct fscache_cookie *cookie,
                                      struct page *page);
@@ -654,6 +654,25 @@ to see if a page is being written to the cache, and:
 to wait for it to finish if it is.
 
 
+When releasepage() is being implemented, a special FS-Cache function exists to
+manage the heuristics of coping with vmscan trying to eject pages, which may
+conflict with the cache trying to write pages to the cache (which may itself
+need to allocate memory):
+
+       bool fscache_maybe_release_page(struct fscache_cookie *cookie,
+                                       struct page *page,
+                                       gfp_t gfp);
+
+This takes the netfs cookie, and the page and gfp arguments as supplied to
+releasepage().  It will return false if the page cannot be released yet for
+some reason and if it returns true, the page has been uncached and can now be
+released.
+
+To make a page available for release, this function may wait for an outstanding
+storage request to complete, or it may attempt to cancel the storage request -
+in which case the page will not be stored in the cache this time.
+
+
 ==========================
 INDEX AND DATA FILE UPDATE
 ==========================
index ebc50f8..52bc314 100644 (file)
@@ -41,6 +41,13 @@ expand files, provided the time taken to do so isn't too long.
 Operations of both types may sleep during execution, thus tying up the thread
 loaned to it.
 
+A further class of work item is available, based on the slow work item class:
+
+ (*) Delayed slow work items.
+
+These are slow work items that have a timer to defer queueing of the item for
+a while.
+
 
 THREAD-TO-CLASS ALLOCATION
 --------------------------
@@ -64,9 +71,11 @@ USING SLOW WORK ITEMS
 Firstly, a module or subsystem wanting to make use of slow work items must
 register its interest:
 
-        int ret = slow_work_register_user();
+        int ret = slow_work_register_user(struct module *module);
 
-This will return 0 if successful, or a -ve error upon failure.
+This will return 0 if successful, or a -ve error upon failure.  The module
+pointer should be the module interested in using this facility (almost
+certainly THIS_MODULE).
 
 
 Slow work items may then be set up by:
@@ -91,6 +100,10 @@ Slow work items may then be set up by:
 
        slow_work_init(&myitem, &myitem_ops);
 
+     or:
+
+       delayed_slow_work_init(&myitem, &myitem_ops);
+
      or:
 
        vslow_work_init(&myitem, &myitem_ops);
@@ -102,15 +115,92 @@ A suitably set up work item can then be enqueued for processing:
        int ret = slow_work_enqueue(&myitem);
 
 This will return a -ve error if the thread pool is unable to gain a reference
-on the item, 0 otherwise.
+on the item, 0 otherwise, or (for delayed work):
+
+       int ret = delayed_slow_work_enqueue(&myitem, my_jiffy_delay);
 
 
 The items are reference counted, so there ought to be no need for a flush
-operation.  When all a module's slow work items have been processed, and the
+operation.  But as the reference counting is optional, means to cancel
+existing work items are also included:
+
+       cancel_slow_work(&myitem);
+       cancel_delayed_slow_work(&myitem);
+
+can be used to cancel pending work.  The above cancel function waits for
+existing work to have been executed (or prevent execution of them, depending
+on timing).
+
+
+When all a module's slow work items have been processed, and the
 module has no further interest in the facility, it should unregister its
 interest:
 
-       slow_work_unregister_user();
+       slow_work_unregister_user(struct module *module);
+
+The module pointer is used to wait for all outstanding work items for that
+module before completing the unregistration.  This prevents the put_ref() code
+from being taken away before it completes.  module should almost certainly be
+THIS_MODULE.
+
+
+================
+HELPER FUNCTIONS
+================
+
+The slow-work facility provides a function by which it can be determined
+whether or not an item is queued for later execution:
+
+       bool queued = slow_work_is_queued(struct slow_work *work);
+
+If it returns false, then the item is not on the queue (it may be executing
+with a requeue pending).  This can be used to work out whether an item on which
+another depends is on the queue, thus allowing a dependent item to be queued
+after it.
+
+If the above shows an item on which another depends not to be queued, then the
+owner of the dependent item might need to wait.  However, to avoid locking up
+the threads unnecessarily be sleeping in them, it can make sense under some
+circumstances to return the work item to the queue, thus deferring it until
+some other items have had a chance to make use of the yielded thread.
+
+To yield a thread and defer an item, the work function should simply enqueue
+the work item again and return.  However, this doesn't work if there's nothing
+actually on the queue, as the thread just vacated will jump straight back into
+the item's work function, thus busy waiting on a CPU.
+
+Instead, the item should use the thread to wait for the dependency to go away,
+but rather than using schedule() or schedule_timeout() to sleep, it should use
+the following function:
+
+       bool requeue = slow_work_sleep_till_thread_needed(
+                       struct slow_work *work,
+                       signed long *_timeout);
+
+This will add a second wait and then sleep, such that it will be woken up if
+either something appears on the queue that could usefully make use of the
+thread - and behind which this item can be queued, or if the event the caller
+set up to wait for happens.  True will be returned if something else appeared
+on the queue and this work function should perhaps return, of false if
+something else woke it up.  The timeout is as for schedule_timeout().
+
+For example:
+
+       wq = bit_waitqueue(&my_flags, MY_BIT);
+       init_wait(&wait);
+       requeue = false;
+       do {
+               prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
+               if (!test_bit(MY_BIT, &my_flags))
+                       break;
+               requeue = slow_work_sleep_till_thread_needed(&my_work,
+                                                            &timeout);
+       } while (timeout > 0 && !requeue);
+       finish_wait(wq, &wait);
+       if (!test_bit(MY_BIT, &my_flags)
+               goto do_my_thing;
+       if (requeue)
+               return; // to slow_work
 
 
 ===============
@@ -118,7 +208,8 @@ ITEM OPERATIONS
 ===============
 
 Each work item requires a table of operations of type struct slow_work_ops.
-All members are required:
+Only ->execute() is required; the getting and putting of a reference and the
+describing of an item are all optional.
 
  (*) Get a reference on an item:
 
@@ -148,6 +239,16 @@ All members are required:
      This should perform the work required of the item.  It may sleep, it may
      perform disk I/O and it may wait for locks.
 
+ (*) View an item through /proc:
+
+       void (*desc)(struct slow_work *work, struct seq_file *m);
+
+     If supplied, this should print to 'm' a small string describing the work
+     the item is to do.  This should be no more than about 40 characters, and
+     shouldn't include a newline character.
+
+     See the 'Viewing executing and queued items' section below.
+
 
 ==================
 POOL CONFIGURATION
@@ -172,3 +273,50 @@ The slow-work thread pool has a number of configurables:
      is bounded to between 1 and one fewer than the number of active threads.
      This ensures there is always at least one thread that can process very
      slow work items, and always at least one thread that won't.
+
+
+==================================
+VIEWING EXECUTING AND QUEUED ITEMS
+==================================
+
+If CONFIG_SLOW_WORK_PROC is enabled, a proc file is made available:
+
+       /proc/slow_work_rq
+
+through which the list of work items being executed and the queues of items to
+be executed may be viewed.  The owner of a work item is given the chance to
+add some information of its own.
+
+The contents look something like the following:
+
+    THR PID   ITEM ADDR        FL MARK  DESC
+    === ===== ================ == ===== ==========
+      0  3005 ffff880023f52348  a 952ms FSC: OBJ17d3: LOOK
+      1  3006 ffff880024e33668  2 160ms FSC: OBJ17e5 OP60d3b: Write1/Store fl=2
+      2  3165 ffff8800296dd180  a 424ms FSC: OBJ17e4: LOOK
+      3  4089 ffff8800262c8d78  a 212ms FSC: OBJ17ea: CRTN
+      4  4090 ffff88002792bed8  2 388ms FSC: OBJ17e8 OP60d36: Write1/Store fl=2
+      5  4092 ffff88002a0ef308  2 388ms FSC: OBJ17e7 OP60d2e: Write1/Store fl=2
+      6  4094 ffff88002abaf4b8  2 132ms FSC: OBJ17e2 OP60d4e: Write1/Store fl=2
+      7  4095 ffff88002bb188e0  a 388ms FSC: OBJ17e9: CRTN
+    vsq     - ffff880023d99668  1 308ms FSC: OBJ17e0 OP60f91: Write1/EnQ fl=2
+    vsq     - ffff8800295d1740  1 212ms FSC: OBJ16be OP4d4b6: Write1/EnQ fl=2
+    vsq     - ffff880025ba3308  1 160ms FSC: OBJ179a OP58dec: Write1/EnQ fl=2
+    vsq     - ffff880024ec83e0  1 160ms FSC: OBJ17ae OP599f2: Write1/EnQ fl=2
+    vsq     - ffff880026618e00  1 160ms FSC: OBJ17e6 OP60d33: Write1/EnQ fl=2
+    vsq     - ffff880025a2a4b8  1 132ms FSC: OBJ16a2 OP4d583: Write1/EnQ fl=2
+    vsq     - ffff880023cbe6d8  9 212ms FSC: OBJ17eb: LOOK
+    vsq     - ffff880024d37590  9 212ms FSC: OBJ17ec: LOOK
+    vsq     - ffff880027746cb0  9 212ms FSC: OBJ17ed: LOOK
+    vsq     - ffff880024d37ae8  9 212ms FSC: OBJ17ee: LOOK
+    vsq     - ffff880024d37cb0  9 212ms FSC: OBJ17ef: LOOK
+    vsq     - ffff880025036550  9 212ms FSC: OBJ17f0: LOOK
+    vsq     - ffff8800250368e0  9 212ms FSC: OBJ17f1: LOOK
+    vsq     - ffff880025036aa8  9 212ms FSC: OBJ17f2: LOOK
+
+In the 'THR' column, executing items show the thread they're occupying and
+queued threads indicate which queue they're on.  'PID' shows the process ID of
+a slow-work thread that's executing something.  'FL' shows the work item flags.
+'MARK' indicates how long since an item was queued or began executing.  Lastly,
+the 'DESC' column permits the owner of an item to give some information.
+
index c824b4d..6150c80 100644 (file)
@@ -512,10 +512,32 @@ W:        http://www.arm.linux.org.uk/
 S:     Maintained
 F:     arch/arm/
 
+ARM PRIMECELL AACI PL041 DRIVER
+M:     Russell King <linux@arm.linux.org.uk>
+S:     Maintained
+F:     sound/arm/aaci.*
+
+ARM PRIMECELL CLCD PL110 DRIVER
+M:     Russell King <linux@arm.linux.org.uk>
+S:     Maintained
+F:     drivers/video/amba-clcd.*
+
+ARM PRIMECELL KMI PL050 DRIVER
+M:     Russell King <linux@arm.linux.org.uk>
+S:     Maintained
+F:     drivers/input/serio/ambakmi.*
+F:     include/linux/amba/kmi.h
+
 ARM PRIMECELL MMCI PL180/1 DRIVER
 S:     Orphan
 F:     drivers/mmc/host/mmci.*
 
+ARM PRIMECELL BUS SUPPORT
+M:     Russell King <linux@arm.linux.org.uk>
+S:     Maintained
+F:     drivers/amba/
+F:     include/linux/amba/bus.h
+
 ARM/ADI ROADRUNNER MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -749,6 +771,14 @@ ARM/NEC MOBILEPRO 900/c MACHINE SUPPORT
 M:     Michael Petchkovsky <mkpetch@internode.on.net>
 S:     Maintained
 
+ARM/NOMADIK ARCHITECTURE
+M:     Alessandro Rubini <rubini@unipv.it>
+M:     STEricsson <STEricsson_nomadik_linux@list.st.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/mach-nomadik/
+F:     arch/arm/plat-nomadik/
+
 ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
 M:     Nelson Castillo <arhuaco@freaks-unidos.net>
 L:     openmoko-kernel@lists.openmoko.org (subscribers-only)
@@ -893,6 +923,12 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:     http://www.mcuos.com
 S:     Maintained
 
+ARM/U8500 ARM ARCHITECTURE
+M:     Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
+S:     Maintained
+F:     arch/arm/mach-ux500/
+
 ARM/VFP SUPPORT
 M:     Russell King <linux@arm.linux.org.uk>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1027,7 +1063,7 @@ F:        drivers/serial/atmel_serial.c
 
 ATMEL LCDFB DRIVER
 M:     Nicolas Ferre <nicolas.ferre@atmel.com>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/atmel_lcdfb.c
 F:     include/video/atmel_lcdc.h
@@ -2113,7 +2149,7 @@ F:        drivers/net/wan/dlci.c
 F:     drivers/net/wan/sdla.c
 
 FRAMEBUFFER LAYER
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 W:     http://linux-fbdev.sourceforge.net/
 S:     Orphan
 F:     Documentation/fb/
@@ -2136,7 +2172,7 @@ F:        drivers/i2c/busses/i2c-cpm.c
 
 FREESCALE IMX / MXC FRAMEBUFFER DRIVER
 M:     Sascha Hauer <kernel@pengutronix.de>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/plat-mxc/include/mach/imxfb.h
@@ -2312,6 +2348,13 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
 S:     Maintained
 F:     drivers/media/video/gspca/finepix.c
 
+GSPCA GL860 SUBDRIVER
+M:     Olivier Lorin <o.lorin@laposte.net>
+L:     linux-media@vger.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
+S:     Maintained
+F:     drivers/media/video/gspca/gl860/
+
 GSPCA M5602 SUBDRIVER
 M:     Erik Andren <erik.andren@gmail.com>
 L:     linux-media@vger.kernel.org
@@ -2533,8 +2576,7 @@ S:        Maintained
 F:     Documentation/i2c/
 F:     drivers/i2c/
 F:     include/linux/i2c.h
-F:     include/linux/i2c-dev.h
-F:     include/linux/i2c-id.h
+F:     include/linux/i2c-*.h
 
 I2C-TINY-USB DRIVER
 M:     Till Harbaum <till@harbaum.org>
@@ -2635,7 +2677,7 @@ S:        Supported
 F:     security/integrity/ima/
 
 IMS TWINTURBO FRAMEBUFFER DRIVER
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Orphan
 F:     drivers/video/imsttfb.c
 
@@ -2670,14 +2712,14 @@ F:      drivers/input/
 
 INTEL FRAMEBUFFER DRIVER (excluding 810 and 815)
 M:     Sylvain Meyer <sylvain.meyer@worldonline.fr>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     Documentation/fb/intelfb.txt
 F:     drivers/video/intelfb/
 
 INTEL 810/815 FRAMEBUFFER DRIVER
 M:     Antonino Daplas <adaplas@gmail.com>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/i810/
 
@@ -3391,7 +3433,7 @@ S:        Supported
 
 MATROX FRAMEBUFFER DRIVER
 M:     Petr Vandrovec <vandrove@vc.cvut.cz>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/matrox/matroxfb_*
 F:     include/linux/matroxfb.h
@@ -3778,7 +3820,7 @@ F:        fs/ntfs/
 
 NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER
 M:     Antonino Daplas <adaplas@gmail.com>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/riva/
 F:     drivers/video/nvidia/
@@ -3813,7 +3855,7 @@ F:        sound/soc/omap/
 
 OMAP FRAMEBUFFER SUPPORT
 M:     Imre Deak <imre.deak@nokia.com>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 L:     linux-omap@vger.kernel.org
 S:     Maintained
 F:     drivers/video/omap/
@@ -4319,14 +4361,14 @@ F:      include/linux/qnxtypes.h
 
 RADEON FRAMEBUFFER DISPLAY DRIVER
 M:     Benjamin Herrenschmidt <benh@kernel.crashing.org>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/aty/radeon*
 F:     include/linux/radeonfb.h
 
 RAGE128 FRAMEBUFFER DISPLAY DRIVER
 M:     Paul Mackerras <paulus@samba.org>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/aty/aty128fb.c
 
@@ -4465,7 +4507,7 @@ F:        drivers/net/wireless/rtl818x/rtl8187*
 
 S3 SAVAGE FRAMEBUFFER DRIVER
 M:     Antonino Daplas <adaplas@gmail.com>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/savage/
 
@@ -5628,7 +5670,7 @@ S:        Maintained
 
 UVESAFB DRIVER
 M:     Michal Januszewski <spock@gentoo.org>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 W:     http://dev.gentoo.org/~spock/projects/uvesafb/
 S:     Maintained
 F:     Documentation/fb/uvesafb.txt
@@ -5661,7 +5703,7 @@ F:        drivers/mmc/host/via-sdmmc.c
 VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER
 M:     Joseph Chan <JosephChan@via.com.tw>
 M:     Scott Fang <ScottFang@viatech.com.cn>
-L:     linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers)
+L:     linux-fbdev@vger.kernel.org
 S:     Maintained
 F:     drivers/video/via/
 
index 1c4119c..1ae18d8 100644 (file)
@@ -702,6 +702,16 @@ config ARCH_BCMRING
        help
          Support for Broadcom's BCMRing platform.
 
+config ARCH_U8500
+       bool "ST-Ericsson U8500 Series"
+       select CPU_V7
+       select ARM_AMBA
+       select GENERIC_TIME
+       select GENERIC_CLOCKEVENTS
+       select COMMON_CLKDEV
+       help
+         Support for ST-Ericsson's Ux500 architecture
+
 endchoice
 
 source "arch/arm/mach-clps711x/Kconfig"
@@ -787,6 +797,7 @@ source "arch/arm/mach-at91/Kconfig"
 source "arch/arm/plat-mxc/Kconfig"
 
 source "arch/arm/mach-nomadik/Kconfig"
+source "arch/arm/plat-nomadik/Kconfig"
 
 source "arch/arm/mach-netx/Kconfig"
 
@@ -804,6 +815,8 @@ source "arch/arm/mach-w90x900/Kconfig"
 
 source "arch/arm/mach-bcmring/Kconfig"
 
+source "arch/arm/mach-ux500/Kconfig"
+
 # Definitions to make life easier
 config ARCH_ACORN
        bool
@@ -955,10 +968,10 @@ source "kernel/time/Kconfig"
 config SMP
        bool "Symmetric Multi-Processing (EXPERIMENTAL)"
        depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
-                MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4)
+                MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500)
        depends on GENERIC_CLOCKEVENTS
        select USE_GENERIC_SMP_HELPERS
-       select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4)
+       select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500)
        help
          This enables support for systems with more than one CPU. If you have
          a system with only one CPU, like most personal computers, say N. If
@@ -1027,9 +1040,9 @@ config HOTPLUG_CPU
 config LOCAL_TIMERS
        bool "Use local timer interrupts"
        depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \
-               REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4)
+               REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500)
        default y
-       select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4)
+       select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500)
        help
          Enable support for local timers on SMP platforms, rather then the
          legacy IPI broadcast method.  Local timers allows the system
index 1a6f70e..ff54c23 100644 (file)
@@ -83,6 +83,14 @@ config DEBUG_ICEDCC
          It does include a timeout to ensure that the system does not
          totally freeze when there is nothing connected to read.
 
+config OC_ETM
+       bool "On-chip ETM and ETB"
+       select ARM_AMBA
+       help
+         Enables the on-chip embedded trace macrocell and embedded trace
+         buffer driver that will allow you to collect traces of the
+         kernel code.
+
 config DEBUG_DC21285_PORT
        bool "Kernel low-level debugging messages via footbridge serial port"
        depends on DEBUG_LL && FOOTBRIDGE
index a73caaf..7603eba 100644 (file)
@@ -166,6 +166,7 @@ machine-$(CONFIG_ARCH_SHARK)                := shark
 machine-$(CONFIG_ARCH_STMP378X)                := stmp378x
 machine-$(CONFIG_ARCH_STMP37XX)                := stmp37xx
 machine-$(CONFIG_ARCH_U300)            := u300
+machine-$(CONFIG_ARCH_U8500)           := ux500
 machine-$(CONFIG_ARCH_VERSATILE)       := versatile
 machine-$(CONFIG_ARCH_W90X900)         := w90x900
 machine-$(CONFIG_FOOTBRIDGE)           := footbridge
@@ -176,6 +177,7 @@ machine-$(CONFIG_ARCH_MXC91231)             := mxc91231
 plat-$(CONFIG_ARCH_MXC)                := mxc
 plat-$(CONFIG_ARCH_OMAP)       := omap
 plat-$(CONFIG_PLAT_IOP)                := iop
+plat-$(CONFIG_PLAT_NOMADIK)    := nomadik
 plat-$(CONFIG_PLAT_ORION)      := orion
 plat-$(CONFIG_PLAT_PXA)                := pxa
 plat-$(CONFIG_PLAT_S3C24XX)    := s3c24xx s3c
index 734ac91..5a375e5 100644 (file)
@@ -342,6 +342,22 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
 }
 EXPORT_SYMBOL(dma_map_single);
 
+/*
+ * see if a mapped address was really a "safe" buffer and if so, copy
+ * the data from the safe buffer back to the unsafe buffer and free up
+ * the safe buffer.  (basically return things back to the way they
+ * should be)
+ */
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+               enum dma_data_direction dir)
+{
+       dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
+               __func__, (void *) dma_addr, size, dir);
+
+       unmap_single(dev, dma_addr, size, dir);
+}
+EXPORT_SYMBOL(dma_unmap_single);
+
 dma_addr_t dma_map_page(struct device *dev, struct page *page,
                unsigned long offset, size_t size, enum dma_data_direction dir)
 {
@@ -366,8 +382,7 @@ EXPORT_SYMBOL(dma_map_page);
  * the safe buffer.  (basically return things back to the way they
  * should be)
  */
-
-void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size,
                enum dma_data_direction dir)
 {
        dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n",
@@ -375,7 +390,7 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
 
        unmap_single(dev, dma_addr, size, dir);
 }
-EXPORT_SYMBOL(dma_unmap_single);
+EXPORT_SYMBOL(dma_unmap_page);
 
 int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr,
                unsigned long off, size_t sz, enum dma_data_direction dir)
index 238b218..c97e102 100644 (file)
@@ -120,6 +120,7 @@ CONFIG_ARCH_AT91RM9200DK=y
 # CONFIG_MACH_CARMEVA is not set
 # CONFIG_MACH_KB9200 is not set
 # CONFIG_MACH_ATEB9200 is not set
+CONFIG_MACH_ECO920=y
 
 #
 # AT91RM9200 Feature Selections
diff --git a/arch/arm/configs/nuc910_defconfig b/arch/arm/configs/nuc910_defconfig
new file mode 100644 (file)
index 0000000..5245655
--- /dev/null
@@ -0,0 +1,905 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.30
+# Wed Jun 10 22:09:25 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_TIME is not set
+# CONFIG_GENERIC_CLOCKEVENTS is not set
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_USER_NS=y
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
+# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_STRIP_ASM_SYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_TRACEPOINTS=y
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBD=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM is not set
+CONFIG_ARCH_W90X900=y
+CONFIG_CPU_W90P910=y
+
+#
+# W90P910 Machines
+#
+CONFIG_MACH_W90P910EVB=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+# CONFIG_OUTER_CACHE is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_TC6393XB is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_STACKTRACE=y
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_RING_BUFFER=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+CONFIG_BLK_DEV_IO_TRACE=y
+# CONFIG_FTRACE_STARTUP_TEST is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/nuc950_defconfig b/arch/arm/configs/nuc950_defconfig
new file mode 100644 (file)
index 0000000..df1de9b
--- /dev/null
@@ -0,0 +1,922 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc7
+# Tue Nov 17 12:31:33 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_USER_NS=y
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+CONFIG_ARCH_W90X900=y
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_CPU_NUC950=y
+
+#
+# W90P910 Machines
+#
+# CONFIG_MACH_W90P910EVB is not set
+
+#
+# NUC950 Machines
+#
+CONFIG_MACH_W90P950EVB=y
+
+#
+# NUC960 Machines
+#
+# CONFIG_MACH_W90N960EVB is not set
+
+#
+# NUC932 Machines
+#
+# CONFIG_MACH_NUC932EVB is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/nuc960_defconfig b/arch/arm/configs/nuc960_defconfig
new file mode 100644 (file)
index 0000000..4b2cd9e
--- /dev/null
@@ -0,0 +1,922 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc7
+# Tue Nov 17 12:20:11 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+CONFIG_USER_NS=y
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+CONFIG_ARCH_W90X900=y
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_CPU_NUC960=y
+
+#
+# W90P910 Machines
+#
+# CONFIG_MACH_W90P910EVB is not set
+
+#
+# NUC950 Machines
+#
+# CONFIG_MACH_W90P950EVB is not set
+
+#
+# NUC960 Machines
+#
+CONFIG_MACH_W90N960EVB=y
+
+#
+# NUC932 Machines
+#
+# CONFIG_MACH_NUC932EVB is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_ARM926T=y
+CONFIG_CPU_32v5=y
+CONFIG_CPU_ABRT_EV5TJ=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_VIVT=y
+CONFIG_CPU_COPY_V4WB=y
+CONFIG_CPU_TLB_V4WBI=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
+# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4096
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
+# CONFIG_XIP_KERNEL is not set
+CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_NWFPE_XP is not set
+# CONFIG_FPE_FASTFPE is not set
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+CONFIG_BINFMT_AOUT=y
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_EHCI_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_OHCI_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+CONFIG_ROMFS_BACKED_BY_BLOCK=y
+# CONFIG_ROMFS_BACKED_BY_MTD is not set
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_BLOCK=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig
new file mode 100644 (file)
index 0000000..15fde22
--- /dev/null
@@ -0,0 +1,680 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.32-rc8
+# Mon Nov 30 11:11:29 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_LOCKBREAK=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+CONFIG_ARCH_U8500=y
+CONFIG_PLAT_NOMADIK=y
+CONFIG_HAS_MTU=y
+
+#
+# ST-Ericsson platform type
+#
+
+#
+# ST-Ericsson Multicore Mobile Platforms
+#
+CONFIG_MACH_U8500_MOP=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_ARM_GIC=y
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SMP=y
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_TWD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=2
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_LOCAL_TIMERS=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+CONFIG_OABI_COMPAT=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_FPE_NWFPE is not set
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_SERIAL_MAX3100 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_BITBANG is not set
+CONFIG_SPI_PL022=y
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_MC13783 is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+# CONFIG_MISC_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=m
+# CONFIG_CRC_ITU_T is not set
+# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/w90p910_defconfig b/arch/arm/configs/w90p910_defconfig
deleted file mode 100644 (file)
index 5245655..0000000
+++ /dev/null
@@ -1,905 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.30
-# Wed Jun 10 22:09:25 2009
-#
-CONFIG_ARM=y
-CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_GENERIC_GPIO=y
-# CONFIG_GENERIC_TIME is not set
-# CONFIG_GENERIC_CLOCKEVENTS is not set
-CONFIG_MMU=y
-# CONFIG_NO_IOPORT is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_STACKTRACE_SUPPORT=y
-CONFIG_HAVE_LATENCYTOP_SUPPORT=y
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_HARDIRQS_SW_RESEND=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
-CONFIG_VECTORS_BASE=0xffff0000
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-
-#
-# RCU Subsystem
-#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
-# CONFIG_IKCONFIG is not set
-CONFIG_LOG_BUF_SHIFT=17
-# CONFIG_GROUP_SCHED is not set
-# CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_RELAY=y
-CONFIG_NAMESPACES=y
-# CONFIG_UTS_NS is not set
-# CONFIG_IPC_NS is not set
-CONFIG_USER_NS=y
-# CONFIG_PID_NS is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_RD_GZIP=y
-CONFIG_RD_BZIP2=y
-CONFIG_RD_LZMA=y
-# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
-# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
-# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
-# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-CONFIG_ANON_INODES=y
-# CONFIG_EMBEDDED is not set
-CONFIG_UID16=y
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-# CONFIG_STRIP_ASM_SYMS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_COMPAT_BRK=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
-CONFIG_TRACEPOINTS=y
-# CONFIG_MARKERS is not set
-CONFIG_HAVE_OPROFILE=y
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-# CONFIG_SLOW_WORK is not set
-CONFIG_HAVE_GENERIC_DMA_COHERENT=y
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-# CONFIG_MODULES is not set
-CONFIG_BLOCK=y
-CONFIG_LBD=y
-CONFIG_BLK_DEV_BSG=y
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_DEFAULT_AS is not set
-# CONFIG_DEFAULT_DEADLINE is not set
-CONFIG_DEFAULT_CFQ=y
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="cfq"
-# CONFIG_FREEZER is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_LOKI is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_DAVINCI is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_MSM is not set
-CONFIG_ARCH_W90X900=y
-CONFIG_CPU_W90P910=y
-
-#
-# W90P910 Machines
-#
-CONFIG_MACH_W90P910EVB=y
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_ARM926T=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_PABRT_NOIFAR=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_CP15=y
-CONFIG_CPU_CP15_MMU=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-# CONFIG_OUTER_CACHE is not set
-CONFIG_COMMON_CLKDEV=y
-
-#
-# Bus support
-#
-# CONFIG_PCI_SYSCALL is not set
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCCARD is not set
-
-#
-# Kernel Features
-#
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_1G is not set
-CONFIG_PAGE_OFFSET=0xC0000000
-CONFIG_PREEMPT=y
-CONFIG_HZ=100
-CONFIG_AEABI=y
-CONFIG_OABI_COMPAT=y
-# CONFIG_ARCH_HAS_HOLES_MEMORYMODEL is not set
-# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
-# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4096
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-CONFIG_ZONE_DMA_FLAG=0
-CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Boot options
-#
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
-# CONFIG_XIP_KERNEL is not set
-CONFIG_KEXEC=y
-CONFIG_ATAGS_PROC=y
-
-#
-# CPU Power Management
-#
-# CONFIG_CPU_IDLE is not set
-
-#
-# Floating point emulation
-#
-
-#
-# At least one emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-# CONFIG_VFP is not set
-
-#
-# Userspace binary formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_HAVE_AOUT=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Power management options
-#
-# CONFIG_PM is not set
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-# CONFIG_NET is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=y
-CONFIG_FIRMWARE_IN_KERNEL=y
-CONFIG_EXTRA_FIRMWARE=""
-# CONFIG_SYS_HYPERVISOR is not set
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-# CONFIG_MTD_AR7_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_SSFDC is not set
-# CONFIG_MTD_OOPS is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-# CONFIG_MTD_PHYSMAP_COMPAT is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_PLATRAM is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLOCK2MTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_ONENAND is not set
-
-#
-# LPDDR flash memory drivers
-#
-# CONFIG_MTD_LPDDR is not set
-
-#
-# UBI - Unsorted block images
-#
-# CONFIG_MTD_UBI is not set
-# CONFIG_PARPORT is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=16384
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_MISC_DEVICES is not set
-CONFIG_HAVE_IDE=y
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_NETLINK is not set
-# CONFIG_SCSI_PROC_FS is not set
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-
-#
-# SCSI Transports
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_SCSI_DH is not set
-# CONFIG_SCSI_OSD_INITIATOR is not set
-# CONFIG_ATA is not set
-# CONFIG_MD is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-# CONFIG_SERIO is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-# CONFIG_DEVKMEM is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=1
-CONFIG_SERIAL_8250_RUNTIME_UARTS=1
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_R3964 is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
-# CONFIG_SPI is not set
-CONFIG_ARCH_REQUIRE_GPIOLIB=y
-CONFIG_GPIOLIB=y
-# CONFIG_GPIO_SYSFS is not set
-
-#
-# Memory mapped GPIO expanders:
-#
-
-#
-# I2C GPIO expanders:
-#
-
-#
-# PCI GPIO expanders:
-#
-
-#
-# SPI GPIO expanders:
-#
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
-# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_TC6393XB is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-# CONFIG_DAB is not set
-
-#
-# Graphics support
-#
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_SOUND is not set
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-CONFIG_USB_DEVICE_CLASS=y
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG is not set
-CONFIG_USB_MON=y
-# CONFIG_USB_WUSB is not set
-# CONFIG_USB_WUSB_CBAF is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_C67X00_HCD is not set
-# CONFIG_USB_OXU210HP_HCD is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_ISP1760_HCD is not set
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_R8A66597_HCD is not set
-# CONFIG_USB_HWA_HCD is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_WDM is not set
-# CONFIG_USB_TMC is not set
-
-#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
-#
-
-#
-# also be needed; see USB_STORAGE Help for more info
-#
-CONFIG_USB_STORAGE=y
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_SEVSEG is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_APPLEDISPLAY is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
-# CONFIG_USB_GADGET is not set
-
-#
-# OTG and related infrastructure
-#
-# CONFIG_USB_GPIO_VBUS is not set
-# CONFIG_NOP_USB_XCEIV is not set
-# CONFIG_MMC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_ACCESSIBILITY is not set
-# CONFIG_NEW_LEDS is not set
-CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_REGULATOR is not set
-# CONFIG_UIO is not set
-# CONFIG_STAGING is not set
-
-#
-# File systems
-#
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT4_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
-# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_BTRFS_FS is not set
-# CONFIG_DNOTIFY is not set
-# CONFIG_INOTIFY is not set
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-CONFIG_GENERIC_ACL=y
-
-#
-# Caches
-#
-# CONFIG_FSCACHE is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS2_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-CONFIG_ROMFS_FS=y
-CONFIG_ROMFS_BACKED_BY_BLOCK=y
-# CONFIG_ROMFS_BACKED_BY_MTD is not set
-# CONFIG_ROMFS_BACKED_BY_BOTH is not set
-CONFIG_ROMFS_ON_BLOCK=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_FRAME_WARN=1024
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_STACKTRACE=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_MEMORY_INIT=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_LATENCYTOP is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_NOP_TRACER=y
-CONFIG_HAVE_FUNCTION_TRACER=y
-CONFIG_RING_BUFFER=y
-CONFIG_TRACING=y
-CONFIG_TRACING_SUPPORT=y
-
-#
-# Tracers
-#
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_EVENT_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_STACK_TRACER is not set
-# CONFIG_KMEMTRACE is not set
-# CONFIG_WORKQUEUE_TRACER is not set
-CONFIG_BLK_DEV_IO_TRACE=y
-# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_HAVE_ARCH_KGDB=y
-CONFIG_ARM_UNWIND=y
-# CONFIG_DEBUG_USER is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
-CONFIG_BINARY_PRINTF=y
-
-#
-# Library routines
-#
-CONFIG_GENERIC_FIND_LAST_BIT=y
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_T10DIF is not set
-# CONFIG_CRC_ITU_T is not set
-# CONFIG_CRC32 is not set
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DECOMPRESS_BZIP2=y
-CONFIG_DECOMPRESS_LZMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
index 3d0cdd2..9fd6d3a 100644 (file)
@@ -331,15 +331,15 @@ static inline void outer_flush_range(unsigned long start, unsigned long end)
  * Convert calls to our calling convention.
  */
 #define flush_cache_all()              __cpuc_flush_kern_all()
-#ifndef CONFIG_CPU_CACHE_VIPT
-static inline void flush_cache_mm(struct mm_struct *mm)
+
+static inline void vivt_flush_cache_mm(struct mm_struct *mm)
 {
        if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
                __cpuc_flush_user_all();
 }
 
 static inline void
-flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
 {
        if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm)))
                __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
@@ -347,7 +347,7 @@ flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long
 }
 
 static inline void
-flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
+vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
 {
        if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
                unsigned long addr = user_addr & PAGE_MASK;
@@ -356,7 +356,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned l
 }
 
 static inline void
-flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
+vivt_flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
                         unsigned long uaddr, void *kaddr,
                         unsigned long len, int write)
 {
@@ -365,6 +365,16 @@ flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
                __cpuc_coherent_kern_range(addr, addr + len);
        }
 }
+
+#ifndef CONFIG_CPU_CACHE_VIPT
+#define flush_cache_mm(mm) \
+               vivt_flush_cache_mm(mm)
+#define flush_cache_range(vma,start,end) \
+               vivt_flush_cache_range(vma,start,end)
+#define flush_cache_page(vma,addr,pfn) \
+               vivt_flush_cache_page(vma,addr,pfn)
+#define flush_ptrace_access(vma,page,ua,ka,len,write) \
+               vivt_flush_ptrace_access(vma,page,ua,ka,len,write)
 #else
 extern void flush_cache_mm(struct mm_struct *mm);
 extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
@@ -410,8 +420,6 @@ extern void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
  */
 extern void flush_dcache_page(struct page *);
 
-extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
-
 static inline void __flush_icache_all(void)
 {
 #ifdef CONFIG_ARM_ERRATA_411920
index ff46dfa..a96300b 100644 (file)
  * must not be used by drivers.
  */
 #ifndef __arch_page_to_dma
-
-#if !defined(CONFIG_HIGHMEM)
 static inline dma_addr_t page_to_dma(struct device *dev, struct page *page)
 {
-       return (dma_addr_t)__virt_to_bus((unsigned long)page_address(page));
+       return (dma_addr_t)__pfn_to_bus(page_to_pfn(page));
 }
-#elif defined(__pfn_to_bus)
-static inline dma_addr_t page_to_dma(struct device *dev, struct page *page)
+
+static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr)
 {
-       return (dma_addr_t)__pfn_to_bus(page_to_pfn(page));
+       return pfn_to_page(__bus_to_pfn(addr));
 }
-#else
-#error "this machine class needs to define __arch_page_to_dma to use HIGHMEM"
-#endif
 
 static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
 {
@@ -45,6 +40,11 @@ static inline dma_addr_t page_to_dma(struct device *dev, struct page *page)
        return __arch_page_to_dma(dev, page);
 }
 
+static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr)
+{
+       return __arch_dma_to_page(dev, addr);
+}
+
 static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
 {
        return __arch_dma_to_virt(dev, addr);
@@ -257,9 +257,11 @@ extern int dma_needs_bounce(struct device*, dma_addr_t, size_t);
  */
 extern dma_addr_t dma_map_single(struct device *, void *, size_t,
                enum dma_data_direction);
+extern void dma_unmap_single(struct device *, dma_addr_t, size_t,
+               enum dma_data_direction);
 extern dma_addr_t dma_map_page(struct device *, struct page *,
                unsigned long, size_t, enum dma_data_direction);
-extern void dma_unmap_single(struct device *, dma_addr_t, size_t,
+extern void dma_unmap_page(struct device *, dma_addr_t, size_t,
                enum dma_data_direction);
 
 /*
@@ -352,7 +354,6 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
 {
        /* nothing to do */
 }
-#endif /* CONFIG_DMABOUNCE */
 
 /**
  * dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
@@ -371,8 +372,9 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle,
 static inline void dma_unmap_page(struct device *dev, dma_addr_t handle,
                size_t size, enum dma_data_direction dir)
 {
-       dma_unmap_single(dev, handle, size, dir);
+       /* nothing to do */
 }
+#endif /* CONFIG_DMABOUNCE */
 
 /**
  * dma_sync_single_range_for_cpu
diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h
new file mode 100644 (file)
index 0000000..f82b25d
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * linux/arch/arm/include/asm/hardware/coresight.h
+ *
+ * CoreSight components' registers
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ * Alexander Shishkin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_HARDWARE_CORESIGHT_H
+#define __ASM_HARDWARE_CORESIGHT_H
+
+#define TRACER_ACCESSED_BIT    0
+#define TRACER_RUNNING_BIT     1
+#define TRACER_CYCLE_ACC_BIT   2
+#define TRACER_ACCESSED                BIT(TRACER_ACCESSED_BIT)
+#define TRACER_RUNNING         BIT(TRACER_RUNNING_BIT)
+#define TRACER_CYCLE_ACC       BIT(TRACER_CYCLE_ACC_BIT)
+
+struct tracectx {
+       unsigned int    etb_bufsz;
+       void __iomem    *etb_regs;
+       void __iomem    *etm_regs;
+       unsigned long   flags;
+       int             ncmppairs;
+       int             etm_portsz;
+       struct device   *dev;
+       struct clk      *emu_clk;
+       struct mutex    mutex;
+};
+
+#define TRACER_TIMEOUT 10000
+
+#define etm_writel(t, v, x) \
+       (__raw_writel((v), (t)->etm_regs + (x)))
+#define etm_readl(t, x) (__raw_readl((t)->etm_regs + (x)))
+
+/* CoreSight Management Registers */
+#define CSMR_LOCKACCESS 0xfb0
+#define CSMR_LOCKSTATUS 0xfb4
+#define CSMR_AUTHSTATUS 0xfb8
+#define CSMR_DEVID     0xfc8
+#define CSMR_DEVTYPE   0xfcc
+/* CoreSight Component Registers */
+#define CSCR_CLASS     0xff4
+
+#define CSCR_PRSR      0x314
+
+#define UNLOCK_MAGIC   0xc5acce55
+
+/* ETM control register, "ETM Architecture", 3.3.1 */
+#define ETMR_CTRL              0
+#define ETMCTRL_POWERDOWN      1
+#define ETMCTRL_PROGRAM                (1 << 10)
+#define ETMCTRL_PORTSEL                (1 << 11)
+#define ETMCTRL_DO_CONTEXTID   (3 << 14)
+#define ETMCTRL_PORTMASK1      (7 << 4)
+#define ETMCTRL_PORTMASK2      (1 << 21)
+#define ETMCTRL_PORTMASK       (ETMCTRL_PORTMASK1 | ETMCTRL_PORTMASK2)
+#define ETMCTRL_PORTSIZE(x) ((((x) & 7) << 4) | (!!((x) & 8)) << 21)
+#define ETMCTRL_DO_CPRT                (1 << 1)
+#define ETMCTRL_DATAMASK       (3 << 2)
+#define ETMCTRL_DATA_DO_DATA   (1 << 2)
+#define ETMCTRL_DATA_DO_ADDR   (1 << 3)
+#define ETMCTRL_DATA_DO_BOTH   (ETMCTRL_DATA_DO_DATA | ETMCTRL_DATA_DO_ADDR)
+#define ETMCTRL_BRANCH_OUTPUT  (1 << 8)
+#define ETMCTRL_CYCLEACCURATE  (1 << 12)
+
+/* ETM configuration code register */
+#define ETMR_CONFCODE          (0x04)
+
+/* ETM trace start/stop resource control register */
+#define ETMR_TRACESSCTRL       (0x18)
+
+/* ETM trigger event register */
+#define ETMR_TRIGEVT           (0x08)
+
+/* address access type register bits, "ETM architecture",
+ * table 3-27 */
+/* - access type */
+#define ETMAAT_IFETCH          0
+#define ETMAAT_IEXEC           1
+#define ETMAAT_IEXECPASS       2
+#define ETMAAT_IEXECFAIL       3
+#define ETMAAT_DLOADSTORE      4
+#define ETMAAT_DLOAD           5
+#define ETMAAT_DSTORE          6
+/* - comparison access size */
+#define ETMAAT_JAVA            (0 << 3)
+#define ETMAAT_THUMB           (1 << 3)
+#define ETMAAT_ARM             (3 << 3)
+/* - data value comparison control */
+#define ETMAAT_NOVALCMP                (0 << 5)
+#define ETMAAT_VALMATCH                (1 << 5)
+#define ETMAAT_VALNOMATCH      (3 << 5)
+/* - exact match */
+#define ETMAAT_EXACTMATCH      (1 << 7)
+/* - context id comparator control */
+#define ETMAAT_IGNCONTEXTID    (0 << 8)
+#define ETMAAT_VALUE1          (1 << 8)
+#define ETMAAT_VALUE2          (2 << 8)
+#define ETMAAT_VALUE3          (3 << 8)
+/* - security level control */
+#define ETMAAT_IGNSECURITY     (0 << 10)
+#define ETMAAT_NSONLY          (1 << 10)
+#define ETMAAT_SONLY           (2 << 10)
+
+#define ETMR_COMP_VAL(x)       (0x40 + (x) * 4)
+#define ETMR_COMP_ACC_TYPE(x)  (0x80 + (x) * 4)
+
+/* ETM status register, "ETM Architecture", 3.3.2 */
+#define ETMR_STATUS            (0x10)
+#define ETMST_OVERFLOW         (1 << 0)
+#define ETMST_PROGBIT          (1 << 1)
+#define ETMST_STARTSTOP                (1 << 2)
+#define ETMST_TRIGGER          (1 << 3)
+
+#define etm_progbit(t)         (etm_readl((t), ETMR_STATUS) & ETMST_PROGBIT)
+#define etm_started(t)         (etm_readl((t), ETMR_STATUS) & ETMST_STARTSTOP)
+#define etm_triggered(t)       (etm_readl((t), ETMR_STATUS) & ETMST_TRIGGER)
+
+#define ETMR_TRACEENCTRL2      0x1c
+#define ETMR_TRACEENCTRL       0x24
+#define ETMTE_INCLEXCL         (1 << 24)
+#define ETMR_TRACEENEVT                0x20
+#define ETMCTRL_OPTS           (ETMCTRL_DO_CPRT | \
+                               ETMCTRL_DATA_DO_ADDR | \
+                               ETMCTRL_BRANCH_OUTPUT | \
+                               ETMCTRL_DO_CONTEXTID)
+
+/* ETB registers, "CoreSight Components TRM", 9.3 */
+#define ETBR_DEPTH             0x04
+#define ETBR_STATUS            0x0c
+#define ETBR_READMEM           0x10
+#define ETBR_READADDR          0x14
+#define ETBR_WRITEADDR         0x18
+#define ETBR_TRIGGERCOUNT      0x1c
+#define ETBR_CTRL              0x20
+#define ETBR_FORMATTERCTRL     0x304
+#define ETBFF_ENFTC            1
+#define ETBFF_ENFCONT          (1 << 1)
+#define ETBFF_FONFLIN          (1 << 4)
+#define ETBFF_MANUAL_FLUSH     (1 << 6)
+#define ETBFF_TRIGIN           (1 << 8)
+#define ETBFF_TRIGEVT          (1 << 9)
+#define ETBFF_TRIGFL           (1 << 10)
+
+#define etb_writel(t, v, x) \
+       (__raw_writel((v), (t)->etb_regs + (x)))
+#define etb_readl(t, x) (__raw_readl((t)->etb_regs + (x)))
+
+#define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0)
+#define etm_unlock(t) \
+       do { etm_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0)
+
+#define etb_lock(t) do { etb_writel((t), 0, CSMR_LOCKACCESS); } while (0)
+#define etb_unlock(t) \
+       do { etb_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0)
+
+#endif /* __ASM_HARDWARE_CORESIGHT_H */
+
index d16ec97..c019949 100644 (file)
@@ -22,4 +22,10 @@ enum km_type {
        KM_TYPE_NR
 };
 
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define KM_NMI         (-1)
+#define KM_NMI_PTE     (-1)
+#define KM_IRQ_PTE     (-1)
+#endif
+
 #endif
index cefedf0..5421d82 100644 (file)
  * private definitions which should NOT be used outside memory.h
  * files.  Use virt_to_phys/phys_to_virt/__pa/__va instead.
  */
+#ifndef __virt_to_phys
 #define __virt_to_phys(x)      ((x) - PAGE_OFFSET + PHYS_OFFSET)
 #define __phys_to_virt(x)      ((x) - PHYS_OFFSET + PAGE_OFFSET)
+#endif
 
 /*
  * Convert a physical address to a Page Frame Number and back
 #define        __phys_to_pfn(paddr)    ((paddr) >> PAGE_SHIFT)
 #define        __pfn_to_phys(pfn)      ((pfn) << PAGE_SHIFT)
 
+/*
+ * Convert a page to/from a physical address
+ */
+#define page_to_phys(page)     (__pfn_to_phys(page_to_pfn(page)))
+#define phys_to_page(phys)     (pfn_to_page(__phys_to_pfn(phys)))
+
 #ifndef __ASSEMBLY__
 
 /*
@@ -194,7 +202,8 @@ static inline void *phys_to_virt(unsigned long x)
 #ifndef __virt_to_bus
 #define __virt_to_bus  __virt_to_phys
 #define __bus_to_virt  __phys_to_virt
-#define __pfn_to_bus(x)        ((x) << PAGE_SHIFT)
+#define __pfn_to_bus(x)        __pfn_to_phys(x)
+#define __bus_to_pfn(x)        __phys_to_pfn(x)
 #endif
 
 static inline __deprecated unsigned long virt_to_bus(void *x)
@@ -292,11 +301,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
 
 #endif /* !CONFIG_DISCONTIGMEM */
 
-/*
- * For BIO.  "will die".  Kill me when bio_to_phys() and bvec_to_phys() die.
- */
-#define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
-
 /*
  * Optional coherency support.  Currently used only by selected
  * Intel XSC3-based systems.
index 201ccaa..1139768 100644 (file)
@@ -304,13 +304,23 @@ PTE_BIT_FUNC(mkyoung,   |= L_PTE_YOUNG);
 
 static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
 
+#define __pgprot_modify(prot,mask,bits)                \
+       __pgprot((pgprot_val(prot) & ~(mask)) | (bits))
+
 /*
  * Mark the prot value as uncacheable and unbufferable.
  */
 #define pgprot_noncached(prot) \
-       __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_UNCACHED)
+       __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED)
 #define pgprot_writecombine(prot) \
-       __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_BUFFERABLE)
+       __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE)
+#if __LINUX_ARM_ARCH__ >= 7
+#define pgprot_dmacoherent(prot) \
+       __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE)
+#else
+#define pgprot_dmacoherent(prot) \
+       __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED)
+#endif
 
 #define pmd_none(pmd)          (!pmd_val(pmd))
 #define pmd_present(pmd)       (pmd_val(pmd))
index ca2bf2f..9997ad2 100644 (file)
 #  define __SWAB_64_THRU_32__
 #endif
 
+#if defined(__KERNEL__) && __LINUX_ARM_ARCH__ >= 6
+
+static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
+{
+       __asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x));
+       return x;
+}
+#define __arch_swab16 __arch_swab16
+
+static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
+{
+       __asm__ ("rev %0, %1" : "=r" (x) : "r" (x));
+       return x;
+}
+#define __arch_swab32 __arch_swab32
+
+#else
+
 static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
 {
        __u32 t;
@@ -48,3 +66,4 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
 
 #endif
 
+#endif
index d65b2f5..058e7e9 100644 (file)
@@ -138,21 +138,26 @@ extern unsigned int user_debug;
 #define dmb() __asm__ __volatile__ ("" : : : "memory")
 #endif
 
-#ifndef CONFIG_SMP
+#if __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP)
+#define mb()           dmb()
+#define rmb()          dmb()
+#define wmb()          dmb()
+#else
 #define mb()   do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 #define rmb()  do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
 #define wmb()  do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
+#endif
+
+#ifndef CONFIG_SMP
 #define smp_mb()       barrier()
 #define smp_rmb()      barrier()
 #define smp_wmb()      barrier()
 #else
-#define mb()           dmb()
-#define rmb()          dmb()
-#define wmb()          dmb()
-#define smp_mb()       dmb()
-#define smp_rmb()      dmb()
-#define smp_wmb()      dmb()
+#define smp_mb()       mb()
+#define smp_rmb()      rmb()
+#define smp_wmb()      wmb()
 #endif
+
 #define read_barrier_depends()         do { } while(0)
 #define smp_read_barrier_depends()     do { } while(0)
 
index 79087dd..e7ccf7e 100644 (file)
@@ -17,6 +17,8 @@ obj-y         := compat.o elf.o entry-armv.o entry-common.o irq.o \
                   process.o ptrace.o return_address.o setup.o signal.o \
                   sys_arm.o stacktrace.o time.o traps.o
 
+obj-$(CONFIG_OC_ETM)           += etm.o
+
 obj-$(CONFIG_ISA_DMA_API)      += dma.o
 obj-$(CONFIG_ARCH_ACORN)       += ecard.o 
 obj-$(CONFIG_FIQ)              += fiq.o
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
new file mode 100644 (file)
index 0000000..8277539
--- /dev/null
@@ -0,0 +1,641 @@
+/*
+ * linux/arch/arm/kernel/etm.c
+ *
+ * Driver for ARM's Embedded Trace Macrocell and Embedded Trace Buffer.
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ * Alexander Shishkin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/sysrq.h>
+#include <linux/device.h>
+#include <linux/clk.h>
+#include <linux/amba/bus.h>
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/mutex.h>
+#include <asm/hardware/coresight.h>
+#include <asm/sections.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Shishkin");
+
+static struct tracectx tracer;
+
+static inline bool trace_isrunning(struct tracectx *t)
+{
+       return !!(t->flags & TRACER_RUNNING);
+}
+
+static int etm_setup_address_range(struct tracectx *t, int n,
+               unsigned long start, unsigned long end, int exclude, int data)
+{
+       u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \
+                   ETMAAT_NOVALCMP;
+
+       if (n < 1 || n > t->ncmppairs)
+               return -EINVAL;
+
+       /* comparators and ranges are numbered starting with 1 as opposed
+        * to bits in a word */
+       n--;
+
+       if (data)
+               flags |= ETMAAT_DLOADSTORE;
+       else
+               flags |= ETMAAT_IEXEC;
+
+       /* first comparator for the range */
+       etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2));
+       etm_writel(t, start, ETMR_COMP_VAL(n * 2));
+
+       /* second comparator is right next to it */
+       etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1));
+       etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1));
+
+       flags = exclude ? ETMTE_INCLEXCL : 0;
+       etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL);
+
+       return 0;
+}
+
+static int trace_start(struct tracectx *t)
+{
+       u32 v;
+       unsigned long timeout = TRACER_TIMEOUT;
+
+       etb_unlock(t);
+
+       etb_writel(t, 0, ETBR_FORMATTERCTRL);
+       etb_writel(t, 1, ETBR_CTRL);
+
+       etb_lock(t);
+
+       /* configure etm */
+       v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz);
+
+       if (t->flags & TRACER_CYCLE_ACC)
+               v |= ETMCTRL_CYCLEACCURATE;
+
+       etm_unlock(t);
+
+       etm_writel(t, v, ETMR_CTRL);
+
+       while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
+               ;
+       if (!timeout) {
+               dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
+               etm_lock(t);
+               return -EFAULT;
+       }
+
+       etm_setup_address_range(t, 1, (unsigned long)_stext,
+                       (unsigned long)_etext, 0, 0);
+       etm_writel(t, 0, ETMR_TRACEENCTRL2);
+       etm_writel(t, 0, ETMR_TRACESSCTRL);
+       etm_writel(t, 0x6f, ETMR_TRACEENEVT);
+
+       v &= ~ETMCTRL_PROGRAM;
+       v |= ETMCTRL_PORTSEL;
+
+       etm_writel(t, v, ETMR_CTRL);
+
+       timeout = TRACER_TIMEOUT;
+       while (etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout)
+               ;
+       if (!timeout) {
+               dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n");
+               etm_lock(t);
+               return -EFAULT;
+       }
+
+       etm_lock(t);
+
+       t->flags |= TRACER_RUNNING;
+
+       return 0;
+}
+
+static int trace_stop(struct tracectx *t)
+{
+       unsigned long timeout = TRACER_TIMEOUT;
+
+       etm_unlock(t);
+
+       etm_writel(t, 0x440, ETMR_CTRL);
+       while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout)
+               ;
+       if (!timeout) {
+               dev_dbg(t->dev, "Waiting for progbit to assert timed out\n");
+               etm_lock(t);
+               return -EFAULT;
+       }
+
+       etm_lock(t);
+
+       etb_unlock(t);
+       etb_writel(t, ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL);
+
+       timeout = TRACER_TIMEOUT;
+       while (etb_readl(t, ETBR_FORMATTERCTRL) &
+                       ETBFF_MANUAL_FLUSH && --timeout)
+               ;
+       if (!timeout) {
+               dev_dbg(t->dev, "Waiting for formatter flush to commence "
+                               "timed out\n");
+               etb_lock(t);
+               return -EFAULT;
+       }
+
+       etb_writel(t, 0, ETBR_CTRL);
+
+       etb_lock(t);
+
+       t->flags &= ~TRACER_RUNNING;
+
+       return 0;
+}
+
+static int etb_getdatalen(struct tracectx *t)
+{
+       u32 v;
+       int rp, wp;
+
+       v = etb_readl(t, ETBR_STATUS);
+
+       if (v & 1)
+               return t->etb_bufsz;
+
+       rp = etb_readl(t, ETBR_READADDR);
+       wp = etb_readl(t, ETBR_WRITEADDR);
+
+       if (rp > wp) {
+               etb_writel(t, 0, ETBR_READADDR);
+               etb_writel(t, 0, ETBR_WRITEADDR);
+
+               return 0;
+       }
+
+       return wp - rp;
+}
+
+/* sysrq+v will always stop the running trace and leave it at that */
+static void etm_dump(void)
+{
+       struct tracectx *t = &tracer;
+       u32 first = 0;
+       int length;
+
+       if (!t->etb_regs) {
+               printk(KERN_INFO "No tracing hardware found\n");
+               return;
+       }
+
+       if (trace_isrunning(t))
+               trace_stop(t);
+
+       etb_unlock(t);
+
+       length = etb_getdatalen(t);
+
+       if (length == t->etb_bufsz)
+               first = etb_readl(t, ETBR_WRITEADDR);
+
+       etb_writel(t, first, ETBR_READADDR);
+
+       printk(KERN_INFO "Trace buffer contents length: %d\n", length);
+       printk(KERN_INFO "--- ETB buffer begin ---\n");
+       for (; length; length--)
+               printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM)));
+       printk(KERN_INFO "\n--- ETB buffer end ---\n");
+
+       /* deassert the overflow bit */
+       etb_writel(t, 1, ETBR_CTRL);
+       etb_writel(t, 0, ETBR_CTRL);
+
+       etb_writel(t, 0, ETBR_TRIGGERCOUNT);
+       etb_writel(t, 0, ETBR_READADDR);
+       etb_writel(t, 0, ETBR_WRITEADDR);
+
+       etb_lock(t);
+}
+
+static void sysrq_etm_dump(int key, struct tty_struct *tty)
+{
+       dev_dbg(tracer.dev, "Dumping ETB buffer\n");
+       etm_dump();
+}
+
+static struct sysrq_key_op sysrq_etm_op = {
+       .handler = sysrq_etm_dump,
+       .help_msg = "ETM buffer dump",
+       .action_msg = "etm",
+};
+
+static int etb_open(struct inode *inode, struct file *file)
+{
+       if (!tracer.etb_regs)
+               return -ENODEV;
+
+       file->private_data = &tracer;
+
+       return nonseekable_open(inode, file);
+}
+
+static ssize_t etb_read(struct file *file, char __user *data,
+               size_t len, loff_t *ppos)
+{
+       int total, i;
+       long length;
+       struct tracectx *t = file->private_data;
+       u32 first = 0;
+       u32 *buf;
+
+       mutex_lock(&t->mutex);
+
+       if (trace_isrunning(t)) {
+               length = 0;
+               goto out;
+       }
+
+       etb_unlock(t);
+
+       total = etb_getdatalen(t);
+       if (total == t->etb_bufsz)
+               first = etb_readl(t, ETBR_WRITEADDR);
+
+       etb_writel(t, first, ETBR_READADDR);
+
+       length = min(total * 4, (int)len);
+       buf = vmalloc(length);
+
+       dev_dbg(t->dev, "ETB buffer length: %d\n", total);
+       dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS));
+       for (i = 0; i < length / 4; i++)
+               buf[i] = etb_readl(t, ETBR_READMEM);
+
+       /* the only way to deassert overflow bit in ETB status is this */
+       etb_writel(t, 1, ETBR_CTRL);
+       etb_writel(t, 0, ETBR_CTRL);
+
+       etb_writel(t, 0, ETBR_WRITEADDR);
+       etb_writel(t, 0, ETBR_READADDR);
+       etb_writel(t, 0, ETBR_TRIGGERCOUNT);
+
+       etb_lock(t);
+
+       length -= copy_to_user(data, buf, length);
+       vfree(buf);
+
+out:
+       mutex_unlock(&t->mutex);
+
+       return length;
+}
+
+static int etb_release(struct inode *inode, struct file *file)
+{
+       /* there's nothing to do here, actually */
+       return 0;
+}
+
+static const struct file_operations etb_fops = {
+       .owner = THIS_MODULE,
+       .read = etb_read,
+       .open = etb_open,
+       .release = etb_release,
+};
+
+static struct miscdevice etb_miscdev = {
+       .name = "tracebuf",
+       .minor = 0,
+       .fops = &etb_fops,
+};
+
+static int __init etb_probe(struct amba_device *dev, struct amba_id *id)
+{
+       struct tracectx *t = &tracer;
+       int ret = 0;
+
+       ret = amba_request_regions(dev, NULL);
+       if (ret)
+               goto out;
+
+       t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
+       if (!t->etb_regs) {
+               ret = -ENOMEM;
+               goto out_release;
+       }
+
+       amba_set_drvdata(dev, t);
+
+       etb_miscdev.parent = &dev->dev;
+
+       ret = misc_register(&etb_miscdev);
+       if (ret)
+               goto out_unmap;
+
+       t->emu_clk = clk_get(&dev->dev, "emu_src_ck");
+       if (IS_ERR(t->emu_clk)) {
+               dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n");
+               return -EFAULT;
+       }
+
+       clk_enable(t->emu_clk);
+
+       etb_unlock(t);
+       t->etb_bufsz = etb_readl(t, ETBR_DEPTH);
+       dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz);
+
+       /* make sure trace capture is disabled */
+       etb_writel(t, 0, ETBR_CTRL);
+       etb_writel(t, 0x1000, ETBR_FORMATTERCTRL);
+       etb_lock(t);
+
+       dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n");
+
+out:
+       return ret;
+
+out_unmap:
+       amba_set_drvdata(dev, NULL);
+       iounmap(t->etb_regs);
+
+out_release:
+       amba_release_regions(dev);
+
+       return ret;
+}
+
+static int etb_remove(struct amba_device *dev)
+{
+       struct tracectx *t = amba_get_drvdata(dev);
+
+       amba_set_drvdata(dev, NULL);
+
+       iounmap(t->etb_regs);
+       t->etb_regs = NULL;
+
+       clk_disable(t->emu_clk);
+       clk_put(t->emu_clk);
+
+       amba_release_regions(dev);
+
+       return 0;
+}
+
+static struct amba_id etb_ids[] = {
+       {
+               .id     = 0x0003b907,
+               .mask   = 0x0007ffff,
+       },
+       { 0, 0 },
+};
+
+static struct amba_driver etb_driver = {
+       .drv            = {
+               .name   = "etb",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = etb_probe,
+       .remove         = etb_remove,
+       .id_table       = etb_ids,
+};
+
+/* use a sysfs file "trace_running" to start/stop tracing */
+static ssize_t trace_running_show(struct kobject *kobj,
+                                 struct kobj_attribute *attr,
+                                 char *buf)
+{
+       return sprintf(buf, "%x\n", trace_isrunning(&tracer));
+}
+
+static ssize_t trace_running_store(struct kobject *kobj,
+                                  struct kobj_attribute *attr,
+                                  const char *buf, size_t n)
+{
+       unsigned int value;
+       int ret;
+
+       if (sscanf(buf, "%u", &value) != 1)
+               return -EINVAL;
+
+       mutex_lock(&tracer.mutex);
+       ret = value ? trace_start(&tracer) : trace_stop(&tracer);
+       mutex_unlock(&tracer.mutex);
+
+       return ret ? : n;
+}
+
+static struct kobj_attribute trace_running_attr =
+       __ATTR(trace_running, 0644, trace_running_show, trace_running_store);
+
+static ssize_t trace_info_show(struct kobject *kobj,
+                                 struct kobj_attribute *attr,
+                                 char *buf)
+{
+       u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st;
+       int datalen;
+
+       etb_unlock(&tracer);
+       datalen = etb_getdatalen(&tracer);
+       etb_wa = etb_readl(&tracer, ETBR_WRITEADDR);
+       etb_ra = etb_readl(&tracer, ETBR_READADDR);
+       etb_st = etb_readl(&tracer, ETBR_STATUS);
+       etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL);
+       etb_lock(&tracer);
+
+       etm_unlock(&tracer);
+       etm_ctrl = etm_readl(&tracer, ETMR_CTRL);
+       etm_st = etm_readl(&tracer, ETMR_STATUS);
+       etm_lock(&tracer);
+
+       return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n"
+                       "ETBR_WRITEADDR:\t%08x\n"
+                       "ETBR_READADDR:\t%08x\n"
+                       "ETBR_STATUS:\t%08x\n"
+                       "ETBR_FORMATTERCTRL:\t%08x\n"
+                       "ETMR_CTRL:\t%08x\n"
+                       "ETMR_STATUS:\t%08x\n",
+                       datalen,
+                       tracer.ncmppairs,
+                       etb_wa,
+                       etb_ra,
+                       etb_st,
+                       etb_fc,
+                       etm_ctrl,
+                       etm_st
+                       );
+}
+
+static struct kobj_attribute trace_info_attr =
+       __ATTR(trace_info, 0444, trace_info_show, NULL);
+
+static ssize_t trace_mode_show(struct kobject *kobj,
+                                 struct kobj_attribute *attr,
+                                 char *buf)
+{
+       return sprintf(buf, "%d %d\n",
+                       !!(tracer.flags & TRACER_CYCLE_ACC),
+                       tracer.etm_portsz);
+}
+
+static ssize_t trace_mode_store(struct kobject *kobj,
+                                  struct kobj_attribute *attr,
+                                  const char *buf, size_t n)
+{
+       unsigned int cycacc, portsz;
+
+       if (sscanf(buf, "%u %u", &cycacc, &portsz) != 2)
+               return -EINVAL;
+
+       mutex_lock(&tracer.mutex);
+       if (cycacc)
+               tracer.flags |= TRACER_CYCLE_ACC;
+       else
+               tracer.flags &= ~TRACER_CYCLE_ACC;
+
+       tracer.etm_portsz = portsz & 0x0f;
+       mutex_unlock(&tracer.mutex);
+
+       return n;
+}
+
+static struct kobj_attribute trace_mode_attr =
+       __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
+
+static int __init etm_probe(struct amba_device *dev, struct amba_id *id)
+{
+       struct tracectx *t = &tracer;
+       int ret = 0;
+
+       if (t->etm_regs) {
+               dev_dbg(&dev->dev, "ETM already initialized\n");
+               ret = -EBUSY;
+               goto out;
+       }
+
+       ret = amba_request_regions(dev, NULL);
+       if (ret)
+               goto out;
+
+       t->etm_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res));
+       if (!t->etm_regs) {
+               ret = -ENOMEM;
+               goto out_release;
+       }
+
+       amba_set_drvdata(dev, t);
+
+       mutex_init(&t->mutex);
+       t->dev = &dev->dev;
+       t->flags = TRACER_CYCLE_ACC;
+       t->etm_portsz = 1;
+
+       etm_unlock(t);
+       ret = etm_readl(t, CSCR_PRSR);
+
+       t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf;
+       etm_writel(t, 0x440, ETMR_CTRL);
+       etm_lock(t);
+
+       ret = sysfs_create_file(&dev->dev.kobj,
+                       &trace_running_attr.attr);
+       if (ret)
+               goto out_unmap;
+
+       /* failing to create any of these two is not fatal */
+       ret = sysfs_create_file(&dev->dev.kobj, &trace_info_attr.attr);
+       if (ret)
+               dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n");
+
+       ret = sysfs_create_file(&dev->dev.kobj, &trace_mode_attr.attr);
+       if (ret)
+               dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n");
+
+       dev_dbg(t->dev, "ETM AMBA driver initialized.\n");
+
+out:
+       return ret;
+
+out_unmap:
+       amba_set_drvdata(dev, NULL);
+       iounmap(t->etm_regs);
+
+out_release:
+       amba_release_regions(dev);
+
+       return ret;
+}
+
+static int etm_remove(struct amba_device *dev)
+{
+       struct tracectx *t = amba_get_drvdata(dev);
+
+       amba_set_drvdata(dev, NULL);
+
+       iounmap(t->etm_regs);
+       t->etm_regs = NULL;
+
+       amba_release_regions(dev);
+
+       sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr);
+       sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr);
+       sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr);
+
+       return 0;
+}
+
+static struct amba_id etm_ids[] = {
+       {
+               .id     = 0x0003b921,
+               .mask   = 0x0007ffff,
+       },
+       { 0, 0 },
+};
+
+static struct amba_driver etm_driver = {
+       .drv            = {
+               .name   = "etm",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = etm_probe,
+       .remove         = etm_remove,
+       .id_table       = etm_ids,
+};
+
+static int __init etm_init(void)
+{
+       int retval;
+
+       retval = amba_driver_register(&etb_driver);
+       if (retval) {
+               printk(KERN_ERR "Failed to register etb\n");
+               return retval;
+       }
+
+       retval = amba_driver_register(&etm_driver);
+       if (retval) {
+               amba_driver_unregister(&etb_driver);
+               printk(KERN_ERR "Failed to probe etm\n");
+               return retval;
+       }
+
+       /* not being able to install this handler is not fatal */
+       (void)register_sysrq_key('v', &sysrq_etm_op);
+
+       return 0;
+}
+
+device_initcall(etm_init);
+
index 2a573d4..e7714f3 100644 (file)
@@ -662,8 +662,12 @@ static void do_signal(struct pt_regs *regs, int syscall)
                                regs->ARM_sp -= 4;
                                usp = (u32 __user *)regs->ARM_sp;
 
-                               put_user(regs->ARM_pc, usp);
-                               regs->ARM_pc = KERN_RESTART_CODE;
+                               if (put_user(regs->ARM_pc, usp) == 0) {
+                                       regs->ARM_pc = KERN_RESTART_CODE;
+                               } else {
+                                       regs->ARM_sp += 4;
+                                       force_sigsegv(0, current);
+                               }
 #endif
                        }
                }
index 2fd8843..c71e39e 100644 (file)
@@ -163,6 +163,11 @@ config MACH_CPUAT91
          Select this if you are using the Eukrea Electromatique's
          CPUAT91 board <http://www.eukrea.com/>.
 
+config MACH_ECO920
+       bool "eco920"
+       help
+         Select this if you are using the eco920 board
+
 endif
 
 # ----------------------------------------------------------
index ada440a..709fbad 100644 (file)
@@ -35,6 +35,7 @@ obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o
 obj-$(CONFIG_MACH_ECBAT91)     += board-ecbat91.o
 obj-$(CONFIG_MACH_YL9200)      += board-yl-9200.o
 obj-$(CONFIG_MACH_CPUAT91)     += board-cpuat91.o
+obj-$(CONFIG_MACH_ECO920)      += board-eco920.o
 
 # AT91SAM9260 board-specific support
 obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
@@ -77,6 +78,7 @@ obj-y                         += leds.o
 # Power Management
 obj-$(CONFIG_PM)               += pm.o
 obj-$(CONFIG_AT91_SLOW_CLOCK)  += pm_slowclock.o
+obj-$(CONFIG_CPU_IDLE) += cpuidle.o
 
 ifeq ($(CONFIG_PM_DEBUG),y)
 CFLAGS_pm.o += -DDEBUG
index 332b784..a57af3e 100644 (file)
@@ -130,6 +130,62 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {}
 #endif
 
 
+/* --------------------------------------------------------------------
+ *  USB Host HS (EHCI)
+ *  Needs an OHCI host for low and full speed management
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
+static struct at91_usbh_data usbh_ehci_data;
+
+static struct resource usbh_ehci_resources[] = {
+       [0] = {
+               .start  = AT91SAM9G45_EHCI_BASE,
+               .end    = AT91SAM9G45_EHCI_BASE + SZ_1M - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = AT91SAM9G45_ID_UHPHS,
+               .end    = AT91SAM9G45_ID_UHPHS,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device at91_usbh_ehci_device = {
+       .name           = "atmel-ehci",
+       .id             = -1,
+       .dev            = {
+                               .dma_mask               = &ehci_dmamask,
+                               .coherent_dma_mask      = DMA_BIT_MASK(32),
+                               .platform_data          = &usbh_ehci_data,
+       },
+       .resource       = usbh_ehci_resources,
+       .num_resources  = ARRAY_SIZE(usbh_ehci_resources),
+};
+
+void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data)
+{
+       int i;
+
+       if (!data)
+               return;
+
+       /* Enable VBus control for UHP ports */
+       for (i = 0; i < data->ports; i++) {
+               if (data->vbus_pin[i])
+                       at91_set_gpio_output(data->vbus_pin[i], 0);
+       }
+
+       usbh_ehci_data = *data;
+       at91_clock_associate("uhphs_clk", &at91_usbh_ehci_device.dev, "ehci_clk");
+       platform_device_register(&at91_usbh_ehci_device);
+}
+#else
+void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {}
+#endif
+
+
 /* --------------------------------------------------------------------
  *  USB HS Device (Gadget)
  * -------------------------------------------------------------------- */
diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c
new file mode 100644 (file)
index 0000000..295a966
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/board.h>
+#include <mach/at91rm9200_mc.h>
+#include "generic.h"
+
+static void __init eco920_map_io(void)
+{
+       at91rm9200_initialize(18432000, AT91RM9200_PQFP);
+
+       /* Setup the LEDs */
+       at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
+
+       /* DBGU on ttyS0. (Rx & Tx only */
+       at91_register_uart(0, 0, 0);
+
+       /* set serial console to ttyS0 (ie, DBGU) */
+       at91_set_serial_console(0);
+}
+
+static void __init eco920_init_irq(void)
+{
+       at91rm9200_init_interrupts(NULL);
+}
+
+static struct at91_eth_data __initdata eco920_eth_data = {
+       .phy_irq_pin    = AT91_PIN_PC2,
+       .is_rmii        = 1,
+};
+
+static struct at91_usbh_data __initdata eco920_usbh_data = {
+       .ports          = 1,
+};
+
+static struct at91_udc_data __initdata eco920_udc_data = {
+       .vbus_pin       = AT91_PIN_PB12,
+       .pullup_pin     = AT91_PIN_PB13,
+};
+
+static struct at91_mmc_data __initdata eco920_mmc_data = {
+       .slot_b         = 0,
+       .wire4          = 0,
+};
+
+static struct physmap_flash_data eco920_flash_data = {
+       .width  = 2,
+};
+
+static struct resource eco920_flash_resource = {
+       .start          = 0x11000000,
+       .end            = 0x11ffffff,
+       .flags          = IORESOURCE_MEM,
+};
+
+static struct platform_device eco920_flash = {
+       .name           = "physmap-flash",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &eco920_flash_data,
+       },
+       .resource       = &eco920_flash_resource,
+       .num_resources  = 1,
+};
+
+static struct resource at91_beeper_resources[] = {
+       [0] = {
+               .start          = AT91RM9200_BASE_TC3,
+               .end            = AT91RM9200_BASE_TC3 + 0x39,
+               .flags          = IORESOURCE_MEM,
+       },
+};
+
+static struct platform_device at91_beeper = {
+       .name           = "at91_beeper",
+       .id             = 0,
+       .resource       = at91_beeper_resources,
+       .num_resources  = ARRAY_SIZE(at91_beeper_resources),
+};
+
+static struct spi_board_info eco920_spi_devices[] = {
+       {       /* CAN controller */
+               .modalias       = "tlv5638",
+               .chip_select    = 3,
+               .max_speed_hz   = 20 * 1000 * 1000,
+               .mode           = SPI_CPHA,
+       },
+};
+
+static void __init eco920_board_init(void)
+{
+       at91_add_device_serial();
+       at91_add_device_eth(&eco920_eth_data);
+       at91_add_device_usbh(&eco920_usbh_data);
+       at91_add_device_udc(&eco920_udc_data);
+
+       at91_add_device_mmc(0, &eco920_mmc_data);
+       platform_device_register(&eco920_flash);
+
+       at91_sys_write(AT91_SMC_CSR(7), AT91_SMC_RWHOLD_(1)
+                               | AT91_SMC_RWSETUP_(1)
+                               | AT91_SMC_DBW_8
+                               | AT91_SMC_WSEN
+                               | AT91_SMC_NWS_(15));
+
+       at91_set_A_periph(AT91_PIN_PC6, 1);
+
+       at91_set_gpio_input(AT91_PIN_PA23, 0);
+       at91_set_deglitch(AT91_PIN_PA23, 1);
+
+/* Initialization of the Static Memory Controller for Chip Select 3 */
+       at91_sys_write(AT91_SMC_CSR(3),
+               AT91_SMC_DBW_16  |      /* 16 bit */
+               AT91_SMC_WSEN    |
+               AT91_SMC_NWS_(5) |      /* wait states */
+               AT91_SMC_TDF_(1)        /* float time */
+       );
+
+       at91_clock_associate("tc3_clk", &at91_beeper.dev, "at91_beeper");
+       at91_set_B_periph(AT91_PIN_PB6, 0);
+       platform_device_register(&at91_beeper);
+
+       at91_add_device_spi(eco920_spi_devices, ARRAY_SIZE(eco920_spi_devices));
+}
+
+MACHINE_START(ECO920, "eco920")
+       /* Maintainer: Sascha Hauer */
+       .phys_io        = AT91_BASE_SYS,
+       .io_pg_offst    = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+       .boot_params    = AT91_SDRAM_BASE + 0x100,
+       .timer          = &at91rm9200_timer,
+       .map_io         = eco920_map_io,
+       .init_irq       = eco920_init_irq,
+       .init_machine   = eco920_board_init,
+MACHINE_END
index 64c3843..1cf4d86 100644 (file)
@@ -366,6 +366,7 @@ static void __init ek_board_init(void)
        at91_add_device_serial();
        /* USB HS Host */
        at91_add_device_usbh_ohci(&ek_usbh_hs_data);
+       at91_add_device_usbh_ehci(&ek_usbh_hs_data);
        /* USB HS Device */
        at91_add_device_usba(&ek_usba_udc_data);
        /* SPI */
diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c
new file mode 100644 (file)
index 0000000..1cfeac1
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * based on arch/arm/mach-kirkwood/cpuidle.c
+ *
+ * CPU idle support for AT91 SoC
+ *
+ * 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.
+ *
+ * The cpu idle uses wait-for-interrupt and RAM self refresh in order
+ * to implement two idle states -
+ * #1 wait-for-interrupt
+ * #2 wait-for-interrupt and RAM self refresh
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/cpuidle.h>
+#include <asm/proc-fns.h>
+#include <linux/io.h>
+
+#include "pm.h"
+
+#define AT91_MAX_STATES        2
+
+static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device);
+
+static struct cpuidle_driver at91_idle_driver = {
+       .name =         "at91_idle",
+       .owner =        THIS_MODULE,
+};
+
+/* Actual code that puts the SoC in different idle states */
+static int at91_enter_idle(struct cpuidle_device *dev,
+                              struct cpuidle_state *state)
+{
+       struct timeval before, after;
+       int idle_time;
+       u32 saved_lpr;
+
+       local_irq_disable();
+       do_gettimeofday(&before);
+       if (state == &dev->states[0])
+               /* Wait for interrupt state */
+               cpu_do_idle();
+       else if (state == &dev->states[1]) {
+               asm("b 1f; .align 5; 1:");
+               asm("mcr p15, 0, r0, c7, c10, 4");      /* drain write buffer */
+               saved_lpr = sdram_selfrefresh_enable();
+               cpu_do_idle();
+               sdram_selfrefresh_disable(saved_lpr);
+       }
+       do_gettimeofday(&after);
+       local_irq_enable();
+       idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+                       (after.tv_usec - before.tv_usec);
+       return idle_time;
+}
+
+/* Initialize CPU idle by registering the idle states */
+static int at91_init_cpuidle(void)
+{
+       struct cpuidle_device *device;
+
+       cpuidle_register_driver(&at91_idle_driver);
+
+       device = &per_cpu(at91_cpuidle_device, smp_processor_id());
+       device->state_count = AT91_MAX_STATES;
+
+       /* Wait for interrupt state */
+       device->states[0].enter = at91_enter_idle;
+       device->states[0].exit_latency = 1;
+       device->states[0].target_residency = 10000;
+       device->states[0].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(device->states[0].name, "WFI");
+       strcpy(device->states[0].desc, "Wait for interrupt");
+
+       /* Wait for interrupt and RAM self refresh state */
+       device->states[1].enter = at91_enter_idle;
+       device->states[1].exit_latency = 10;
+       device->states[1].target_residency = 10000;
+       device->states[1].flags = CPUIDLE_FLAG_TIME_VALID;
+       strcpy(device->states[1].name, "RAM_SR");
+       strcpy(device->states[1].desc, "WFI and RAM Self Refresh");
+
+       if (cpuidle_register_device(device)) {
+               printk(KERN_ERR "at91_init_cpuidle: Failed registering\n");
+               return -EIO;
+       }
+       return 0;
+}
+
+device_initcall(at91_init_cpuidle);
index 2f4fced..2295d80 100644 (file)
@@ -98,6 +98,7 @@ struct at91_usbh_data {
 };
 extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
 extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data);
+extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data);
 
  /* NAND / SmartMedia */
 struct atmel_nand_data {
index 4028724..6156689 100644 (file)
 #include <mach/cpu.h>
 
 #include "generic.h"
-
-#ifdef CONFIG_ARCH_AT91RM9200
-#include <mach/at91rm9200_mc.h>
-
-/*
- * The AT91RM9200 goes into self-refresh mode with this command, and will
- * terminate self-refresh automatically on the next SDRAM access.
- */
-#define sdram_selfrefresh_enable()     at91_sys_write(AT91_SDRAMC_SRR, 1)
-#define sdram_selfrefresh_disable()    do {} while (0)
-
-#elif defined(CONFIG_ARCH_AT91CAP9)
-#include <mach/at91cap9_ddrsdr.h>
-
-static u32 saved_lpr;
-
-static inline void sdram_selfrefresh_enable(void)
-{
-       u32 lpr;
-
-       saved_lpr = at91_sys_read(AT91_DDRSDRC_LPR);
-
-       lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
-       at91_sys_write(AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
-}
-
-#define sdram_selfrefresh_disable()    at91_sys_write(AT91_DDRSDRC_LPR, saved_lpr)
-
-#else
-#include <mach/at91sam9_sdramc.h>
-
-#ifdef CONFIG_ARCH_AT91SAM9263
-/*
- * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
- * handle those cases both here and in the Suspend-To-RAM support.
- */
-#define        AT91_SDRAMC     AT91_SDRAMC0
-#warning Assuming EB1 SDRAM controller is *NOT* used
-#endif
-
-static u32 saved_lpr;
-
-static inline void sdram_selfrefresh_enable(void)
-{
-       u32 lpr;
-
-       saved_lpr = at91_sys_read(AT91_SDRAMC_LPR);
-
-       lpr = saved_lpr & ~AT91_SDRAMC_LPCB;
-       at91_sys_write(AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH);
-}
-
-#define sdram_selfrefresh_disable()    at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
-
-#endif
-
+#include "pm.h"
 
 /*
  * Show the reason for the previous system reset.
@@ -260,6 +205,7 @@ extern u32 at91_slow_clock_sz;
 
 static int at91_pm_enter(suspend_state_t state)
 {
+       u32 saved_lpr;
        at91_gpio_suspend();
        at91_irq_suspend();
 
@@ -315,9 +261,9 @@ static int at91_pm_enter(suspend_state_t state)
                         */
                        asm("b 1f; .align 5; 1:");
                        asm("mcr p15, 0, r0, c7, c10, 4");      /* drain write buffer */
-                       sdram_selfrefresh_enable();
+                       saved_lpr = sdram_selfrefresh_enable();
                        asm("mcr p15, 0, r0, c7, c0, 4");       /* wait for interrupt */
-                       sdram_selfrefresh_disable();
+                       sdram_selfrefresh_disable(saved_lpr);
                        break;
 
                case PM_SUSPEND_ON:
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
new file mode 100644 (file)
index 0000000..08322c4
--- /dev/null
@@ -0,0 +1,67 @@
+#ifdef CONFIG_ARCH_AT91RM9200
+#include <mach/at91rm9200_mc.h>
+
+/*
+ * The AT91RM9200 goes into self-refresh mode with this command, and will
+ * terminate self-refresh automatically on the next SDRAM access.
+ *
+ * Self-refresh mode is exited as soon as a memory access is made, but we don't
+ * know for sure when that happens. However, we need to restore the low-power
+ * mode if it was enabled before going idle. Restoring low-power mode while
+ * still in self-refresh is "not recommended", but seems to work.
+ */
+
+static inline u32 sdram_selfrefresh_enable(void)
+{
+       u32 saved_lpr = at91_sys_read(AT91_SDRAMC_LPR);
+
+       at91_sys_write(AT91_SDRAMC_LPR, 0);
+       at91_sys_write(AT91_SDRAMC_SRR, 1);
+       return saved_lpr;
+}
+
+#define sdram_selfrefresh_disable(saved_lpr)   at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
+
+#elif defined(CONFIG_ARCH_AT91CAP9)
+#include <mach/at91cap9_ddrsdr.h>
+
+
+static inline u32 sdram_selfrefresh_enable(void)
+{
+       u32 saved_lpr, lpr;
+
+       saved_lpr = at91_sys_read(AT91_DDRSDRC_LPR);
+
+       lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
+       at91_sys_write(AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
+       return saved_lpr;
+}
+
+#define sdram_selfrefresh_disable(saved_lpr)   at91_sys_write(AT91_DDRSDRC_LPR, saved_lpr)
+
+#else
+#include <mach/at91sam9_sdramc.h>
+
+#ifdef CONFIG_ARCH_AT91SAM9263
+/*
+ * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
+ * handle those cases both here and in the Suspend-To-RAM support.
+ */
+#define        AT91_SDRAMC     AT91_SDRAMC0
+#warning Assuming EB1 SDRAM controller is *NOT* used
+#endif
+
+static inline u32 sdram_selfrefresh_enable(void)
+{
+       u32 saved_lpr, lpr;
+
+       saved_lpr = at91_sys_read(AT91_SDRAMC_LPR);
+
+       lpr = saved_lpr & ~AT91_SDRAMC_LPCB;
+       at91_sys_write(AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH);
+       return saved_lpr;
+}
+
+#define sdram_selfrefresh_disable(saved_lpr)   at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
+
+#endif
index 4db0eff..dae5e9b 100644 (file)
 
 #define IO_SPACE_LIMIT 0xffffffff
 
-#define __io(a)         ((void __iomem *)HW_IO_PHYS_TO_VIRT(a))
-
-/* Do not enable mem_pci for a big endian arm architecture or unexpected byteswaps will */
-/* happen in readw/writew etc. */
-
-#define readb(c)        __raw_readb(c)
-#define readw(c)        __raw_readw(c)
-#define readl(c)        __raw_readl(c)
-#define readb_relaxed(addr) readb(addr)
-#define readw_relaxed(addr) readw(addr)
-#define readl_relaxed(addr) readl(addr)
-
-#define readsb(p, d, l)   __raw_readsb(p, d, l)
-#define readsw(p, d, l)   __raw_readsw(p, d, l)
-#define readsl(p, d, l)   __raw_readsl(p, d, l)
-
-#define writeb(v, c)     __raw_writeb(v, c)
-#define writew(v, c)     __raw_writew(v, c)
-#define writel(v, c)     __raw_writel(v, c)
-
-#define writesb(p, d, l)  __raw_writesb(p, d, l)
-#define writesw(p, d, l)  __raw_writesw(p, d, l)
-#define writesl(p, d, l)  __raw_writesl(p, d, l)
-
-#define memset_io(c, v, l)    _memset_io((c), (v), (l))
-#define memcpy_fromio(a, c, l)    _memcpy_fromio((a), (c), (l))
-#define memcpy_toio(c, a, l)  _memcpy_toio((c), (a), (l))
-
-#define eth_io_copy_and_sum(s, c, l, b) eth_copy_and_sum((s), (c), (l), (b))
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a)                __typesafe_io(a)
+#define __mem_pci(a)   (a)
 
 #endif
index 42ae29b..25b1da9 100644 (file)
@@ -64,6 +64,8 @@ static inline unsigned long __lbus_to_virt(dma_addr_t x)
                (dma_addr_t)page_to_phys(page);                         \
        })
 
+#define __arch_dma_to_page(dev, addr)  phys_to_page(addr)
+
 #endif /* CONFIG_ARCH_IOP13XX */
 #endif /* !ASSEMBLY */
 
index 76e5308..ffa19aa 100644 (file)
@@ -41,6 +41,13 @@ extern struct bus_type platform_bus_type;
                __dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \
           __dma; })
 
+#define __arch_dma_to_page(dev, x)     \
+       ({ dma_addr_t __dma = x;                                \
+          if (!is_lbus_device(dev))                            \
+               __dma += PHYS_OFFSET - KS8695_PCIMEM_PA;        \
+          phys_to_page(__dma);                                 \
+       })
+
 #endif
 
 #endif
index 2a02b49..3c5e0f5 100644 (file)
@@ -5,13 +5,13 @@ menu "Nomadik boards"
 config MACH_NOMADIK_8815NHK
        bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
        select NOMADIK_8815
+       select HAS_MTU
 
 endmenu
 
 config NOMADIK_8815
        bool
 
-
 config I2C_BITBANG_8815NHK
        tristate "Driver for bit-bang busses found on the 8815 NHK"
        depends on I2C && MACH_NOMADIK_8815NHK
index 4120409..36f67fb 100644 (file)
@@ -7,7 +7,7 @@
 
 # Object file lists.
 
-obj-y                  += clock.o timer.o gpio.o
+obj-y                  += clock.o gpio.o
 
 # Cpu revision
 obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o
index 6bfd537..1163944 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/flash.h>
+
+#include <plat/mtu.h>
+
 #include <mach/setup.h>
 #include <mach/nand.h>
 #include <mach/fsmc.h>
 #include "clock.h"
 
+/* Initial value for SRC control register: all timers use MXTAL/8 source */
+#define SRC_CR_INIT_MASK       0x00007fff
+#define SRC_CR_INIT_VAL                0x2aaa8000
+
 /* These adresses span 16MB, so use three individual pages */
 static struct resource nhk8815_nand_resources[] = {
        {
@@ -239,6 +246,26 @@ static struct platform_device *nhk8815_platform_devices[] __initdata = {
        /* will add more devices */
 };
 
+static void __init nomadik_timer_init(void)
+{
+       u32 src_cr;
+
+       /* Configure timer sources in "system reset controller" ctrl reg */
+       src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
+       src_cr &= SRC_CR_INIT_MASK;
+       src_cr |= SRC_CR_INIT_VAL;
+       writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
+
+       /* Save global pointer to mtu, used by platform timer code */
+       mtu_base = io_p2v(NOMADIK_MTU0_BASE);
+
+       nmdk_timer_init();
+}
+
+static struct sys_timer nomadik_timer = {
+       .init   = nomadik_timer_init,
+};
+
 static void __init nhk8815_platform_init(void)
 {
        int i;
diff --git a/arch/arm/mach-nomadik/include/mach/mtu.h b/arch/arm/mach-nomadik/include/mach/mtu.h
deleted file mode 100644 (file)
index 76da7f0..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef __ASM_ARCH_MTU_H
-#define __ASM_ARCH_MTU_H
-
-/*
- * The MTU device hosts four different counters, with 4 set of
- * registers. These are register names.
- */
-
-#define MTU_IMSC       0x00    /* Interrupt mask set/clear */
-#define MTU_RIS                0x04    /* Raw interrupt status */
-#define MTU_MIS                0x08    /* Masked interrupt status */
-#define MTU_ICR                0x0C    /* Interrupt clear register */
-
-/* per-timer registers take 0..3 as argument */
-#define MTU_LR(x)      (0x10 + 0x10 * (x) + 0x00)      /* Load value */
-#define MTU_VAL(x)     (0x10 + 0x10 * (x) + 0x04)      /* Current value */
-#define MTU_CR(x)      (0x10 + 0x10 * (x) + 0x08)      /* Control reg */
-#define MTU_BGLR(x)    (0x10 + 0x10 * (x) + 0x0c)      /* At next overflow */
-
-/* bits for the control register */
-#define MTU_CRn_ENA            0x80
-#define MTU_CRn_PERIODIC       0x40    /* if 0 = free-running */
-#define MTU_CRn_PRESCALE_MASK  0x0c
-#define MTU_CRn_PRESCALE_1             0x00
-#define MTU_CRn_PRESCALE_16            0x04
-#define MTU_CRn_PRESCALE_256           0x08
-#define MTU_CRn_32BITS         0x02
-#define MTU_CRn_ONESHOT                0x01    /* if 0 = wraps reloading from BGLR*/
-
-/* Other registers are usual amba/primecell registers, currently not used */
-#define MTU_ITCR       0xff0
-#define MTU_ITOP       0xff4
-
-#define MTU_PERIPH_ID0 0xfe0
-#define MTU_PERIPH_ID1 0xfe4
-#define MTU_PERIPH_ID2 0xfe8
-#define MTU_PERIPH_ID3 0xfeC
-
-#define MTU_PCELL0     0xff0
-#define MTU_PCELL1     0xff4
-#define MTU_PCELL2     0xff8
-#define MTU_PCELL3     0xffC
-
-#endif /* __ASM_ARCH_MTU_H */
-
index a4e468c..b7897ed 100644 (file)
@@ -15,7 +15,7 @@
 extern void cpu8815_map_io(void);
 extern void cpu8815_platform_init(void);
 extern void cpu8815_init_irq(void);
-extern struct sys_timer nomadik_timer;
+extern void nmdk_timer_init(void);
 
 #endif /* NOMADIK_8815 */
 
diff --git a/arch/arm/mach-nomadik/timer.c b/arch/arm/mach-nomadik/timer.c
deleted file mode 100644 (file)
index d1738e7..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- *  linux/arch/arm/mach-nomadik/timer.c
- *
- * Copyright (C) 2008 STMicroelectronics
- * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2, as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/clockchips.h>
-#include <linux/jiffies.h>
-#include <asm/mach/time.h>
-#include <mach/mtu.h>
-
-#define TIMER_CTRL     0x80    /* No divisor */
-#define TIMER_PERIODIC 0x40
-#define TIMER_SZ32BIT  0x02
-
-/* Initial value for SRC control register: all timers use MXTAL/8 source */
-#define SRC_CR_INIT_MASK       0x00007fff
-#define SRC_CR_INIT_VAL                0x2aaa8000
-
-static u32     nmdk_count;             /* accumulated count */
-static u32     nmdk_cycle;             /* write-once */
-static __iomem void *mtu_base;
-
-/*
- * clocksource: the MTU device is a decrementing counters, so we negate
- * the value being read.
- */
-static cycle_t nmdk_read_timer(struct clocksource *cs)
-{
-       u32 count = readl(mtu_base + MTU_VAL(0));
-       return nmdk_count + nmdk_cycle - count;
-
-}
-
-static struct clocksource nmdk_clksrc = {
-       .name           = "mtu_0",
-       .rating         = 120,
-       .read           = nmdk_read_timer,
-       .shift          = 20,
-       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-/*
- * Clockevent device: currently only periodic mode is supported
- */
-static void nmdk_clkevt_mode(enum clock_event_mode mode,
-                            struct clock_event_device *dev)
-{
-       unsigned long flags;
-
-       switch (mode) {
-       case CLOCK_EVT_MODE_PERIODIC:
-               /* enable interrupts -- and count current value? */
-               raw_local_irq_save(flags);
-               writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
-               raw_local_irq_restore(flags);
-               break;
-       case CLOCK_EVT_MODE_ONESHOT:
-               BUG(); /* Not supported, yet */
-               /* FALLTHROUGH */
-       case CLOCK_EVT_MODE_SHUTDOWN:
-       case CLOCK_EVT_MODE_UNUSED:
-               /* disable irq */
-               raw_local_irq_save(flags);
-               writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
-               raw_local_irq_restore(flags);
-               break;
-       case CLOCK_EVT_MODE_RESUME:
-               break;
-       }
-}
-
-static struct clock_event_device nmdk_clkevt = {
-       .name           = "mtu_0",
-       .features       = CLOCK_EVT_FEAT_PERIODIC,
-       .shift          = 32,
-       .rating         = 100,
-       .set_mode       = nmdk_clkevt_mode,
-};
-
-/*
- * IRQ Handler for the timer 0 of the MTU block. The irq is not shared
- * as we are the only users of mtu0 by now.
- */
-static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
-{
-       /* ack: "interrupt clear register" */
-       writel( 1 << 0, mtu_base + MTU_ICR);
-
-       /* we can't count lost ticks, unfortunately */
-       nmdk_count += nmdk_cycle;
-       nmdk_clkevt.event_handler(&nmdk_clkevt);
-
-       return IRQ_HANDLED;
-}
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-static struct irqaction nmdk_timer_irq = {
-       .name           = "Nomadik Timer Tick",
-       .flags          = IRQF_DISABLED | IRQF_TIMER,
-       .handler        = nmdk_timer_interrupt,
-};
-
-static void nmdk_timer_reset(void)
-{
-       u32 cr;
-
-       writel(0, mtu_base + MTU_CR(0)); /* off */
-
-       /* configure load and background-load, and fire it up */
-       writel(nmdk_cycle, mtu_base + MTU_LR(0));
-       writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
-       cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS;
-       writel(cr, mtu_base + MTU_CR(0));
-       writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
-}
-
-static void __init nmdk_timer_init(void)
-{
-       u32 src_cr;
-       unsigned long rate;
-       int bits;
-
-       rate = CLOCK_TICK_RATE; /* 2.4MHz */
-       nmdk_cycle = (rate + HZ/2) / HZ;
-
-       /* Configure timer sources in "system reset controller" ctrl reg */
-       src_cr = readl(io_p2v(NOMADIK_SRC_BASE));
-       src_cr &= SRC_CR_INIT_MASK;
-       src_cr |= SRC_CR_INIT_VAL;
-       writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
-
-       /* Save global pointer to mtu, used by functions above */
-       mtu_base = io_p2v(NOMADIK_MTU0_BASE);
-
-       /* Init the timer and register clocksource */
-       nmdk_timer_reset();
-
-       nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
-       bits =  8*sizeof(nmdk_count);
-       nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits);
-
-       clocksource_register(&nmdk_clksrc);
-
-       /* Register irq and clockevents */
-       setup_irq(IRQ_MTU0, &nmdk_timer_irq);
-       nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
-       nmdk_clkevt.cpumask = cpumask_of(0);
-       clockevents_register_device(&nmdk_clkevt);
-}
-
-struct sys_timer nomadik_timer = {
-       .init           = nmdk_timer_init,
-};
index aad194f..6f1bbbc 100644 (file)
@@ -100,3 +100,11 @@ config MACH_OMAP_ZOOM2
 config MACH_OMAP_4430SDP
        bool "OMAP 4430 SDP board"
        depends on ARCH_OMAP4
+
+config OMAP3_EMU
+       bool "OMAP3 debugging peripherals"
+       depends on ARCH_OMAP3
+       select OC_ETM
+       help
+         Say Y here to enable debugging hardware of omap3
+
index 8cb1677..e141cab 100644 (file)
@@ -44,6 +44,9 @@ obj-$(CONFIG_ARCH_OMAP4)              += cm4xxx.o
 obj-$(CONFIG_ARCH_OMAP2)               += clock24xx.o
 obj-$(CONFIG_ARCH_OMAP3)               += clock34xx.o
 
+# EMU peripherals
+obj-$(CONFIG_OMAP3_EMU)                += emu.o
+
 iommu-y                                        += iommu2.o
 iommu-$(CONFIG_ARCH_OMAP3)             += omap3-iommu.o
 
index 7c5c00d..066e88a 100644 (file)
@@ -119,7 +119,7 @@ static struct omap_clk omap34xx_clks[] = {
        CLK(NULL,       "dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_343X),
        CLK(NULL,       "dpll3_m3_ck",  &dpll3_m3_ck,   CK_343X),
        CLK(NULL,       "dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_343X),
-       CLK(NULL,       "emu_core_alwon_ck", &emu_core_alwon_ck, CK_343X),
+       CLK("etb",      "emu_core_alwon_ck", &emu_core_alwon_ck, CK_343X),
        CLK(NULL,       "dpll4_ck",     &dpll4_ck,      CK_343X),
        CLK(NULL,       "dpll4_x2_ck",  &dpll4_x2_ck,   CK_343X),
        CLK(NULL,       "omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_343X),
@@ -138,7 +138,7 @@ static struct omap_clk omap34xx_clks[] = {
        CLK(NULL,       "dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_343X),
        CLK(NULL,       "dpll4_m6_ck",  &dpll4_m6_ck,   CK_343X),
        CLK(NULL,       "dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_343X),
-       CLK(NULL,       "emu_per_alwon_ck", &emu_per_alwon_ck, CK_343X),
+       CLK("etb",      "emu_per_alwon_ck", &emu_per_alwon_ck, CK_343X),
        CLK(NULL,       "dpll5_ck",     &dpll5_ck,      CK_3430ES2),
        CLK(NULL,       "dpll5_m2_ck",  &dpll5_m2_ck,   CK_3430ES2),
        CLK(NULL,       "clkout2_src_ck", &clkout2_src_ck, CK_343X),
@@ -147,7 +147,7 @@ static struct omap_clk omap34xx_clks[] = {
        CLK(NULL,       "dpll1_fck",    &dpll1_fck,     CK_343X),
        CLK(NULL,       "mpu_ck",       &mpu_ck,        CK_343X),
        CLK(NULL,       "arm_fck",      &arm_fck,       CK_343X),
-       CLK(NULL,       "emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_343X),
+       CLK("etb",      "emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_343X),
        CLK(NULL,       "dpll2_fck",    &dpll2_fck,     CK_343X),
        CLK(NULL,       "iva2_ck",      &iva2_ck,       CK_343X),
        CLK(NULL,       "l3_ick",       &l3_ick,        CK_343X),
@@ -302,7 +302,7 @@ static struct omap_clk omap34xx_clks[] = {
        CLK("omap-mcbsp.2", "fck",      &mcbsp2_fck,    CK_343X),
        CLK("omap-mcbsp.3", "fck",      &mcbsp3_fck,    CK_343X),
        CLK("omap-mcbsp.4", "fck",      &mcbsp4_fck,    CK_343X),
-       CLK(NULL,       "emu_src_ck",   &emu_src_ck,    CK_343X),
+       CLK("etb",      "emu_src_ck",   &emu_src_ck,    CK_343X),
        CLK(NULL,       "pclk_fck",     &pclk_fck,      CK_343X),
        CLK(NULL,       "pclkx2_fck",   &pclkx2_fck,    CK_343X),
        CLK(NULL,       "atclk_fck",    &atclk_fck,     CK_343X),
diff --git a/arch/arm/mach-omap2/emu.c b/arch/arm/mach-omap2/emu.c
new file mode 100644 (file)
index 0000000..ec0d984
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * emu.c
+ *
+ * ETM and ETB CoreSight components' resources as found in OMAP3xxx.
+ *
+ * Copyright (C) 2009 Nokia Corporation.
+ * Alexander Shishkin
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alexander Shishkin");
+
+/* Cortex CoreSight components within omap3xxx EMU */
+#define ETM_BASE       (L4_EMU_34XX_PHYS + 0x10000)
+#define DBG_BASE       (L4_EMU_34XX_PHYS + 0x11000)
+#define ETB_BASE       (L4_EMU_34XX_PHYS + 0x1b000)
+#define DAPCTL         (L4_EMU_34XX_PHYS + 0x1d000)
+
+static struct amba_device omap3_etb_device = {
+       .dev            = {
+               .init_name = "etb",
+       },
+       .res            = {
+               .start  = ETB_BASE,
+               .end    = ETB_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       .periphid       = 0x000bb907,
+};
+
+static struct amba_device omap3_etm_device = {
+       .dev            = {
+               .init_name = "etm",
+       },
+       .res            = {
+               .start  = ETM_BASE,
+               .end    = ETM_BASE + SZ_4K - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       .periphid       = 0x102bb921,
+};
+
+static int __init emu_init(void)
+{
+       amba_device_register(&omap3_etb_device, &iomem_resource);
+       amba_device_register(&omap3_etm_device, &iomem_resource);
+
+       return 0;
+}
+
+subsys_initcall(emu_init);
+
index 983cc8c..9e4d981 100644 (file)
@@ -447,6 +447,7 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy)
                pxa27x_freq_table[i].frequency = freq;
                pxa27x_freq_table[i].index = i;
        }
+       pxa27x_freq_table[i].index = i;
        pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END;
 
        /*
index 67f34a8..149cdd9 100644 (file)
@@ -102,7 +102,7 @@ static int setup_freqs_table(struct cpufreq_policy *policy,
                table[i].index = i;
                table[i].frequency = freqs[i].cpufreq_mhz * 1000;
        }
-       table[num].frequency = i;
+       table[num].index = i;
        table[num].frequency = CPUFREQ_TABLE_END;
 
        pxa3xx_freqs = freqs;
index 3da45d0..d98023f 100644 (file)
@@ -802,10 +802,12 @@ static void __init spitz_init(void)
 {
        spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON;
 
+#ifdef CONFIG_MACH_BORZOI
        if (machine_is_borzoi()) {
                sharpsl_nand_platform_data.badblock_pattern = &sharpsl_akita_bbt;
                sharpsl_nand_platform_data.ecc_layout = &akita_oobinfo;
        }
+#endif
 
        platform_scoop_config = &spitz_pcmcia_config;
 
index 885b5c0..fab46fe 100644 (file)
@@ -12,3 +12,4 @@ obj-$(CONFIG_MMC)                 += mmc.o
 obj-$(CONFIG_SPI_PL022)           += spi.o
 obj-$(CONFIG_MACH_U300_SPIDUMMY)  += dummyspichip.o
 obj-$(CONFIG_I2C_STU300)          += i2c.o
+obj-$(CONFIG_REGULATOR_AB3100)    += regulator.o
index 10be1f8..c73ed06 100644 (file)
  */
 #include <linux/kernel.h>
 #include <linux/i2c.h>
+#include <linux/mfd/ab3100.h>
+#include <linux/regulator/machine.h>
+#include <linux/amba/bus.h>
 #include <mach/irqs.h>
 
+/*
+ * Initial settings of ab3100 registers.
+ * Common for below LDO regulator settings are that
+ * bit 7-5 controls voltage. Bit 4 turns regulator ON(1) or OFF(0).
+ * Bit 3-2 controls sleep enable and bit 1-0 controls sleep mode.
+ */
+
+/* LDO_A 0x16: 2.75V, ON, SLEEP_A, SLEEP OFF GND */
+#define LDO_A_SETTING          0x16
+/* LDO_C 0x10: 2.65V, ON, SLEEP_A or B, SLEEP full power */
+#define LDO_C_SETTING          0x10
+/* LDO_D 0x10: 2.65V, ON, sleep mode not used */
+#define LDO_D_SETTING          0x10
+/* LDO_E 0x10: 1.8V, ON, SLEEP_A or B, SLEEP full power */
+#define LDO_E_SETTING          0x10
+/* LDO_E SLEEP 0x00: 1.8V, not used, SLEEP_A or B, not used */
+#define LDO_E_SLEEP_SETTING    0x00
+/* LDO_F 0xD0: 2.5V, ON, SLEEP_A or B, SLEEP full power */
+#define LDO_F_SETTING          0xD0
+/* LDO_G 0x00: 2.85V, OFF, SLEEP_A or B, SLEEP full power */
+#define LDO_G_SETTING          0x00
+/* LDO_H 0x18: 2.75V, ON, SLEEP_B, SLEEP full power */
+#define LDO_H_SETTING          0x18
+/* LDO_K 0x00: 2.75V, OFF, SLEEP_A or B, SLEEP full power */
+#define LDO_K_SETTING          0x00
+/* LDO_EXT 0x00: Voltage not set, OFF, not used, not used */
+#define LDO_EXT_SETTING                0x00
+/* BUCK 0x7D: 1.2V, ON, SLEEP_A and B, SLEEP low power */
+#define BUCK_SETTING   0x7D
+/* BUCK SLEEP 0xAC: 1.05V, Not used, SLEEP_A and B, Not used */
+#define BUCK_SLEEP_SETTING     0xAC
+
+static struct regulator_consumer_supply supply_ldo_c[] = {
+       {
+               .dev_name = "ab3100-codec",
+               .supply = "vaudio", /* Powers the codec */
+       },
+};
+
+/*
+ * This one needs to be a supply so we can turn it off
+ * in order to shut down the system.
+ */
+static struct regulator_consumer_supply supply_ldo_d[] = {
+       {
+               .dev = NULL,
+               .supply = "vana15", /* Powers the SoC (CPU etc) */
+       },
+};
+
+static struct regulator_consumer_supply supply_ldo_g[] = {
+       {
+               .dev_name = "mmci",
+               .supply = "vmmc", /* Powers MMC/SD card */
+       },
+};
+
+static struct regulator_consumer_supply supply_ldo_h[] = {
+       {
+               .dev_name = "xgam_pdi",
+               .supply = "vdisp", /* Powers camera, display etc */
+       },
+};
+
+static struct regulator_consumer_supply supply_ldo_k[] = {
+       {
+               .dev_name = "irda",
+               .supply = "vir", /* Power IrDA */
+       },
+};
+
+/*
+ * This is a placeholder for whoever wish to use the
+ * external power.
+ */
+static struct regulator_consumer_supply supply_ldo_ext[] = {
+       {
+               .dev = NULL,
+               .supply = "vext", /* External power */
+       },
+};
+
+/* Preset (hardware defined) voltages for these regulators */
+#define LDO_A_VOLTAGE 2750000
+#define LDO_C_VOLTAGE 2650000
+#define LDO_D_VOLTAGE 2650000
+
+static struct ab3100_platform_data ab3100_plf_data = {
+       .reg_constraints = {
+               /* LDO A routing and constraints */
+               {
+                       .constraints = {
+                               .name = "vrad",
+                               .min_uV = LDO_A_VOLTAGE,
+                               .max_uV = LDO_A_VOLTAGE,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .always_on = 1,
+                               .boot_on = 1,
+                       },
+               },
+               /* LDO C routing and constraints */
+               {
+                       .constraints = {
+                               .min_uV = LDO_C_VOLTAGE,
+                               .max_uV = LDO_C_VOLTAGE,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                       },
+                       .num_consumer_supplies = ARRAY_SIZE(supply_ldo_c),
+                       .consumer_supplies = supply_ldo_c,
+               },
+               /* LDO D routing and constraints */
+               {
+                       .constraints = {
+                               .min_uV = LDO_D_VOLTAGE,
+                               .max_uV = LDO_D_VOLTAGE,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+                               /*
+                                * Actually this is boot_on but we need
+                                * to reference count it externally to
+                                * be able to shut down the system.
+                                */
+                       },
+                       .num_consumer_supplies = ARRAY_SIZE(supply_ldo_d),
+                       .consumer_supplies = supply_ldo_d,
+               },
+               /* LDO E routing and constraints */
+               {
+                       .constraints = {
+                               .name = "vio",
+                               .min_uV = 1800000,
+                               .max_uV = 1800000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask =
+                               REGULATOR_CHANGE_VOLTAGE |
+                               REGULATOR_CHANGE_STATUS,
+                               .always_on = 1,
+                               .boot_on = 1,
+                       },
+               },
+               /* LDO F routing and constraints */
+               {
+                       .constraints = {
+                               .name = "vana25",
+                               .min_uV = 2500000,
+                               .max_uV = 2500000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask =
+                               REGULATOR_CHANGE_VOLTAGE |
+                               REGULATOR_CHANGE_STATUS,
+                               .always_on = 1,
+                               .boot_on = 1,
+                       },
+               },
+               /* LDO G routing and constraints */
+               {
+                       .constraints = {
+                               .min_uV = 1500000,
+                               .max_uV = 2850000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask =
+                               REGULATOR_CHANGE_VOLTAGE |
+                               REGULATOR_CHANGE_STATUS,
+                       },
+                       .num_consumer_supplies = ARRAY_SIZE(supply_ldo_g),
+                       .consumer_supplies = supply_ldo_g,
+               },
+               /* LDO H routing and constraints */
+               {
+                       .constraints = {
+                               .min_uV = 1200000,
+                               .max_uV = 2750000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask =
+                               REGULATOR_CHANGE_VOLTAGE |
+                               REGULATOR_CHANGE_STATUS,
+                       },
+                       .num_consumer_supplies = ARRAY_SIZE(supply_ldo_h),
+                       .consumer_supplies = supply_ldo_h,
+               },
+               /* LDO K routing and constraints */
+               {
+                       .constraints = {
+                               .min_uV = 1800000,
+                               .max_uV = 2750000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask =
+                               REGULATOR_CHANGE_VOLTAGE |
+                               REGULATOR_CHANGE_STATUS,
+                       },
+                       .num_consumer_supplies = ARRAY_SIZE(supply_ldo_k),
+                       .consumer_supplies = supply_ldo_k,
+               },
+               /* External regulator interface. No fixed voltage specified.
+                * If we knew the voltage of the external regulator and it
+                * was connected on the board, we could add the (fixed)
+                * voltage for it here.
+                */
+               {
+                       .constraints = {
+                               .min_uV = 0,
+                               .max_uV = 0,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask =
+                               REGULATOR_CHANGE_STATUS,
+                       },
+                       .num_consumer_supplies = ARRAY_SIZE(supply_ldo_ext),
+                       .consumer_supplies = supply_ldo_ext,
+               },
+               /* Buck converter routing and constraints */
+               {
+                       .constraints = {
+                               .name = "vcore",
+                               .min_uV = 1200000,
+                               .max_uV = 1800000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                               .valid_ops_mask =
+                               REGULATOR_CHANGE_VOLTAGE |
+                               REGULATOR_CHANGE_STATUS,
+                               .always_on = 1,
+                               .boot_on = 1,
+                       },
+               },
+       },
+       .reg_initvals = {
+               LDO_A_SETTING,
+               LDO_C_SETTING,
+               LDO_E_SETTING,
+               LDO_E_SLEEP_SETTING,
+               LDO_F_SETTING,
+               LDO_G_SETTING,
+               LDO_H_SETTING,
+               LDO_K_SETTING,
+               LDO_EXT_SETTING,
+               BUCK_SETTING,
+               BUCK_SLEEP_SETTING,
+               LDO_D_SETTING,
+       },
+};
+
 static struct i2c_board_info __initdata bus0_i2c_board_info[] = {
        {
                .type = "ab3100",
                .addr = 0x48,
                .irq = IRQ_U300_IRQ0_EXT,
+               .platform_data = &ab3100_plf_data,
        },
 };
 
@@ -38,6 +282,11 @@ void __init u300_i2c_register_board_devices(void)
 {
        i2c_register_board_info(0, bus0_i2c_board_info,
                                ARRAY_SIZE(bus0_i2c_board_info));
+       /*
+        * This makes the core shut down all unused regulators
+        * after all the initcalls have completed.
+        */
+       regulator_has_full_constraints();
        i2c_register_board_info(1, bus1_i2c_board_info,
                                ARRAY_SIZE(bus1_i2c_board_info));
 }
index 7b6b016..109f5a6 100644 (file)
@@ -40,64 +40,6 @@ static unsigned int mmc_status(struct device *dev)
        return mmci_card->mmc_inserted;
 }
 
-/*
- * Here follows a large chunk of code which will only be enabled if you
- * have both the AB3100 chip mounted and the MMC subsystem activated.
- */
-
-static u32 mmc_translate_vdd(struct device *dev, unsigned int voltage)
-{
-       int v;
-
-       /*
-        * MMC Spec:
-        * bit 7:       1.70 - 1.95V
-        * bit 8 - 14:  2.0 - 2.6V
-        * bit 15 - 23: 2.7 - 3.6V
-        *
-        * ab3100 voltages:
-        * 000 - 2.85V
-        * 001 - 2.75V
-        * 010 - 1.8V
-        * 011 - 1.5V
-        */
-       switch (voltage) {
-       case 8:
-               v = 3;
-               break;
-       case 9:
-       case 10:
-       case 11:
-       case 12:
-       case 13:
-       case 14:
-       case 15:
-               v = 1;
-               break;
-       case 16:
-               v = 1;
-               break;
-       case 17:
-       case 18:
-       case 19:
-       case 20:
-       case 21:
-       case 22:
-       case 23:
-       case 24:
-               v = 0;
-               break;
-       default:
-               v = 0;
-               break;
-       }
-
-       /* PL180 voltage register bits */
-       return v << 2;
-}
-
-
-
 static int mmci_callback(void *data)
 {
        struct mmci_card_event *mmci_card = data;
@@ -154,9 +96,11 @@ int __devinit mmc_init(struct amba_device *adev)
        if (!mmci_card)
                return -ENOMEM;
 
+       /*
+        * Do not set ocr_mask or voltage translation function,
+        * we have a regulator we can control instead.
+        */
        /* Nominally 2.85V on our platform */
-       mmci_card->mmc0_plat_data.ocr_mask = MMC_VDD_28_29;
-       mmci_card->mmc0_plat_data.translate_vdd = mmc_translate_vdd;
        mmci_card->mmc0_plat_data.status = mmc_status;
        mmci_card->mmc0_plat_data.gpio_wp = -1;
        mmci_card->mmc0_plat_data.gpio_cd = -1;
diff --git a/arch/arm/mach-u300/regulator.c b/arch/arm/mach-u300/regulator.c
new file mode 100644 (file)
index 0000000..9c53f01
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-u300/regulator.c
+ *
+ * Copyright (C) 2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * Handle board-bound regulators and board power not related
+ * to any devices.
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ */
+#include <linux/device.h>
+#include <linux/signal.h>
+#include <linux/err.h>
+#include <linux/regulator/consumer.h>
+/* Those are just for writing in syscon */
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/syscon.h>
+
+/*
+ * Regulators that power the board and chip and which are
+ * not copuled to specific drivers are hogged in these
+ * instances.
+ */
+static struct regulator *main_power_15;
+
+/*
+ * This function is used from pm.h to shut down the system by
+ * resetting all regulators in turn and then disable regulator
+ * LDO D (main power).
+ */
+void u300_pm_poweroff(void)
+{
+       sigset_t old, all;
+
+       sigfillset(&all);
+       if (!sigprocmask(SIG_BLOCK, &all, &old)) {
+               /* Disable LDO D to shut down the system */
+               if (main_power_15)
+                       regulator_disable(main_power_15);
+               else
+                       pr_err("regulator not available to shut down system\n");
+               (void) sigprocmask(SIG_SETMASK, &old, NULL);
+       }
+       return;
+}
+
+/*
+ * Hog the regulators needed to power up the board.
+ */
+static int __init u300_init_boardpower(void)
+{
+       int err;
+       u32 val;
+
+       pr_info("U300: setting up board power\n");
+       main_power_15 = regulator_get(NULL, "vana15");
+       if (IS_ERR(main_power_15)) {
+               pr_err("could not get vana15");
+               return PTR_ERR(main_power_15);
+       }
+       err = regulator_enable(main_power_15);
+       if (err) {
+               pr_err("could not enable vana15\n");
+               return err;
+       }
+
+       /*
+        * On U300 a special system controller register pulls up the DC
+        * until the vana15 (LDO D) regulator comes up. At this point, all
+        * regulators are set and we do not need power control via
+        * DC ON anymore. This function will likely be moved whenever
+        * the rest of the U300 power management is implemented.
+        */
+       pr_info("U300: disable system controller pull-up\n");
+       val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMCR);
+       val &= ~U300_SYSCON_PMCR_DCON_ENABLE;
+       writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMCR);
+
+       /* Register globally exported PM poweroff hook */
+       pm_power_off = u300_pm_poweroff;
+
+       return 0;
+}
+
+/*
+ * So at module init time we hog the regulator!
+ */
+module_init(u300_init_boardpower);
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
new file mode 100644 (file)
index 0000000..03625d7
--- /dev/null
@@ -0,0 +1,15 @@
+menu "ST-Ericsson platform type"
+       depends on ARCH_U8500
+
+comment "ST-Ericsson Multicore Mobile Platforms"
+
+config MACH_U8500_MOP
+       bool "U8500 Early Development platform"
+       default y
+       select ARM_GIC
+       select HAS_MTU
+       help
+         Include support for mop500 development platform
+         based on U8500 architecture. The platform is based
+         on early drop silicon version of 8500.
+endmenu
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
new file mode 100644 (file)
index 0000000..95e6e24
--- /dev/null
@@ -0,0 +1,8 @@
+#
+# Makefile for the linux kernel, U8500 machine.
+#
+
+obj-y                          := clock.o
+obj-$(CONFIG_ARCH_U8500)       += cpu-u8500.o
+obj-$(CONFIG_MACH_U8500_MOP)   += board-mop500.o
+obj-$(CONFIG_SMP)              += platsmp.o headsmp.o localtimer.o
diff --git a/arch/arm/mach-ux500/Makefile.boot b/arch/arm/mach-ux500/Makefile.boot
new file mode 100644 (file)
index 0000000..c7e75ac
--- /dev/null
@@ -0,0 +1,4 @@
+   zreladdr-y  := 0x00008000
+params_phys-y  := 0x00000100
+initrd_phys-y  := 0x00800000
+
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
new file mode 100644 (file)
index 0000000..aa5afbc
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson
+ *
+ * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/amba/bus.h>
+#include <linux/amba/pl022.h>
+#include <linux/spi/spi.h>
+
+#include <asm/localtimer.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/mtu.h>
+
+#include <mach/hardware.h>
+#include <mach/setup.h>
+
+#define __MEM_4K_RESOURCE(x) \
+       .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+
+/* These are active devices on this board */
+static struct amba_device uart0_device = {
+       .dev = { .init_name = "uart0" },
+       __MEM_4K_RESOURCE(U8500_UART0_BASE),
+       .irq = {IRQ_UART0, NO_IRQ},
+};
+
+static struct amba_device uart1_device = {
+       .dev = { .init_name = "uart1" },
+       __MEM_4K_RESOURCE(U8500_UART1_BASE),
+       .irq = {IRQ_UART1, NO_IRQ},
+};
+
+static struct amba_device uart2_device = {
+       .dev = { .init_name = "uart2" },
+       __MEM_4K_RESOURCE(U8500_UART2_BASE),
+       .irq = {IRQ_UART2, NO_IRQ},
+};
+
+static void ab4500_spi_cs_control(u32 command)
+{
+       /* set the FRM signal, which is CS  - TODO */
+}
+
+struct pl022_config_chip ab4500_chip_info = {
+       .lbm = LOOPBACK_DISABLED,
+       .com_mode = INTERRUPT_TRANSFER,
+       .iface = SSP_INTERFACE_MOTOROLA_SPI,
+       /* we can act as master only */
+       .hierarchy = SSP_MASTER,
+       .slave_tx_disable = 0,
+       .endian_rx = SSP_RX_MSB,
+       .endian_tx = SSP_TX_MSB,
+       .data_size = SSP_DATA_BITS_24,
+       .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM,
+       .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC,
+       .clk_phase = SSP_CLK_SECOND_EDGE,
+       .clk_pol = SSP_CLK_POL_IDLE_HIGH,
+       .cs_control = ab4500_spi_cs_control,
+};
+
+static struct spi_board_info u8500_spi_devices[] = {
+       {
+               .modalias = "ab4500",
+               .controller_data = &ab4500_chip_info,
+               .max_speed_hz = 12000000,
+               .bus_num = 0,
+               .chip_select = 0,
+               .mode = SPI_MODE_0,
+               .irq = IRQ_AB4500,
+       },
+};
+
+static struct pl022_ssp_controller ssp0_platform_data = {
+       .bus_id = 0,
+       /* pl022 not yet supports dma */
+       .enable_dma = 0,
+       /* on this platform, gpio 31,142,144,214 &
+        * 224 are connected as chip selects
+        */
+       .num_chipselect = 5,
+};
+
+static struct amba_device pl022_device = {
+       .dev = {
+               .coherent_dma_mask = ~0,
+               .init_name = "pl022",
+               .platform_data = &ssp0_platform_data,
+       },
+       .res = {
+               .start = U8500_SSP0_BASE,
+               .end   = U8500_SSP0_BASE + SZ_4K - 1,
+               .flags = IORESOURCE_MEM,
+       },
+       .irq = {IRQ_SSP0, NO_IRQ },
+       /* ST-Ericsson modified id */
+       .periphid = SSP_PER_ID,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+       &uart0_device,
+       &uart1_device,
+       &uart2_device,
+       &pl022_device,
+};
+
+static void __init u8500_timer_init(void)
+{
+#ifdef CONFIG_LOCAL_TIMERS
+       /* Setup the local timer base */
+       twd_base = __io_address(U8500_TWD_BASE);
+#endif
+       /* Setup the MTU base */
+       mtu_base = __io_address(U8500_MTU0_BASE);
+
+       nmdk_timer_init();
+}
+
+static struct sys_timer u8500_timer = {
+       .init   = u8500_timer_init,
+};
+
+static void __init u8500_init_machine(void)
+{
+       int i;
+
+       /* Register the active AMBA devices on this board */
+       for (i = 0; i < ARRAY_SIZE(amba_devs); i++)
+               amba_device_register(amba_devs[i], &iomem_resource);
+
+       spi_register_board_info(u8500_spi_devices,
+                       ARRAY_SIZE(u8500_spi_devices));
+
+       u8500_init_devices();
+}
+
+MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
+       /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */
+       .phys_io        = U8500_UART2_BASE,
+       .io_pg_offst    = (IO_ADDRESS(U8500_UART2_BASE) >> 18) & 0xfffc,
+       .boot_params    = 0x100,
+       .map_io         = u8500_map_io,
+       .init_irq       = u8500_init_irq,
+       /* we re-use nomadik timer here */
+       .timer          = &u8500_timer,
+       .init_machine   = u8500_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
new file mode 100644 (file)
index 0000000..20b6ebb
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ *  Copyright (C) 2009 ST-Ericsson
+ *     heavily based on realview platform
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+
+#include <asm/clkdev.h>
+
+/* currently the clk structure
+ * just supports rate. This would
+ * be extended as and when new devices are
+ * added - TODO
+ */
+struct clk {
+       unsigned long           rate;
+};
+
+int clk_enable(struct clk *clk)
+{
+       return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+       return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       /*TODO*/
+       return rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       clk->rate = rate;
+       return 0;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/* ssp clock */
+static struct clk ssp_clk = {
+       .rate = 48000000,
+};
+
+/* fixed clock */
+static struct clk f38_clk = {
+       .rate = 38400000,
+};
+
+static struct clk_lookup lookups[] = {
+       {
+               /* UART0 */
+               .dev_id         = "uart0",
+               .clk            = &f38_clk,
+       }, {    /* UART1 */
+               .dev_id         = "uart1",
+               .clk            = &f38_clk,
+       }, {    /* UART2 */
+               .dev_id         = "uart2",
+               .clk            = &f38_clk,
+       }, {    /* SSP */
+               .dev_id         = "pl022",
+               .clk            = &ssp_clk,
+       }
+};
+
+static int __init clk_init(void)
+{
+       int i;
+
+       /* register the clock lookups */
+       for (i = 0; i < ARRAY_SIZE(lookups); i++)
+               clkdev_add(&lookups[i]);
+       return 0;
+}
+arch_initcall(clk_init);
diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c
new file mode 100644 (file)
index 0000000..5f05e58
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson
+ *
+ * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/amba/bus.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware/gic.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+
+/* add any platform devices here - TODO */
+static struct platform_device *platform_devs[] __initdata = {
+       /* yet to be added, add i2c0, gpio.. */
+};
+
+#define __IO_DEV_DESC(x, sz)   {               \
+       .virtual        = IO_ADDRESS(x),        \
+       .pfn            = __phys_to_pfn(x),     \
+       .length         = sz,                   \
+       .type           = MT_DEVICE,            \
+}
+
+/* minimum static i/o mapping required to boot U8500 platforms */
+static struct map_desc u8500_io_desc[] __initdata = {
+       __IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K),
+       __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K),
+       __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K),
+       __IO_DEV_DESC(U8500_TWD_BASE, SZ_4K),
+       __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K),
+       __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K),
+};
+
+void __init u8500_map_io(void)
+{
+       iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc));
+}
+
+void __init u8500_init_irq(void)
+{
+       gic_dist_init(0, __io_address(U8500_GIC_DIST_BASE), 29);
+       gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE));
+}
+
+/*
+ * This function is called from the board init
+ */
+void __init u8500_init_devices(void)
+{
+       /* Register the platform devices */
+       platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
+
+       return ;
+}
diff --git a/arch/arm/mach-ux500/headsmp.S b/arch/arm/mach-ux500/headsmp.S
new file mode 100644 (file)
index 0000000..a6be2cd
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (c) 2009 ST-Ericsson
+ *     This file is based  ARM Realview platform
+ *  Copyright (c) 2003 ARM Limited
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+       __INIT
+
+/*
+ * U8500 specific entry point for secondary CPUs.
+ */
+ENTRY(u8500_secondary_startup)
+       mrc     p15, 0, r0, c0, c0, 5
+       and     r0, r0, #15
+       adr     r4, 1f
+       ldmia   r4, {r5, r6}
+       sub     r4, r4, r5
+       add     r6, r6, r4
+       dsb
+pen:   ldr     r7, [r6]
+       cmp     r7, r0
+       bne     pen
+
+       /*
+        * we've been released from the holding pen: secondary_stack
+        * should now contain the SVC stack for this core
+        */
+       b       secondary_startup
+
+1:     .long   .
+       .long   pen_release
diff --git a/arch/arm/mach-ux500/include/mach/clkdev.h b/arch/arm/mach-ux500/include/mach/clkdev.h
new file mode 100644 (file)
index 0000000..04b37a8
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/debug-macro.S b/arch/arm/mach-ux500/include/mach/debug-macro.S
new file mode 100644 (file)
index 0000000..8f21b6a
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Debugging macro include header
+ *
+ *  Copyright (C) 2009 ST-Ericsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+       .macro  addruart,rx
+       mrc     p15, 0, \rx, c1, c0
+       tst     \rx, #1                 @MMU enabled?
+       moveq   \rx, #0x80000000        @MMU off, Physical address
+       movne   \rx, #0xF0000000        @MMU on, Virtual address
+       orr     \rx, \rx, #0x7000
+       .endm
+
+#include <asm/hardware/debug-pl01x.S>
diff --git a/arch/arm/mach-ux500/include/mach/entry-macro.S b/arch/arm/mach-ux500/include/mach/entry-macro.S
new file mode 100644 (file)
index 0000000..eece330
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Low-level IRQ helper macros for U8500 platforms
+ *
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * This file is a copy of ARM Realview platform.
+ *     -just satisfied checkpatch script.
+ *
+ * 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 <mach/hardware.h>
+#include <asm/hardware/gic.h>
+
+               .macro  disable_fiq
+               .endm
+
+               .macro  get_irqnr_preamble, base, tmp
+               ldr     \base, =IO_ADDRESS(U8500_GIC_CPU_BASE)
+               .endm
+
+               .macro  arch_ret_to_user, tmp1, tmp2
+               .endm
+
+               /*
+                * The interrupt numbering scheme is defined in the
+                * interrupt controller spec.  To wit:
+                *
+                * Interrupts 0-15 are IPI
+                * 16-28 are reserved
+                * 29-31 are local.  We allow 30 to be used for the watchdog.
+                * 32-1020 are global
+                * 1021-1022 are reserved
+                * 1023 is "spurious" (no interrupt)
+                *
+                * For now, we ignore all local interrupts so only return an
+                * interrupt if it's between 30 and 1020. The test_for_ipi
+                * routine below will pick up on IPIs.
+                *
+                * A simple read from the controller will tell us the number
+                * of the highest priority enabled interrupt. We then just
+                * need to check whether it is in the valid range for an
+                * IRQ (30-1020 inclusive).
+                */
+
+               .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+               /* bits 12-10 = src CPU, 9-0 = int # */
+               ldr     \irqstat, [\base, #GIC_CPU_INTACK]
+
+               ldr     \tmp, =1021
+
+               bic     \irqnr, \irqstat, #0x1c00
+
+               cmp     \irqnr, #29
+               cmpcc   \irqnr, \irqnr
+               cmpne   \irqnr, \tmp
+               cmpcs   \irqnr, \irqnr
+
+               .endm
+
+               /* We assume that irqstat (the raw value of the IRQ
+                * acknowledge register) is preserved from the macro above.
+                * If there is an IPI, we immediately signal end of
+                * interrupt on the controller, since this requires the
+                * original irqstat value which we won't easily be able
+                * to recreate later.
+                */
+
+               .macro test_for_ipi, irqnr, irqstat, base, tmp
+               bic     \irqnr, \irqstat, #0x1c00
+               cmp     \irqnr, #16
+               strcc   \irqstat, [\base, #GIC_CPU_EOI]
+               cmpcs   \irqnr, \irqnr
+               .endm
+
+               /* As above, this assumes that irqstat and base
+                * are preserved..
+                */
+
+               .macro test_for_ltirq, irqnr, irqstat, base, tmp
+               bic     \irqnr, \irqstat, #0x1c00
+               mov     \tmp, #0
+               cmp     \irqnr, #29
+               moveq   \tmp, #1
+               streq   \irqstat, [\base, #GIC_CPU_EOI]
+               cmp     \tmp, #0
+               .endm
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h
new file mode 100644 (file)
index 0000000..6da6502
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * U8500 hardware definitions
+ *
+ * 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 __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+/* macros to get at IO space when running virtually
+ * We dont map all the peripherals, let ioremap do
+ * this for us. We map only very basic peripherals here.
+ */
+#define U8500_IO_VIRTUAL       0xf0000000
+#define U8500_IO_PHYSICAL      0xa0000000
+
+/* this macro is used in assembly, so no cast */
+#define IO_ADDRESS(x)           \
+       (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + U8500_IO_VIRTUAL)
+
+/* typesafe io address */
+#define __io_address(n)                __io(IO_ADDRESS(n))
+
+/*
+ * Base address definitions for U8500 Onchip IPs. All the
+ * peripherals are contained in a single 1 Mbyte region, with
+ * AHB peripherals at the bottom and APB peripherals at the
+ * top of the region. PER stands for PERIPHERAL region which
+ * itself divided into sub regions.
+ */
+#define U8500_PER3_BASE                0x80000000
+#define U8500_PER2_BASE                0x80110000
+#define U8500_PER1_BASE                0x80120000
+#define U8500_PER4_BASE                0x80150000
+
+#define U8500_PER6_BASE                0xa03c0000
+#define U8500_PER5_BASE                0xa03e0000
+#define U8500_PER7_BASE                0xa03d0000
+
+#define U8500_SVA_BASE         0xa0100000
+#define U8500_SIA_BASE         0xa0200000
+
+#define U8500_SGA_BASE         0xa0300000
+#define U8500_MCDE_BASE                0xa0350000
+#define U8500_DMA_BASE         0xa0362000
+
+#define U8500_SCU_BASE         0xa0410000
+#define U8500_GIC_CPU_BASE     0xa0410100
+#define U8500_TWD_BASE         0xa0410600
+#define U8500_GIC_DIST_BASE    0xa0411000
+#define U8500_L2CC_BASE                0xa0412000
+
+#define U8500_TWD_SIZE         0x100
+
+/* per7 base addressess */
+#define U8500_CR_BASE          (U8500_PER7_BASE + 0x8000)
+#define U8500_MTU0_BASE                (U8500_PER7_BASE + 0xa000)
+#define U8500_MTU1_BASE                (U8500_PER7_BASE + 0xb000)
+#define U8500_TZPC0_BASE       (U8500_PER7_BASE + 0xc000)
+#define U8500_CLKRST7_BASE     (U8500_PER7_BASE + 0xf000)
+
+/* per6 base addressess */
+#define U8500_RNG_BASE         (U8500_PER6_BASE + 0x0000)
+#define U8500_PKA_BASE         (U8500_PER6_BASE + 0x1000)
+#define U8500_PKAM_BASE                (U8500_PER6_BASE + 0x2000)
+#define U8500_CRYPTO0_BASE     (U8500_PER6_BASE + 0xa000)
+#define U8500_CRYPTO1_BASE     (U8500_PER6_BASE + 0xb000)
+#define U8500_CLKRST6_BASE     (U8500_PER7_BASE + 0xf000)
+
+/* per5 base addressess */
+#define U8500_USBOTG_BASE      (U8500_PER5_BASE + 0x00000)
+#define U8500_GPIO5_BASE       (U8500_PER5_BASE + 0x1e000)
+#define U8500_CLKRST5_BASE     (U8500_PER7_BASE + 0x1f000)
+
+/* per4 base addressess */
+#define U8500_BACKUPRAM0_BASE  (U8500_PER4_BASE + 0x0000)
+#define U8500_BACKUPRAM1_BASE  (U8500_PER4_BASE + 0x1000)
+#define U8500_RTT0_BASE                (U8500_PER4_BASE + 0x2000)
+#define U8500_RTT1_BASE                (U8500_PER4_BASE + 0x3000)
+#define U8500_RTC_BASE         (U8500_PER4_BASE + 0x4000)
+#define U8500_SCR_BASE         (U8500_PER4_BASE + 0x5000)
+#define U8500_DMC_BASE         (U8500_PER4_BASE + 0x6000)
+#define U8500_PRCMU_BASE       (U8500_PER4_BASE + 0x7000)
+
+/* per3 base addressess */
+#define U8500_FSMC_BASE                (U8500_PER3_BASE + 0x0000)
+#define U8500_SSP0_BASE                (U8500_PER3_BASE + 0x2000)
+#define U8500_SSP1_BASE                (U8500_PER3_BASE + 0x3000)
+#define U8500_I2C0_BASE                (U8500_PER3_BASE + 0x4000)
+#define U8500_SDI2_BASE                (U8500_PER3_BASE + 0x5000)
+#define U8500_SKE_BASE         (U8500_PER3_BASE + 0x6000)
+#define U8500_UART2_BASE       (U8500_PER3_BASE + 0x7000)
+#define U8500_SDI5_BASE                (U8500_PER3_BASE + 0x8000)
+#define U8500_GPIO3_BASE       (U8500_PER3_BASE + 0xe000)
+#define U8500_CLKRST3_BASE     (U8500_PER7_BASE + 0xf000)
+
+/* per2 base addressess */
+#define U8500_I2C3_BASE                (U8500_PER2_BASE + 0x0000)
+#define U8500_SPI2_BASE                (U8500_PER2_BASE + 0x1000)
+#define U8500_SPI1_BASE                (U8500_PER2_BASE + 0x2000)
+#define U8500_PWL_BASE         (U8500_PER2_BASE + 0x3000)
+#define U8500_SDI4_BASE                (U8500_PER2_BASE + 0x4000)
+#define U8500_MSP2_BASE                (U8500_PER2_BASE + 0x7000)
+#define U8500_SDI1_BASE                (U8500_PER2_BASE + 0x8000)
+#define U8500_SDI3_BASE                (U8500_PER2_BASE + 0x9000)
+#define U8500_SPI0_BASE                (U8500_PER2_BASE + 0xa000)
+#define U8500_HSIR_BASE                (U8500_PER2_BASE + 0xb000)
+#define U8500_HSIT_BASE                (U8500_PER2_BASE + 0xc000)
+#define U8500_GPIO2_BASE       (U8500_PER2_BASE + 0xe000)
+#define U8500_CLKRST2_BASE     (U8500_PER2_BASE + 0xf000)
+
+/* per1 base addresses */
+#define U8500_UART0_BASE       (U8500_PER1_BASE + 0x0000)
+#define U8500_UART1_BASE       (U8500_PER1_BASE + 0x1000)
+#define U8500_I2C1_BASE                (U8500_PER1_BASE + 0x2000)
+#define U8500_MSP0_BASE                (U8500_PER1_BASE + 0x3000)
+#define U8500_MSP1_BASE                (U8500_PER1_BASE + 0x4000)
+#define U8500_SDI0_BASE                (U8500_PER1_BASE + 0x6000)
+#define U8500_I2C2_BASE                (U8500_PER1_BASE + 0x8000)
+#define U8500_SPI3_BASE                (U8500_PER1_BASE + 0x9000)
+#define U8500_SLIM0_BASE       (U8500_PER1_BASE + 0xa000)
+#define U8500_GPIO1_BASE       (U8500_PER1_BASE + 0xe000)
+#define U8500_CLKRST1_BASE     (U8500_PER2_BASE + 0xf000)
+
+/* ST-Ericsson modified pl022 id */
+#define SSP_PER_ID             0x01080022
+
+#endif                         /* __MACH_HARDWARE_H */
diff --git a/arch/arm/mach-ux500/include/mach/io.h b/arch/arm/mach-ux500/include/mach/io.h
new file mode 100644 (file)
index 0000000..1cf3f44
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-u8500/include/mach/io.h
+ *
+ * Copyright (C) 1997-1999 Russell King
+ *
+ * Modifications:
+ *  06-12-1997 RMK     Created.
+ *  07-04-1999 RMK     Major cleanup
+ */
+#ifndef __ASM_ARM_ARCH_IO_H
+#define __ASM_ARM_ARCH_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/*
+ * We don't actually have real ISA nor PCI buses, but there is so many
+ * drivers out there that might just work if we fake them...
+ */
+#define __io(a)                __typesafe_io(a)
+#define __mem_pci(a)   (a)
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h
new file mode 100644 (file)
index 0000000..394b5dd
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  Copyright (C) 2008 STMicroelectronics
+ *  Copyright (C) 2009 ST-Ericsson.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef ASM_ARCH_IRQS_H
+#define ASM_ARCH_IRQS_H
+
+#include <mach/hardware.h>
+
+#define IRQ_LOCALTIMER                  29
+#define IRQ_LOCALWDOG                   30
+
+/* Shared Peripheral Interrupt (SHPI) */
+#define IRQ_SHPI_START                 32
+
+/* Interrupt numbers generic for shared peripheral */
+#define IRQ_MTU0               (IRQ_SHPI_START + 4)
+#define IRQ_SPI2               (IRQ_SHPI_START + 6)
+#define IRQ_SPI0               (IRQ_SHPI_START + 8)
+#define IRQ_UART0              (IRQ_SHPI_START + 11)
+#define IRQ_I2C3               (IRQ_SHPI_START + 12)
+#define IRQ_SSP0               (IRQ_SHPI_START + 14)
+#define IRQ_MTU1               (IRQ_SHPI_START + 17)
+#define IRQ_RTC_RTT            (IRQ_SHPI_START + 18)
+#define IRQ_UART1              (IRQ_SHPI_START + 19)
+#define IRQ_I2C0               (IRQ_SHPI_START + 21)
+#define IRQ_I2C1               (IRQ_SHPI_START + 22)
+#define IRQ_USBOTG             (IRQ_SHPI_START + 23)
+#define IRQ_DMA                        (IRQ_SHPI_START + 25)
+#define IRQ_UART2              (IRQ_SHPI_START + 26)
+#define IRQ_HSIR_EXCEP         (IRQ_SHPI_START + 29)
+#define IRQ_MSP0               (IRQ_SHPI_START + 31)
+#define IRQ_HSIR_CH0_OVRRUN    (IRQ_SHPI_START + 32)
+#define IRQ_HSIR_CH1_OVRRUN    (IRQ_SHPI_START + 33)
+#define IRQ_HSIR_CH2_OVRRUN    (IRQ_SHPI_START + 34)
+#define IRQ_HSIR_CH3_OVRRUN    (IRQ_SHPI_START + 35)
+#define IRQ_AB4500             (IRQ_SHPI_START + 40)
+#define IRQ_DISP               (IRQ_SHPI_START + 48)
+#define IRQ_SiPI3              (IRQ_SHPI_START + 49)
+#define IRQ_SSP1               (IRQ_SHPI_START + 52)
+#define IRQ_I2C2               (IRQ_SHPI_START + 55)
+#define IRQ_SDMMC0             (IRQ_SHPI_START + 60)
+#define IRQ_MSP1               (IRQ_SHPI_START + 62)
+#define IRQ_SPI1               (IRQ_SHPI_START + 96)
+#define IRQ_MSP2               (IRQ_SHPI_START + 98)
+#define IRQ_SDMMC4             (IRQ_SHPI_START + 99)
+#define IRQ_HSIRD0             (IRQ_SHPI_START + 104)
+#define IRQ_HSIRD1             (IRQ_SHPI_START + 105)
+#define IRQ_HSITD0             (IRQ_SHPI_START + 106)
+#define IRQ_HSITD1             (IRQ_SHPI_START + 107)
+#define IRQ_GPIO0              (IRQ_SHPI_START + 119)
+#define IRQ_GPIO1              (IRQ_SHPI_START + 120)
+#define IRQ_GPIO2              (IRQ_SHPI_START + 121)
+#define IRQ_GPIO3              (IRQ_SHPI_START + 122)
+#define IRQ_GPIO4              (IRQ_SHPI_START + 123)
+#define IRQ_GPIO5              (IRQ_SHPI_START + 124)
+#define IRQ_GPIO6              (IRQ_SHPI_START + 125)
+#define IRQ_GPIO7              (IRQ_SHPI_START + 126)
+#define IRQ_GPIO8              (IRQ_SHPI_START + 127)
+
+/* There are 128 shared peripheral interrupts assigned to
+ * INTID[160:32]. The first 32 interrupts are reserved.
+ */
+#define NR_IRQS                        161
+
+#endif /*ASM_ARCH_IRQS_H*/
diff --git a/arch/arm/mach-ux500/include/mach/memory.h b/arch/arm/mach-ux500/include/mach/memory.h
new file mode 100644 (file)
index 0000000..510571a
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Physical DRAM offset.
+ */
+#define PHYS_OFFSET    UL(0x00000000)
+#define BUS_OFFSET     UL(0x00000000)
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
new file mode 100644 (file)
index 0000000..cf0ce16
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * These symbols are needed for board-specific files to call their
+ * own cpu-specific files
+ */
+#ifndef __ASM_ARCH_SETUP_H
+#define __ASM_ARCH_SETUP_H
+
+#include <asm/mach/time.h>
+#include <linux/init.h>
+
+extern void u8500_map_io(void);
+extern void u8500_init_devices(void);
+extern void u8500_init_irq(void);
+/* We re-use nomadik_timer for this platform */
+extern void nmdk_timer_init(void);
+
+#endif /*  __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h
new file mode 100644 (file)
index 0000000..b59f7bc
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * This file is based ARM realview platform.
+ * Copyright (C) ARM Limited.
+ *
+ * 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 ASMARM_ARCH_SMP_H
+#define ASMARM_ARCH_SMP_H
+
+#include <asm/hardware/gic.h>
+
+/* This is required to wakeup the secondary core */
+extern void u8500_secondary_startup(void);
+
+#define hard_smp_processor_id()                                \
+       ({                                              \
+               unsigned int cpunum;                    \
+               __asm__("mrc p15, 0, %0, c0, c0, 5"     \
+                       : "=r" (cpunum));               \
+               cpunum &= 0x0F;                         \
+       })
+
+/*
+ * We use IRQ1 as the IPI
+ */
+static inline void smp_cross_call(const struct cpumask *mask)
+{
+       gic_raise_softirq(mask, 1);
+}
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/system.h b/arch/arm/mach-ux500/include/mach/system.h
new file mode 100644 (file)
index 0000000..c0cd800
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson.
+ *
+ * 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 __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+static inline void arch_idle(void)
+{
+       /*
+        * This should do all the clock switching
+        * and wait for interrupt tricks
+        */
+       cpu_do_idle();
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+       /* yet to be implemented - TODO */
+}
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/timex.h b/arch/arm/mach-ux500/include/mach/timex.h
new file mode 100644 (file)
index 0000000..d0942c1
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __ASM_ARCH_TIMEX_H
+#define __ASM_ARCH_TIMEX_H
+
+#define CLOCK_TICK_RATE                110000000
+
+#endif
diff --git a/arch/arm/mach-ux500/include/mach/uncompress.h b/arch/arm/mach-ux500/include/mach/uncompress.h
new file mode 100644 (file)
index 0000000..8552eb1
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  Copyright (C) 2009 ST-Ericsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef __ASM_ARCH_UNCOMPRESS_H
+#define __ASM_ARCH_UNCOMPRESS_H
+
+#include <asm/setup.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+
+#define U8500_UART_DR          0x80007000
+#define U8500_UART_LCRH                0x8000702c
+#define U8500_UART_CR          0x80007030
+#define U8500_UART_FR          0x80007018
+
+static void putc(const char c)
+{
+       /* Do nothing if the UART is not enabled. */
+       if (!(readb(U8500_UART_CR) & 0x1))
+               return;
+
+       if (c == '\n')
+               putc('\r');
+
+       while (readb(U8500_UART_FR) & (1 << 5))
+               barrier();
+       writeb(c, U8500_UART_DR);
+}
+
+static void flush(void)
+{
+       if (!(readb(U8500_UART_CR) & 0x1))
+               return;
+       while (readb(U8500_UART_FR) & (1 << 3))
+               barrier();
+}
+
+static inline void arch_decomp_setup(void)
+{
+}
+
+#define arch_decomp_wdog() /* nothing to do here */
+
+#endif /* __ASM_ARCH_UNCOMPRESS_H */
diff --git a/arch/arm/mach-ux500/include/mach/vmalloc.h b/arch/arm/mach-ux500/include/mach/vmalloc.h
new file mode 100644 (file)
index 0000000..86cdbbc
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ *  Copyright (C) 2009 ST-Ericsson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#define VMALLOC_END    0xf0000000
diff --git a/arch/arm/mach-ux500/localtimer.c b/arch/arm/mach-ux500/localtimer.c
new file mode 100644 (file)
index 0000000..2288f6a
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008-2009 ST-Ericsson
+ * Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+ *
+ * This file is heavily based on relaview platform, almost a copy.
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/clockchips.h>
+
+#include <asm/irq.h>
+#include <asm/smp_twd.h>
+#include <asm/localtimer.h>
+
+/*
+ * Setup the local clock events for a CPU.
+ */
+void __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+       evt->irq = IRQ_LOCALTIMER;
+       twd_timer_setup(evt);
+}
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
new file mode 100644 (file)
index 0000000..8dfe7ca
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2002 ARM Ltd.
+ * Copyright (C) 2008 STMicroelctronics.
+ * Copyright (C) 2009 ST-Ericsson.
+ * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+ *
+ * This file is based on arm realview platform
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/localtimer.h>
+#include <asm/smp_scu.h>
+#include <mach/hardware.h>
+
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+volatile int __cpuinitdata pen_release = -1;
+
+static unsigned int __init get_core_count(void)
+{
+       return scu_get_core_count(__io_address(U8500_SCU_BASE));
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+       trace_hardirqs_off();
+
+       /*
+        * if any interrupts are already enabled for the primary
+        * core (e.g. timer irq), then they will not have been enabled
+        * for us: do so
+        */
+       gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE));
+
+       /*
+        * let the primary processor know we're out of the
+        * pen, then head off into the C entry point
+        */
+       pen_release = -1;
+
+       /*
+        * Synchronise with the boot thread.
+        */
+       spin_lock(&boot_lock);
+       spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       unsigned long timeout;
+
+       /*
+        * set synchronisation state between this boot processor
+        * and the secondary one
+        */
+       spin_lock(&boot_lock);
+
+       /*
+        * The secondary processor is waiting to be released from
+        * the holding pen - release it, then wait for it to flag
+        * that it has been released by resetting pen_release.
+        */
+       pen_release = cpu;
+       flush_cache_all();
+
+       timeout = jiffies + (1 * HZ);
+       while (time_before(jiffies, timeout)) {
+               if (pen_release == -1)
+                       break;
+       }
+
+       /*
+        * now the secondary core is starting up let it run its
+        * calibrations, then wait for it to finish
+        */
+       spin_unlock(&boot_lock);
+
+       return pen_release != -1 ? -ENOSYS : 0;
+}
+
+static void __init wakeup_secondary(void)
+{
+       /* nobody is to be released from the pen yet */
+       pen_release = -1;
+
+       /*
+        * write the address of secondary startup into the backup ram register
+        * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the
+        * backup ram register at offset 0x1FF0, which is what boot rom code
+        * is waiting for. This would wake up the secondary core from WFE
+        */
+#define U8500_CPU1_JUMPADDR_OFFSET 0x1FF4
+       __raw_writel(virt_to_phys(u8500_secondary_startup),
+               (void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) +
+               U8500_CPU1_JUMPADDR_OFFSET);
+
+#define U8500_CPU1_WAKEMAGIC_OFFSET 0x1FF0
+       __raw_writel(0xA1FEED01,
+               (void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) +
+               U8500_CPU1_WAKEMAGIC_OFFSET);
+
+       /* make sure write buffer is drained */
+       mb();
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+       unsigned int i, ncores = get_core_count();
+
+       for (i = 0; i < ncores; i++)
+               set_cpu_possible(i, true);
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+       unsigned int ncores = get_core_count();
+       unsigned int cpu = smp_processor_id();
+       int i;
+
+       /* sanity check */
+       if (ncores == 0) {
+               printk(KERN_ERR
+                      "U8500: strange CM count of 0? Default to 1\n");
+               ncores = 1;
+       }
+
+       if (ncores > num_possible_cpus())       {
+               printk(KERN_WARNING
+                      "U8500: no. of cores (%d) greater than configured "
+                      "maximum of %d - clipping\n",
+                      ncores, num_possible_cpus());
+               ncores = num_possible_cpus();
+       }
+
+       smp_store_cpu_info(cpu);
+
+       /*
+        * are we trying to boot more cores than exist?
+        */
+       if (max_cpus > ncores)
+               max_cpus = ncores;
+
+       /*
+        * Initialise the present map, which describes the set of CPUs
+        * actually populated at the present time.
+        */
+       for (i = 0; i < max_cpus; i++)
+               set_cpu_present(i, true);
+
+       if (max_cpus > 1) {
+               /*
+                * Enable the local timer or broadcast device for the
+                * boot CPU, but only if we have more than one CPU.
+                */
+               percpu_timer_setup();
+               scu_enable(__io_address(U8500_SCU_BASE));
+               wakeup_secondary();
+       }
+}
index 2a6f98d..51f17b7 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/mach-types.h>
 
 #include <mach/regs-serial.h>
+#include <mach/nuc900_spi.h>
 #include <mach/map.h>
 
 #include "cpu.h"
@@ -196,6 +197,18 @@ static struct platform_device nuc900_device_emc = {
 
 /* SPI device */
 
+static struct w90p910_spi_info nuc900_spiflash_data = {
+       .num_cs         = 1,
+       .lsb            = 0,
+       .txneg          = 1,
+       .rxneg          = 0,
+       .divider        = 24,
+       .sleep          = 0,
+       .txnum          = 0,
+       .txbitlen       = 1,
+       .bus_num        = 0,
+};
+
 static struct resource nuc900_spi_resource[] = {
        [0] = {
                .start = W90X900_PA_I2C + SPIOFFSET,
@@ -214,6 +227,9 @@ static struct platform_device nuc900_device_spi = {
        .id             = -1,
        .num_resources  = ARRAY_SIZE(nuc900_spi_resource),
        .resource       = nuc900_spi_resource,
+       .dev            = {
+                               .platform_data = &nuc900_spiflash_data,
+                       }
 };
 
 /* spi device, spi flash info */
index 9264d81..7b7d4c3 100644 (file)
@@ -774,5 +774,5 @@ config CACHE_XSC3L2
 
 config ARM_L1_CACHE_SHIFT
        int
-       default 6 if ARCH_OMAP3
+       default 6 if ARCH_OMAP3 || ARCH_S5PC1XX
        default 5
index 055cb2a..42352e7 100644 (file)
@@ -6,7 +6,7 @@ obj-y                           := dma-mapping.o extable.o fault.o init.o \
                                   iomap.o
 
 obj-$(CONFIG_MMU)              += fault-armv.o flush.o ioremap.o mmap.o \
-                                  pgd.o mmu.o
+                                  pgd.o mmu.o vmregion.o
 
 ifneq ($(CONFIG_MMU),y)
 obj-y                          += nommu.o
index b480f1d..747f9a9 100644 (file)
@@ -99,18 +99,25 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
 
        l2x0_base = base;
 
-       /* disable L2X0 */
-       writel(0, l2x0_base + L2X0_CTRL);
+       /*
+        * Check if l2x0 controller is already enabled.
+        * If you are booting from non-secure mode
+        * accessing the below registers will fault.
+        */
+       if (!(readl(l2x0_base + L2X0_CTRL) & 1)) {
 
-       aux = readl(l2x0_base + L2X0_AUX_CTRL);
-       aux &= aux_mask;
-       aux |= aux_val;
-       writel(aux, l2x0_base + L2X0_AUX_CTRL);
+               /* l2x0 controller is disabled */
 
-       l2x0_inv_all();
+               aux = readl(l2x0_base + L2X0_AUX_CTRL);
+               aux &= aux_mask;
+               aux |= aux_val;
+               writel(aux, l2x0_base + L2X0_AUX_CTRL);
 
-       /* enable L2X0 */
-       writel(1, l2x0_base + L2X0_CTRL);
+               l2x0_inv_all();
+
+               /* enable L2X0 */
+               writel(1, l2x0_base + L2X0_CTRL);
+       }
 
        outer_cache.inv_range = l2x0_inv_range;
        outer_cache.clean_range = l2x0_clean_range;
index 4127a7b..841f355 100644 (file)
@@ -41,6 +41,14 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to,
        kfrom = kmap_atomic(from, KM_USER0);
        kto = kmap_atomic(to, KM_USER1);
        copy_page(kto, kfrom);
+#ifdef CONFIG_HIGHMEM
+       /*
+        * kmap_atomic() doesn't set the page virtual address, and
+        * kunmap_atomic() takes care of cache flushing already.
+        */
+       if (page_address(to) != NULL)
+#endif
+               __cpuc_flush_dcache_page(kto);
        kunmap_atomic(kto, KM_USER1);
        kunmap_atomic(kfrom, KM_USER0);
 }
index b9590a7..26325cb 100644 (file)
@@ -63,194 +63,152 @@ static u64 get_coherent_dma_mask(struct device *dev)
        return mask;
 }
 
-#ifdef CONFIG_MMU
 /*
- * These are the page tables (2MB each) covering uncached, DMA consistent allocations
+ * Allocate a DMA buffer for 'dev' of size 'size' using the
+ * specified gfp mask.  Note that 'size' must be page aligned.
  */
-static pte_t *consistent_pte[NUM_CONSISTENT_PTES];
-static DEFINE_SPINLOCK(consistent_lock);
+static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gfp)
+{
+       unsigned long order = get_order(size);
+       struct page *page, *p, *e;
+       void *ptr;
+       u64 mask = get_coherent_dma_mask(dev);
 
-/*
- * VM region handling support.
- *
- * This should become something generic, handling VM region allocations for
- * vmalloc and similar (ioremap, module space, etc).
- *
- * I envisage vmalloc()'s supporting vm_struct becoming:
- *
- *  struct vm_struct {
- *    struct vm_region region;
- *    unsigned long    flags;
- *    struct page      **pages;
- *    unsigned int     nr_pages;
- *    unsigned long    phys_addr;
- *  };
- *
- * get_vm_area() would then call vm_region_alloc with an appropriate
- * struct vm_region head (eg):
- *
- *  struct vm_region vmalloc_head = {
- *     .vm_list        = LIST_HEAD_INIT(vmalloc_head.vm_list),
- *     .vm_start       = VMALLOC_START,
- *     .vm_end         = VMALLOC_END,
- *  };
- *
- * However, vmalloc_head.vm_start is variable (typically, it is dependent on
- * the amount of RAM found at boot time.)  I would imagine that get_vm_area()
- * would have to initialise this each time prior to calling vm_region_alloc().
- */
-struct arm_vm_region {
-       struct list_head        vm_list;
-       unsigned long           vm_start;
-       unsigned long           vm_end;
-       struct page             *vm_pages;
-       int                     vm_active;
-};
+#ifdef CONFIG_DMA_API_DEBUG
+       u64 limit = (mask + 1) & ~mask;
+       if (limit && size >= limit) {
+               dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n",
+                       size, mask);
+               return NULL;
+       }
+#endif
 
-static struct arm_vm_region consistent_head = {
-       .vm_list        = LIST_HEAD_INIT(consistent_head.vm_list),
-       .vm_start       = CONSISTENT_BASE,
-       .vm_end         = CONSISTENT_END,
-};
+       if (!mask)
+               return NULL;
 
-static struct arm_vm_region *
-arm_vm_region_alloc(struct arm_vm_region *head, size_t size, gfp_t gfp)
-{
-       unsigned long addr = head->vm_start, end = head->vm_end - size;
-       unsigned long flags;
-       struct arm_vm_region *c, *new;
-
-       new = kmalloc(sizeof(struct arm_vm_region), gfp);
-       if (!new)
-               goto out;
-
-       spin_lock_irqsave(&consistent_lock, flags);
-
-       list_for_each_entry(c, &head->vm_list, vm_list) {
-               if ((addr + size) < addr)
-                       goto nospc;
-               if ((addr + size) <= c->vm_start)
-                       goto found;
-               addr = c->vm_end;
-               if (addr > end)
-                       goto nospc;
-       }
+       if (mask < 0xffffffffULL)
+               gfp |= GFP_DMA;
+
+       page = alloc_pages(gfp, order);
+       if (!page)
+               return NULL;
 
- found:
        /*
-        * Insert this entry _before_ the one we found.
+        * Now split the huge page and free the excess pages
         */
-       list_add_tail(&new->vm_list, &c->vm_list);
-       new->vm_start = addr;
-       new->vm_end = addr + size;
-       new->vm_active = 1;
-
-       spin_unlock_irqrestore(&consistent_lock, flags);
-       return new;
-
- nospc:
-       spin_unlock_irqrestore(&consistent_lock, flags);
-       kfree(new);
- out:
-       return NULL;
+       split_page(page, order);
+       for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++)
+               __free_page(p);
+
+       /*
+        * Ensure that the allocated pages are zeroed, and that any data
+        * lurking in the kernel direct-mapped region is invalidated.
+        */
+       ptr = page_address(page);
+       memset(ptr, 0, size);
+       dmac_flush_range(ptr, ptr + size);
+       outer_flush_range(__pa(ptr), __pa(ptr) + size);
+
+       return page;
 }
 
-static struct arm_vm_region *arm_vm_region_find(struct arm_vm_region *head, unsigned long addr)
+/*
+ * Free a DMA buffer.  'size' must be page aligned.
+ */
+static void __dma_free_buffer(struct page *page, size_t size)
 {
-       struct arm_vm_region *c;
-       
-       list_for_each_entry(c, &head->vm_list, vm_list) {
-               if (c->vm_active && c->vm_start == addr)
-                       goto out;
+       struct page *e = page + (size >> PAGE_SHIFT);
+
+       while (page < e) {
+               __free_page(page);
+               page++;
        }
-       c = NULL;
- out:
-       return c;
 }
 
+#ifdef CONFIG_MMU
+/*
+ * These are the page tables (2MB each) covering uncached, DMA consistent allocations
+ */
+static pte_t *consistent_pte[NUM_CONSISTENT_PTES];
+
+#include "vmregion.h"
+
+static struct arm_vmregion_head consistent_head = {
+       .vm_lock        = __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock),
+       .vm_list        = LIST_HEAD_INIT(consistent_head.vm_list),
+       .vm_start       = CONSISTENT_BASE,
+       .vm_end         = CONSISTENT_END,
+};
+
 #ifdef CONFIG_HUGETLB_PAGE
 #error ARM Coherent DMA allocator does not (yet) support huge TLB
 #endif
 
-static void *
-__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
-           pgprot_t prot)
+/*
+ * Initialise the consistent memory allocation.
+ */
+static int __init consistent_init(void)
 {
-       struct page *page;
-       struct arm_vm_region *c;
-       unsigned long order;
-       u64 mask = get_coherent_dma_mask(dev);
-       u64 limit;
+       int ret = 0;
+       pgd_t *pgd;
+       pmd_t *pmd;
+       pte_t *pte;
+       int i = 0;
+       u32 base = CONSISTENT_BASE;
 
-       if (!consistent_pte[0]) {
-               printk(KERN_ERR "%s: not initialised\n", __func__);
-               dump_stack();
-               return NULL;
-       }
+       do {
+               pgd = pgd_offset(&init_mm, base);
+               pmd = pmd_alloc(&init_mm, pgd, base);
+               if (!pmd) {
+                       printk(KERN_ERR "%s: no pmd tables\n", __func__);
+                       ret = -ENOMEM;
+                       break;
+               }
+               WARN_ON(!pmd_none(*pmd));
 
-       if (!mask)
-               goto no_page;
+               pte = pte_alloc_kernel(pmd, base);
+               if (!pte) {
+                       printk(KERN_ERR "%s: no pte tables\n", __func__);
+                       ret = -ENOMEM;
+                       break;
+               }
 
-       /*
-        * Sanity check the allocation size.
-        */
-       size = PAGE_ALIGN(size);
-       limit = (mask + 1) & ~mask;
-       if ((limit && size >= limit) ||
-           size >= (CONSISTENT_END - CONSISTENT_BASE)) {
-               printk(KERN_WARNING "coherent allocation too big "
-                      "(requested %#x mask %#llx)\n", size, mask);
-               goto no_page;
-       }
+               consistent_pte[i++] = pte;
+               base += (1 << PGDIR_SHIFT);
+       } while (base < CONSISTENT_END);
 
-       order = get_order(size);
+       return ret;
+}
 
-       if (mask < 0xffffffffULL)
-               gfp |= GFP_DMA;
+core_initcall(consistent_init);
 
-       page = alloc_pages(gfp, order);
-       if (!page)
-               goto no_page;
+static void *
+__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot)
+{
+       struct arm_vmregion *c;
 
-       /*
-        * Invalidate any data that might be lurking in the
-        * kernel direct-mapped region for device DMA.
-        */
-       {
-               void *ptr = page_address(page);
-               memset(ptr, 0, size);
-               dmac_flush_range(ptr, ptr + size);
-               outer_flush_range(__pa(ptr), __pa(ptr) + size);
+       if (!consistent_pte[0]) {
+               printk(KERN_ERR "%s: not initialised\n", __func__);
+               dump_stack();
+               return NULL;
        }
 
        /*
         * Allocate a virtual address in the consistent mapping region.
         */
-       c = arm_vm_region_alloc(&consistent_head, size,
+       c = arm_vmregion_alloc(&consistent_head, size,
                            gfp & ~(__GFP_DMA | __GFP_HIGHMEM));
        if (c) {
                pte_t *pte;
-               struct page *end = page + (1 << order);
                int idx = CONSISTENT_PTE_INDEX(c->vm_start);
                u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
 
                pte = consistent_pte[idx] + off;
                c->vm_pages = page;
 
-               split_page(page, order);
-
-               /*
-                * Set the "dma handle"
-                */
-               *handle = page_to_dma(dev, page);
-
                do {
                        BUG_ON(!pte_none(*pte));
 
-                       /*
-                        * x86 does not mark the pages reserved...
-                        */
-                       SetPageReserved(page);
                        set_pte_ext(pte, mk_pte(page, prot), 0);
                        page++;
                        pte++;
@@ -261,48 +219,90 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
                        }
                } while (size -= PAGE_SIZE);
 
-               /*
-                * Free the otherwise unused pages.
-                */
-               while (page < end) {
-                       __free_page(page);
-                       page++;
-               }
-
                return (void *)c->vm_start;
        }
-
-       if (page)
-               __free_pages(page, order);
- no_page:
-       *handle = ~0;
        return NULL;
 }
+
+static void __dma_free_remap(void *cpu_addr, size_t size)
+{
+       struct arm_vmregion *c;
+       unsigned long addr;
+       pte_t *ptep;
+       int idx;
+       u32 off;
+
+       c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
+       if (!c) {
+               printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
+                      __func__, cpu_addr);
+               dump_stack();
+               return;
+       }
+
+       if ((c->vm_end - c->vm_start) != size) {
+               printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
+                      __func__, c->vm_end - c->vm_start, size);
+               dump_stack();
+               size = c->vm_end - c->vm_start;
+       }
+
+       idx = CONSISTENT_PTE_INDEX(c->vm_start);
+       off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
+       ptep = consistent_pte[idx] + off;
+       addr = c->vm_start;
+       do {
+               pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
+
+               ptep++;
+               addr += PAGE_SIZE;
+               off++;
+               if (off >= PTRS_PER_PTE) {
+                       off = 0;
+                       ptep = consistent_pte[++idx];
+               }
+
+               if (pte_none(pte) || !pte_present(pte))
+                       printk(KERN_CRIT "%s: bad page in kernel page table\n",
+                              __func__);
+       } while (size -= PAGE_SIZE);
+
+       flush_tlb_kernel_range(c->vm_start, c->vm_end);
+
+       arm_vmregion_free(&consistent_head, c);
+}
+
 #else  /* !CONFIG_MMU */
+
+#define __dma_alloc_remap(page, size, gfp, prot)       page_address(page)
+#define __dma_free_remap(addr, size)                   do { } while (0)
+
+#endif /* CONFIG_MMU */
+
 static void *
 __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
            pgprot_t prot)
 {
-       void *virt;
-       u64 mask = get_coherent_dma_mask(dev);
+       struct page *page;
+       void *addr;
 
-       if (!mask)
-               goto error;
+       *handle = ~0;
+       size = PAGE_ALIGN(size);
 
-       if (mask < 0xffffffffULL)
-               gfp |= GFP_DMA;
-       virt = kmalloc(size, gfp);
-       if (!virt)
-               goto error;
+       page = __dma_alloc_buffer(dev, size, gfp);
+       if (!page)
+               return NULL;
 
-       *handle =  virt_to_dma(dev, virt);
-       return virt;
+       if (!arch_is_coherent())
+               addr = __dma_alloc_remap(page, size, gfp, prot);
+       else
+               addr = page_address(page);
 
-error:
-       *handle = ~0;
-       return NULL;
+       if (addr)
+               *handle = page_to_dma(dev, page);
+
+       return addr;
 }
-#endif /* CONFIG_MMU */
 
 /*
  * Allocate DMA-coherent memory space and return both the kernel remapped
@@ -316,19 +316,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gf
        if (dma_alloc_from_coherent(dev, size, handle, &memory))
                return memory;
 
-       if (arch_is_coherent()) {
-               void *virt;
-
-               virt = kmalloc(size, gfp);
-               if (!virt)
-                       return NULL;
-               *handle =  virt_to_dma(dev, virt);
-
-               return virt;
-       }
-
        return __dma_alloc(dev, size, handle, gfp,
-                          pgprot_noncached(pgprot_kernel));
+                          pgprot_dmacoherent(pgprot_kernel));
 }
 EXPORT_SYMBOL(dma_alloc_coherent);
 
@@ -349,15 +338,12 @@ static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
 {
        int ret = -ENXIO;
 #ifdef CONFIG_MMU
-       unsigned long flags, user_size, kern_size;
-       struct arm_vm_region *c;
+       unsigned long user_size, kern_size;
+       struct arm_vmregion *c;
 
        user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 
-       spin_lock_irqsave(&consistent_lock, flags);
-       c = arm_vm_region_find(&consistent_head, (unsigned long)cpu_addr);
-       spin_unlock_irqrestore(&consistent_lock, flags);
-
+       c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
        if (c) {
                unsigned long off = vma->vm_pgoff;
 
@@ -379,7 +365,7 @@ static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
 int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
                      void *cpu_addr, dma_addr_t dma_addr, size_t size)
 {
-       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+       vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot);
        return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
 }
 EXPORT_SYMBOL(dma_mmap_coherent);
@@ -396,143 +382,22 @@ EXPORT_SYMBOL(dma_mmap_writecombine);
  * free a page as defined by the above mapping.
  * Must not be called with IRQs disabled.
  */
-#ifdef CONFIG_MMU
 void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
 {
-       struct arm_vm_region *c;
-       unsigned long flags, addr;
-       pte_t *ptep;
-       int idx;
-       u32 off;
-
        WARN_ON(irqs_disabled());
 
        if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
                return;
 
-       if (arch_is_coherent()) {
-               kfree(cpu_addr);
-               return;
-       }
-
        size = PAGE_ALIGN(size);
 
-       spin_lock_irqsave(&consistent_lock, flags);
-       c = arm_vm_region_find(&consistent_head, (unsigned long)cpu_addr);
-       if (!c)
-               goto no_area;
-
-       c->vm_active = 0;
-       spin_unlock_irqrestore(&consistent_lock, flags);
-
-       if ((c->vm_end - c->vm_start) != size) {
-               printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
-                      __func__, c->vm_end - c->vm_start, size);
-               dump_stack();
-               size = c->vm_end - c->vm_start;
-       }
-
-       idx = CONSISTENT_PTE_INDEX(c->vm_start);
-       off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
-       ptep = consistent_pte[idx] + off;
-       addr = c->vm_start;
-       do {
-               pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
-               unsigned long pfn;
-
-               ptep++;
-               addr += PAGE_SIZE;
-               off++;
-               if (off >= PTRS_PER_PTE) {
-                       off = 0;
-                       ptep = consistent_pte[++idx];
-               }
-
-               if (!pte_none(pte) && pte_present(pte)) {
-                       pfn = pte_pfn(pte);
-
-                       if (pfn_valid(pfn)) {
-                               struct page *page = pfn_to_page(pfn);
-
-                               /*
-                                * x86 does not mark the pages reserved...
-                                */
-                               ClearPageReserved(page);
-
-                               __free_page(page);
-                               continue;
-                       }
-               }
-
-               printk(KERN_CRIT "%s: bad page in kernel page table\n",
-                      __func__);
-       } while (size -= PAGE_SIZE);
-
-       flush_tlb_kernel_range(c->vm_start, c->vm_end);
-
-       spin_lock_irqsave(&consistent_lock, flags);
-       list_del(&c->vm_list);
-       spin_unlock_irqrestore(&consistent_lock, flags);
-
-       kfree(c);
-       return;
+       if (!arch_is_coherent())
+               __dma_free_remap(cpu_addr, size);
 
- no_area:
-       spin_unlock_irqrestore(&consistent_lock, flags);
-       printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n",
-              __func__, cpu_addr);
-       dump_stack();
+       __dma_free_buffer(dma_to_page(dev, handle), size);
 }
-#else  /* !CONFIG_MMU */
-void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle)
-{
-       if (dma_release_from_coherent(dev, get_order(size), cpu_addr))
-               return;
-       kfree(cpu_addr);
-}
-#endif /* CONFIG_MMU */
 EXPORT_SYMBOL(dma_free_coherent);
 
-/*
- * Initialise the consistent memory allocation.
- */
-static int __init consistent_init(void)
-{
-       int ret = 0;
-#ifdef CONFIG_MMU
-       pgd_t *pgd;
-       pmd_t *pmd;
-       pte_t *pte;
-       int i = 0;
-       u32 base = CONSISTENT_BASE;
-
-       do {
-               pgd = pgd_offset(&init_mm, base);
-               pmd = pmd_alloc(&init_mm, pgd, base);
-               if (!pmd) {
-                       printk(KERN_ERR "%s: no pmd tables\n", __func__);
-                       ret = -ENOMEM;
-                       break;
-               }
-               WARN_ON(!pmd_none(*pmd));
-
-               pte = pte_alloc_kernel(pmd, base);
-               if (!pte) {
-                       printk(KERN_ERR "%s: no pte tables\n", __func__);
-                       ret = -ENOMEM;
-                       break;
-               }
-
-               consistent_pte[i++] = pte;
-               base += (1 << PGDIR_SHIFT);
-       } while (base < CONSISTENT_END);
-#endif /* !CONFIG_MMU */
-
-       return ret;
-}
-
-core_initcall(consistent_init);
-
 /*
  * Make an area consistent for devices.
  * Note: Drivers should NOT use this function directly, as it will break
index d0d17b6..7296022 100644 (file)
@@ -23,6 +23,8 @@
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 
+#include "mm.h"
+
 static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE;
 
 /*
@@ -151,7 +153,14 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte)
        if (!pfn_valid(pfn))
                return;
 
+       /*
+        * The zero page is never written to, so never has any dirty
+        * cache lines, and therefore never needs to be flushed.
+        */
        page = pfn_to_page(pfn);
+       if (page == ZERO_PAGE(0))
+               return;
+
        mapping = page_mapping(page);
 #ifndef CONFIG_SMP
        if (test_and_clear_bit(PG_dcache_dirty, &page->flags))
index 7f294f3..329594e 100644 (file)
@@ -35,14 +35,12 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
            :
            : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero)
            : "cc");
-       __flush_icache_all();
 }
 
 void flush_cache_mm(struct mm_struct *mm)
 {
        if (cache_is_vivt()) {
-               if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
-                       __cpuc_flush_user_all();
+               vivt_flush_cache_mm(mm);
                return;
        }
 
@@ -52,16 +50,13 @@ void flush_cache_mm(struct mm_struct *mm)
                    :
                    : "r" (0)
                    : "cc");
-               __flush_icache_all();
        }
 }
 
 void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
 {
        if (cache_is_vivt()) {
-               if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm)))
-                       __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
-                                               vma->vm_flags);
+               vivt_flush_cache_range(vma, start, end);
                return;
        }
 
@@ -71,22 +66,26 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned
                    :
                    : "r" (0)
                    : "cc");
-               __flush_icache_all();
        }
+
+       if (vma->vm_flags & VM_EXEC)
+               __flush_icache_all();
 }
 
 void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
 {
        if (cache_is_vivt()) {
-               if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
-                       unsigned long addr = user_addr & PAGE_MASK;
-                       __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
-               }
+               vivt_flush_cache_page(vma, user_addr, pfn);
                return;
        }
 
-       if (cache_is_vipt_aliasing())
+       if (cache_is_vipt_aliasing()) {
                flush_pfn_alias(pfn, user_addr);
+               __flush_icache_all();
+       }
+
+       if (vma->vm_flags & VM_EXEC && icache_is_vivt_asid_tagged())
+               __flush_icache_all();
 }
 
 void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
@@ -94,15 +93,13 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
                         unsigned long len, int write)
 {
        if (cache_is_vivt()) {
-               if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
-                       unsigned long addr = (unsigned long)kaddr;
-                       __cpuc_coherent_kern_range(addr, addr + len);
-               }
+               vivt_flush_ptrace_access(vma, page, uaddr, kaddr, len, write);
                return;
        }
 
        if (cache_is_vipt_aliasing()) {
                flush_pfn_alias(page_to_pfn(page), uaddr);
+               __flush_icache_all();
                return;
        }
 
@@ -120,6 +117,8 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
 
 void __flush_dcache_page(struct address_space *mapping, struct page *page)
 {
+       void *addr = page_address(page);
+
        /*
         * Writeback any data associated with the kernel mapping of this
         * page.  This ensures that data in the physical page is mutually
@@ -130,9 +129,9 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page)
         * kmap_atomic() doesn't set the page virtual address, and
         * kunmap_atomic() takes care of cache flushing already.
         */
-       if (page_address(page))
+       if (addr)
 #endif
-               __cpuc_flush_dcache_page(page_address(page));
+               __cpuc_flush_dcache_page(addr);
 
        /*
         * If this is a page cache page, and we have an aliasing VIPT cache,
@@ -196,7 +195,16 @@ static void __flush_dcache_aliases(struct address_space *mapping, struct page *p
  */
 void flush_dcache_page(struct page *page)
 {
-       struct address_space *mapping = page_mapping(page);
+       struct address_space *mapping;
+
+       /*
+        * The zero page is never written to, so never has any dirty
+        * cache lines, and therefore never needs to be flushed.
+        */
+       if (page == ZERO_PAGE(0))
+               return;
+
+       mapping = page_mapping(page);
 
 #ifndef CONFIG_SMP
        if (!PageHighMem(page) && mapping && !mapping_mapped(mapping))
@@ -242,6 +250,7 @@ void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned l
                 * userspace address only.
                 */
                flush_pfn_alias(pfn, vmaddr);
+               __flush_icache_all();
        }
 
        /*
index c4f6f05..a888363 100644 (file)
@@ -24,6 +24,8 @@ struct mem_type {
 
 const struct mem_type *get_mem_type(unsigned int type);
 
+extern void __flush_dcache_page(struct address_space *mapping, struct page *page);
+
 #endif
 
 struct map_desc;
index ea67be0..2427cdc 100644 (file)
@@ -1036,7 +1036,7 @@ void __init paging_init(struct machine_desc *mdesc)
         */
        zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
        empty_zero_page = virt_to_page(zero_page);
-       flush_dcache_page(empty_zero_page);
+       __flush_dcache_page(NULL, empty_zero_page);
 }
 
 /*
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c
new file mode 100644 (file)
index 0000000..19e09bd
--- /dev/null
@@ -0,0 +1,131 @@
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+
+#include "vmregion.h"
+
+/*
+ * VM region handling support.
+ *
+ * This should become something generic, handling VM region allocations for
+ * vmalloc and similar (ioremap, module space, etc).
+ *
+ * I envisage vmalloc()'s supporting vm_struct becoming:
+ *
+ *  struct vm_struct {
+ *    struct vmregion  region;
+ *    unsigned long    flags;
+ *    struct page      **pages;
+ *    unsigned int     nr_pages;
+ *    unsigned long    phys_addr;
+ *  };
+ *
+ * get_vm_area() would then call vmregion_alloc with an appropriate
+ * struct vmregion head (eg):
+ *
+ *  struct vmregion vmalloc_head = {
+ *     .vm_list        = LIST_HEAD_INIT(vmalloc_head.vm_list),
+ *     .vm_start       = VMALLOC_START,
+ *     .vm_end         = VMALLOC_END,
+ *  };
+ *
+ * However, vmalloc_head.vm_start is variable (typically, it is dependent on
+ * the amount of RAM found at boot time.)  I would imagine that get_vm_area()
+ * would have to initialise this each time prior to calling vmregion_alloc().
+ */
+
+struct arm_vmregion *
+arm_vmregion_alloc(struct arm_vmregion_head *head, size_t size, gfp_t gfp)
+{
+       unsigned long addr = head->vm_start, end = head->vm_end - size;
+       unsigned long flags;
+       struct arm_vmregion *c, *new;
+
+       if (head->vm_end - head->vm_start < size) {
+               printk(KERN_WARNING "%s: allocation too big (requested %#x)\n",
+                       __func__, size);
+               goto out;
+       }
+
+       new = kmalloc(sizeof(struct arm_vmregion), gfp);
+       if (!new)
+               goto out;
+
+       spin_lock_irqsave(&head->vm_lock, flags);
+
+       list_for_each_entry(c, &head->vm_list, vm_list) {
+               if ((addr + size) < addr)
+                       goto nospc;
+               if ((addr + size) <= c->vm_start)
+                       goto found;
+               addr = c->vm_end;
+               if (addr > end)
+                       goto nospc;
+       }
+
+ found:
+       /*
+        * Insert this entry _before_ the one we found.
+        */
+       list_add_tail(&new->vm_list, &c->vm_list);
+       new->vm_start = addr;
+       new->vm_end = addr + size;
+       new->vm_active = 1;
+
+       spin_unlock_irqrestore(&head->vm_lock, flags);
+       return new;
+
+ nospc:
+       spin_unlock_irqrestore(&head->vm_lock, flags);
+       kfree(new);
+ out:
+       return NULL;
+}
+
+static struct arm_vmregion *__arm_vmregion_find(struct arm_vmregion_head *head, unsigned long addr)
+{
+       struct arm_vmregion *c;
+
+       list_for_each_entry(c, &head->vm_list, vm_list) {
+               if (c->vm_active && c->vm_start == addr)
+                       goto out;
+       }
+       c = NULL;
+ out:
+       return c;
+}
+
+struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *head, unsigned long addr)
+{
+       struct arm_vmregion *c;
+       unsigned long flags;
+
+       spin_lock_irqsave(&head->vm_lock, flags);
+       c = __arm_vmregion_find(head, addr);
+       spin_unlock_irqrestore(&head->vm_lock, flags);
+       return c;
+}
+
+struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *head, unsigned long addr)
+{
+       struct arm_vmregion *c;
+       unsigned long flags;
+
+       spin_lock_irqsave(&head->vm_lock, flags);
+       c = __arm_vmregion_find(head, addr);
+       if (c)
+               c->vm_active = 0;
+       spin_unlock_irqrestore(&head->vm_lock, flags);
+       return c;
+}
+
+void arm_vmregion_free(struct arm_vmregion_head *head, struct arm_vmregion *c)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&head->vm_lock, flags);
+       list_del(&c->vm_list);
+       spin_unlock_irqrestore(&head->vm_lock, flags);
+
+       kfree(c);
+}
diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h
new file mode 100644 (file)
index 0000000..6b2cdbd
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef VMREGION_H
+#define VMREGION_H
+
+#include <linux/spinlock.h>
+#include <linux/list.h>
+
+struct page;
+
+struct arm_vmregion_head {
+       spinlock_t              vm_lock;
+       struct list_head        vm_list;
+       unsigned long           vm_start;
+       unsigned long           vm_end;
+};
+
+struct arm_vmregion {
+       struct list_head        vm_list;
+       unsigned long           vm_start;
+       unsigned long           vm_end;
+       struct page             *vm_pages;
+       int                     vm_active;
+};
+
+struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, gfp_t);
+struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long);
+struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long);
+void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *);
+
+#endif
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig
new file mode 100644 (file)
index 0000000..159daf5
--- /dev/null
@@ -0,0 +1,22 @@
+# We keep common IP's here for Nomadik and other similar
+# familiy of processors from ST-Ericsson. At the moment we have
+# just MTU, others to follow soon.
+
+config PLAT_NOMADIK
+       bool
+       depends on ARCH_NOMADIK || ARCH_U8500
+       default y
+       help
+         Common platform code for Nomadik and other ST-Ericsson
+         platforms.
+
+if PLAT_NOMADIK
+
+config HAS_MTU
+       bool
+       help
+         Support for Multi Timer Unit. MTU provides access
+         to multiple interrupt generating programmable
+         32-bit free running decrementing counters.
+
+endif
diff --git a/arch/arm/plat-nomadik/Makefile b/arch/arm/plat-nomadik/Makefile
new file mode 100644 (file)
index 0000000..37c7cdd
--- /dev/null
@@ -0,0 +1,5 @@
+# arch/arm/plat-nomadik/Makefile
+# Copyright 2009 ST-Ericsson
+# Licensed under GPLv2
+
+obj-$(CONFIG_HAS_MTU)  += timer.o
diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h
new file mode 100644 (file)
index 0000000..42c9072
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef __PLAT_MTU_H
+#define __PLAT_MTU_H
+
+/* should be set by the platform code */
+extern void __iomem *mtu_base;
+
+/*
+ * The MTU device hosts four different counters, with 4 set of
+ * registers. These are register names.
+ */
+
+#define MTU_IMSC       0x00    /* Interrupt mask set/clear */
+#define MTU_RIS                0x04    /* Raw interrupt status */
+#define MTU_MIS                0x08    /* Masked interrupt status */
+#define MTU_ICR                0x0C    /* Interrupt clear register */
+
+/* per-timer registers take 0..3 as argument */
+#define MTU_LR(x)      (0x10 + 0x10 * (x) + 0x00)      /* Load value */
+#define MTU_VAL(x)     (0x10 + 0x10 * (x) + 0x04)      /* Current value */
+#define MTU_CR(x)      (0x10 + 0x10 * (x) + 0x08)      /* Control reg */
+#define MTU_BGLR(x)    (0x10 + 0x10 * (x) + 0x0c)      /* At next overflow */
+
+/* bits for the control register */
+#define MTU_CRn_ENA            0x80
+#define MTU_CRn_PERIODIC       0x40    /* if 0 = free-running */
+#define MTU_CRn_PRESCALE_MASK  0x0c
+#define MTU_CRn_PRESCALE_1             0x00
+#define MTU_CRn_PRESCALE_16            0x04
+#define MTU_CRn_PRESCALE_256           0x08
+#define MTU_CRn_32BITS         0x02
+#define MTU_CRn_ONESHOT                0x01    /* if 0 = wraps reloading from BGLR*/
+
+/* Other registers are usual amba/primecell registers, currently not used */
+#define MTU_ITCR       0xff0
+#define MTU_ITOP       0xff4
+
+#define MTU_PERIPH_ID0 0xfe0
+#define MTU_PERIPH_ID1 0xfe4
+#define MTU_PERIPH_ID2 0xfe8
+#define MTU_PERIPH_ID3 0xfeC
+
+#define MTU_PCELL0     0xff0
+#define MTU_PCELL1     0xff4
+#define MTU_PCELL2     0xff8
+#define MTU_PCELL3     0xffC
+
+#endif /* __PLAT_MTU_H */
+
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
new file mode 100644 (file)
index 0000000..62f18ad
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ *  linux/arch/arm/mach-nomadik/timer.c
+ *
+ * Copyright (C) 2008 STMicroelectronics
+ * Copyright (C) 2009 Alessandro Rubini, somewhat based on at91sam926x
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/clockchips.h>
+#include <linux/jiffies.h>
+#include <asm/mach/time.h>
+
+#include <plat/mtu.h>
+
+static u32     nmdk_count;             /* accumulated count */
+static u32     nmdk_cycle;             /* write-once */
+
+/* setup by the platform code */
+void __iomem *mtu_base;
+
+/*
+ * clocksource: the MTU device is a decrementing counters, so we negate
+ * the value being read.
+ */
+static cycle_t nmdk_read_timer(struct clocksource *cs)
+{
+       u32 count = readl(mtu_base + MTU_VAL(0));
+       return nmdk_count + nmdk_cycle - count;
+
+}
+
+static struct clocksource nmdk_clksrc = {
+       .name           = "mtu_0",
+       .rating         = 120,
+       .read           = nmdk_read_timer,
+       .shift          = 20,
+       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/*
+ * Clockevent device: currently only periodic mode is supported
+ */
+static void nmdk_clkevt_mode(enum clock_event_mode mode,
+                            struct clock_event_device *dev)
+{
+       unsigned long flags;
+
+       switch (mode) {
+       case CLOCK_EVT_MODE_PERIODIC:
+               /* enable interrupts -- and count current value? */
+               raw_local_irq_save(flags);
+               writel(readl(mtu_base + MTU_IMSC) | 1, mtu_base + MTU_IMSC);
+               raw_local_irq_restore(flags);
+               break;
+       case CLOCK_EVT_MODE_ONESHOT:
+               BUG(); /* Not supported, yet */
+               /* FALLTHROUGH */
+       case CLOCK_EVT_MODE_SHUTDOWN:
+       case CLOCK_EVT_MODE_UNUSED:
+               /* disable irq */
+               raw_local_irq_save(flags);
+               writel(readl(mtu_base + MTU_IMSC) & ~1, mtu_base + MTU_IMSC);
+               raw_local_irq_restore(flags);
+               break;
+       case CLOCK_EVT_MODE_RESUME:
+               break;
+       }
+}
+
+static struct clock_event_device nmdk_clkevt = {
+       .name           = "mtu_0",
+       .features       = CLOCK_EVT_FEAT_PERIODIC,
+       .shift          = 32,
+       .rating         = 100,
+       .set_mode       = nmdk_clkevt_mode,
+};
+
+/*
+ * IRQ Handler for the timer 0 of the MTU block. The irq is not shared
+ * as we are the only users of mtu0 by now.
+ */
+static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id)
+{
+       /* ack: "interrupt clear register" */
+       writel(1 << 0, mtu_base + MTU_ICR);
+
+       /* we can't count lost ticks, unfortunately */
+       nmdk_count += nmdk_cycle;
+       nmdk_clkevt.event_handler(&nmdk_clkevt);
+
+       return IRQ_HANDLED;
+}
+
+/*
+ * Set up timer interrupt, and return the current time in seconds.
+ */
+static struct irqaction nmdk_timer_irq = {
+       .name           = "Nomadik Timer Tick",
+       .flags          = IRQF_DISABLED | IRQF_TIMER,
+       .handler        = nmdk_timer_interrupt,
+};
+
+static void nmdk_timer_reset(void)
+{
+       u32 cr;
+
+       writel(0, mtu_base + MTU_CR(0)); /* off */
+
+       /* configure load and background-load, and fire it up */
+       writel(nmdk_cycle, mtu_base + MTU_LR(0));
+       writel(nmdk_cycle, mtu_base + MTU_BGLR(0));
+       cr = MTU_CRn_PERIODIC | MTU_CRn_PRESCALE_1 | MTU_CRn_32BITS;
+       writel(cr, mtu_base + MTU_CR(0));
+       writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
+}
+
+void __init nmdk_timer_init(void)
+{
+       unsigned long rate;
+       int bits;
+
+       rate = CLOCK_TICK_RATE; /* 2.4MHz */
+       nmdk_cycle = (rate + HZ/2) / HZ;
+
+       /* Init the timer and register clocksource */
+       nmdk_timer_reset();
+
+       nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
+       bits =  8*sizeof(nmdk_count);
+       nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits);
+
+       if (clocksource_register(&nmdk_clksrc))
+               printk(KERN_ERR "timer: failed to initialize clock "
+                       "source %s\n", nmdk_clksrc.name);
+
+       /* Register irq and clockevents */
+       setup_irq(IRQ_MTU0, &nmdk_timer_irq);
+       nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
+       nmdk_clkevt.cpumask = cpumask_of(0);
+       clockevents_register_device(&nmdk_clkevt);
+}
index 9ad41dc..3325f7b 100644 (file)
                __dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \
           __dma; })
 
+#define __arch_dma_to_page(dev, addr)  \
+       ({ dma_addr_t __dma = addr;                             \
+          if (is_lbus_device(dev))                             \
+               __dma += PHYS_OFFSET - OMAP1510_LB_OFFSET;      \
+          phys_to_page(__dma);                                 \
+       })
+
 #define __arch_dma_to_virt(dev, addr)  ({ (void *) (is_lbus_device(dev) ? \
                                                lbus_to_virt(addr) : \
                                                __phys_to_virt(addr)); })
index 94be7bb..07b976d 100644 (file)
@@ -12,7 +12,7 @@
 #
 #   http://www.arm.linux.org.uk/developer/machines/?action=new
 #
-# Last update: Fri Sep 18 21:42:00 2009
+# Last update: Wed Nov 25 22:14:58 2009
 #
 # machine_is_xxx       CONFIG_xxxx             MACH_TYPE_xxx           number
 #
@@ -928,7 +928,7 @@ palmt5                      MACH_PALMT5             PALMT5                  917
 palmtc                 MACH_PALMTC             PALMTC                  918
 omap_apollon           MACH_OMAP_APOLLON       OMAP_APOLLON            919
 mxc30030evb            MACH_MXC30030EVB        MXC30030EVB             920
-rea_2d                 MACH_REA_2D             REA_2D                  921
+rea_cpu2               MACH_REA_2D             REA_2D                  921
 eti3e524               MACH_TI3E524            TI3E524                 922
 ateb9200               MACH_ATEB9200           ATEB9200                923
 auckland               MACH_AUCKLAND           AUCKLAND                924
@@ -2421,3 +2421,118 @@ liberty                 MACH_LIBERTY            LIBERTY                 2434
 mh355                  MACH_MH355              MH355                   2435
 pc7802                 MACH_PC7802             PC7802                  2436
 gnet_sgc               MACH_GNET_SGC           GNET_SGC                2437
+einstein15             MACH_EINSTEIN15         EINSTEIN15              2438
+cmpd                   MACH_CMPD               CMPD                    2439
+davinci_hase1          MACH_DAVINCI_HASE1      DAVINCI_HASE1           2440
+lgeincitephone         MACH_LGEINCITEPHONE     LGEINCITEPHONE          2441
+ea313x                 MACH_EA313X             EA313X                  2442
+fwbd_39064             MACH_FWBD_39064         FWBD_39064              2443
+fwbd_390128            MACH_FWBD_390128        FWBD_390128             2444
+pelco_moe              MACH_PELCO_MOE          PELCO_MOE               2445
+minimix27              MACH_MINIMIX27          MINIMIX27               2446
+omap3_thunder          MACH_OMAP3_THUNDER      OMAP3_THUNDER           2447
+passionc               MACH_PASSIONC           PASSIONC                2448
+mx27amata              MACH_MX27AMATA          MX27AMATA               2449
+bgat1                  MACH_BGAT1              BGAT1                   2450
+buzz                   MACH_BUZZ               BUZZ                    2451
+mb9g20                 MACH_MB9G20             MB9G20                  2452
+yushan                 MACH_YUSHAN             YUSHAN                  2453
+lizard                 MACH_LIZARD             LIZARD                  2454
+omap3polycom           MACH_OMAP3POLYCOM       OMAP3POLYCOM            2455
+smdkv210               MACH_SMDKV210           SMDKV210                2456
+bravo                  MACH_BRAVO              BRAVO                   2457
+siogentoo1             MACH_SIOGENTOO1         SIOGENTOO1              2458
+siogentoo2             MACH_SIOGENTOO2         SIOGENTOO2              2459
+sm3k                   MACH_SM3K               SM3K                    2460
+acer_tempo_f900                MACH_ACER_TEMPO_F900    ACER_TEMPO_F900         2461
+sst61vc010_dev         MACH_SST61VC010_DEV     SST61VC010_DEV          2462
+glittertind            MACH_GLITTERTIND        GLITTERTIND             2463
+omap_zoom3             MACH_OMAP_ZOOM3         OMAP_ZOOM3              2464
+omap_3630sdp           MACH_OMAP_3630SDP       OMAP_3630SDP            2465
+cybook2440             MACH_CYBOOK2440         CYBOOK2440              2466
+torino_s               MACH_TORINO_S           TORINO_S                2467
+havana                 MACH_HAVANA             HAVANA                  2468
+beaumont_11            MACH_BEAUMONT_11        BEAUMONT_11             2469
+vanguard               MACH_VANGUARD           VANGUARD                2470
+s5pc110_draco          MACH_S5PC110_DRACO      S5PC110_DRACO           2471
+cartesio_two           MACH_CARTESIO_TWO       CARTESIO_TWO            2472
+aster                  MACH_ASTER              ASTER                   2473
+voguesv210             MACH_VOGUESV210         VOGUESV210              2474
+acm500x                        MACH_ACM500X            ACM500X                 2475
+km9260                 MACH_KM9260             KM9260                  2476
+nideflexg1             MACH_NIDEFLEXG1         NIDEFLEXG1              2477
+ctera_plug_io          MACH_CTERA_PLUG_IO      CTERA_PLUG_IO           2478
+smartq7                        MACH_SMARTQ7            SMARTQ7                 2479
+at91sam9g10ek2         MACH_AT91SAM9G10EK2     AT91SAM9G10EK2          2480
+asusp527               MACH_ASUSP527           ASUSP527                2481
+at91sam9g20mpm2                MACH_AT91SAM9G20MPM2    AT91SAM9G20MPM2         2482
+topasa900              MACH_TOPASA900          TOPASA900               2483
+electrum_100           MACH_ELECTRUM_100       ELECTRUM_100            2484
+mx51grb                        MACH_MX51GRB            MX51GRB                 2485
+xea300                 MACH_XEA300             XEA300                  2486
+htcstartrek            MACH_HTCSTARTREK        HTCSTARTREK             2487
+lima                   MACH_LIMA               LIMA                    2488
+csb740                 MACH_CSB740             CSB740                  2489
+usb_s8815              MACH_USB_S8815          USB_S8815               2490
+watson_efm_plugin      MACH_WATSON_EFM_PLUGIN  WATSON_EFM_PLUGIN       2491
+milkyway               MACH_MILKYWAY           MILKYWAY                2492
+g4evm                  MACH_G4EVM              G4EVM                   2493
+picomod6               MACH_PICOMOD6           PICOMOD6                2494
+omapl138_hawkboard     MACH_OMAPL138_HAWKBOARD OMAPL138_HAWKBOARD      2495
+ip6000                 MACH_IP6000             IP6000                  2496
+ip6010                 MACH_IP6010             IP6010                  2497
+utm400                 MACH_UTM400             UTM400                  2498
+omap3_zybex            MACH_OMAP3_ZYBEX        OMAP3_ZYBEX             2499
+wireless_space         MACH_WIRELESS_SPACE     WIRELESS_SPACE          2500
+sx560                  MACH_SX560              SX560                   2501
+ts41x                  MACH_TS41X              TS41X                   2502
+elphel10373            MACH_ELPHEL10373        ELPHEL10373             2503
+rhobot                 MACH_RHOBOT             RHOBOT                  2504
+mx51_refresh           MACH_MX51_REFRESH       MX51_REFRESH            2505
+ls9260                 MACH_LS9260             LS9260                  2506
+shank                  MACH_SHANK              SHANK                   2507
+qsd8x50_st1            MACH_QSD8X50_ST1        QSD8X50_ST1             2508
+at91sam9m10ekes                MACH_AT91SAM9M10EKES    AT91SAM9M10EKES         2509
+hiram                  MACH_HIRAM              HIRAM                   2510
+phy3250                        MACH_PHY3250            PHY3250                 2511
+ea3250                 MACH_EA3250             EA3250                  2512
+fdi3250                        MACH_FDI3250            FDI3250                 2513
+whitestone             MACH_WHITESTONE         WHITESTONE              2514
+at91sam9263nit         MACH_AT91SAM9263NIT     AT91SAM9263NIT          2515
+ccmx51                 MACH_CCMX51             CCMX51                  2516
+ccmx51js               MACH_CCMX51JS           CCMX51JS                2517
+ccwmx51                        MACH_CCWMX51            CCWMX51                 2518
+ccwmx51js              MACH_CCWMX51JS          CCWMX51JS               2519
+mini6410               MACH_MINI6410           MINI6410                2520
+tiny6410               MACH_TINY6410           TINY6410                2521
+nano6410               MACH_NANO6410           NANO6410                2522
+at572d940hfnldb                MACH_AT572D940HFNLDB    AT572D940HFNLDB         2523
+htcleo                 MACH_HTCLEO             HTCLEO                  2524
+avp13                  MACH_AVP13              AVP13                   2525
+xxsvideod              MACH_XXSVIDEOD          XXSVIDEOD               2526
+vpnext                 MACH_VPNEXT             VPNEXT                  2527
+swarco_itc3            MACH_SWARCO_ITC3        SWARCO_ITC3             2528
+tx51                   MACH_TX51               TX51                    2529
+dolby_cat1021          MACH_DOLBY_CAT1021      DOLBY_CAT1021           2530
+mx28evk                        MACH_MX28EVK            MX28EVK                 2531
+phoenix260             MACH_PHOENIX260         PHOENIX260              2532
+uvaca_stork            MACH_UVACA_STORK        UVACA_STORK             2533
+smartq5                        MACH_SMARTQ5            SMARTQ5                 2534
+all3078                        MACH_ALL3078            ALL3078                 2535
+ctera_2bay_ds          MACH_CTERA_2BAY_DS      CTERA_2BAY_DS           2536
+siogentoo3             MACH_SIOGENTOO3         SIOGENTOO3              2537
+epb5000                        MACH_EPB5000            EPB5000                 2538
+hy9263                 MACH_HY9263             HY9263                  2539
+acer_tempo_m900                MACH_ACER_TEMPO_M900    ACER_TEMPO_M900         2540
+acer_tempo_dx650       MACH_ACER_TEMPO_DX900   ACER_TEMPO_DX900        2541
+acer_tempo_x960                MACH_ACER_TEMPO_X960    ACER_TEMPO_X960         2542
+acer_eten_v900         MACH_ACER_ETEN_V900     ACER_ETEN_V900          2543
+acer_eten_x900         MACH_ACER_ETEN_X900     ACER_ETEN_X900          2544
+bonnell                        MACH_BONNELL            BONNELL                 2545
+oht_mx27               MACH_OHT_MX27           OHT_MX27                2546
+htcquartz              MACH_HTCQUARTZ          HTCQUARTZ               2547
+davinci_dm6467tevm     MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM      2548
+c3ax03                 MACH_C3AX03             C3AX03                  2549
+mxt_td60               MACH_MXT_TD60           MXT_TD60                2550
+esyx                   MACH_ESYX               ESYX                    2551
+bulldog                        MACH_BULLDOG            BULLDOG                 2553
index 1f17021..3946aff 100644 (file)
@@ -225,8 +225,13 @@ int blackfin_dma_suspend(void)
 void blackfin_dma_resume(void)
 {
        int i;
-       for (i = 0; i < MAX_DMA_SUSPEND_CHANNELS; ++i)
-               dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map;
+
+       for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
+               dma_ch[i].regs->cfg = 0;
+
+               if (i < MAX_DMA_SUSPEND_CHANNELS)
+                       dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map;
+       }
 }
 #endif
 
index f7b9cdc..b52c1f8 100644 (file)
@@ -38,7 +38,7 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)
 
 #ifdef CONFIG_BFIN_EXTMEM_DCACHEABLE
        d_cache = CPLB_L1_CHBL;
-#ifdef CONFIG_BFIN_EXTMEM_WRITETROUGH
+#ifdef CONFIG_BFIN_EXTMEM_WRITETHROUGH
        d_cache |= CPLB_L1_AOW | CPLB_WT;
 #endif
 #endif
index 430ae39..5cc7e2e 100644 (file)
@@ -151,7 +151,7 @@ void start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_
        regs->pc = new_ip;
        if (current->mm)
                regs->p5 = current->mm->start_data;
-#ifdef CONFIG_SMP
+#ifndef CONFIG_SMP
        task_thread_info(current)->l1_task_info.stack_start =
                (void *)current->mm->context.stack_start;
        task_thread_info(current)->l1_task_info.lowest_sp = (void *)new_sp;
index 0982b5d..56b0ba1 100644 (file)
@@ -315,7 +315,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
                        case BFIN_MEM_ACCESS_CORE:
                        case BFIN_MEM_ACCESS_CORE_ONLY:
                                copied = access_process_vm(child, addr, &data,
-                                                          to_copy, 0);
+                                                          to_copy, 1);
                                if (copied)
                                        break;
 
index e9c6539..2829dd0 100644 (file)
@@ -1,9 +1,13 @@
 /*
- * File: include/asm-blackfin/mach-bf518/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
 #define ANOMALY_05000461 (1)
 /* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */
 #define ANOMALY_05000462 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000099 (0)
 #define ANOMALY_05000450 (0)
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
 
 #endif
index 3f90526..02040df 100644 (file)
@@ -1,14 +1,18 @@
 /*
- * File: include/asm-blackfin/mach-bf527/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
  *  - Revision D, 08/14/2009; ADSP-BF526 Blackfin Processor Anomaly List
- *  - Revision F, 03/03/2009; ADSP-BF527 Blackfin Processor Anomaly List
+ *  - Revision G, 08/25/2009; ADSP-BF527 Blackfin Processor Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
 #define ANOMALY_05000467 (1)
 /* PLL Latches Incorrect Settings During Reset */
 #define ANOMALY_05000469 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000099 (0)
 #define ANOMALY_05000412 (0)
 #define ANOMALY_05000447 (0)
 #define ANOMALY_05000448 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
 
 #endif
index cd83db2..9b3f7a2 100644 (file)
@@ -1,9 +1,13 @@
 /*
- * File: include/asm-blackfin/mach-bf533/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
 #define ANOMALY_05000443 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* These anomalies have been "phased" out of analog.com anomaly sheets and are
  * here to show running on older silicon just isn't feasible.
 #define ANOMALY_05000450 (0)
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
 
 #endif
index f091ad2..d2c427b 100644 (file)
@@ -1,9 +1,13 @@
 /*
- * File: include/asm-blackfin/mach-bf537/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
 #define ANOMALY_05000443 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000099 (0)
 #define ANOMALY_05000450 (0)
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
 
 #endif
index 26b7608..d882b7e 100644 (file)
@@ -1,9 +1,13 @@
 /*
- * File: include/asm-blackfin/mach-bf538/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
 #define ANOMALY_05000443 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000099 (0)
 #define ANOMALY_05000450 (0)
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
+#define ANOMALY_05000475 (0)
 
 #endif
index 52b116a..7d08c75 100644 (file)
@@ -1,9 +1,13 @@
 /*
- * File: include/asm-blackfin/mach-bf548/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
@@ -24,6 +28,8 @@
 #define ANOMALY_05000119 (1)
 /* Rx.H Cannot Be Used to Access 16-bit System MMR Registers */
 #define ANOMALY_05000122 (1)
+/* Data Corruption with Cached External Memory and Non-Cached On-Chip L2 Memory */
+#define ANOMALY_05000220 (1)
 /* False Hardware Error from an Access in the Shadow of a Conditional Branch */
 #define ANOMALY_05000245 (1)
 /* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */
 #define ANOMALY_05000466 (1)
 /* Possible RX data corruption when control & data EP FIFOs are accessed via the core */
 #define ANOMALY_05000467 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* Access to DDR-SDRAM causes system hang under certain PLL/VR settings */
+#define ANOMALY_05000474 (1)
+/* Core Hang With L2/L3 Configured in Writeback Cache Mode */
+#define ANOMALY_05000475 (1)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000099 (0)
 #define ANOMALY_05000198 (0)
 #define ANOMALY_05000202 (0)
 #define ANOMALY_05000215 (0)
-#define ANOMALY_05000220 (0)
 #define ANOMALY_05000227 (0)
 #define ANOMALY_05000230 (0)
 #define ANOMALY_05000231 (0)
index 0261a5e..f99f174 100644 (file)
        \reg\().h = _corelock;
 .endm
 
+.macro safe_testset addr:req, scratch:req
+#if ANOMALY_05000477
+       cli \scratch;
+       testset (\addr);
+       sti \scratch;
+#else
+       testset (\addr);
+#endif
+.endm
+
 /*
  * r0 = address of atomic data to flush and invalidate (32bit).
  *
@@ -33,7 +43,7 @@ ENTRY(_get_core_lock)
        cli r0;
        coreslot_loadaddr p0;
 .Lretry_corelock:
-       testset (p0);
+       safe_testset p0, r2;
        if cc jump .Ldone_corelock;
        SSYNC(r2);
        jump .Lretry_corelock
@@ -56,7 +66,7 @@ ENTRY(_get_core_lock_noflush)
        cli r0;
        coreslot_loadaddr p0;
 .Lretry_corelock_noflush:
-       testset (p0);
+       safe_testset p0, r2;
        if cc jump .Ldone_corelock_noflush;
        SSYNC(r2);
        jump .Lretry_corelock_noflush
index 70da495..5ddc981 100644 (file)
@@ -1,9 +1,13 @@
 /*
- * File: include/asm-blackfin/mach-bf561/anomaly.h
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ * DO NOT EDIT THIS FILE
+ * This file is under version control at
+ *   svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/
+ * and can be replaced with that version at any time
+ * DO NOT EDIT THIS FILE
  *
- * Copyright (C) 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
+ * Copyright 2004-2009 Analog Devices Inc.
+ * Licensed under the ADI BSD license.
+ *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
 /* Disabling Peripherals with DMA Running May Cause DMA System Instability */
 #define ANOMALY_05000278 (__SILICON_REVISION__ < 5)
 /* False Hardware Error Exception when ISR Context Is Not Restored */
-#define ANOMALY_05000281 (__SILICON_REVISION__ < 5)
+/* Temporarily walk around for bug 5423 till this issue is confirmed by
+ * official anomaly document. It looks 05000281 still exists on bf561
+ * v0.5.
+ */
+#define ANOMALY_05000281 (__SILICON_REVISION__ <= 5)
 /* System MMR Write Is Stalled Indefinitely when Killed in a Particular Stage */
 #define ANOMALY_05000283 (1)
 /* Reads Will Receive Incorrect Data under Certain Conditions */
 #define ANOMALY_05000443 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
+#define ANOMALY_05000473 (1)
+/* Core Hang With L2/L3 Configured in Writeback Cache Mode */
+#define ANOMALY_05000475 (__SILICON_REVISION__ < 4)
+/* TESTSET Instruction Cannot Be Interrupted */
+#define ANOMALY_05000477 (1)
 
 /* Anomalies that don't exist on this proc */
 #define ANOMALY_05000119 (0)
 #define ANOMALY_05000450 (0)
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
+#define ANOMALY_05000474 (0)
 
 #endif
index 9dbafcd..f2ca211 100644 (file)
@@ -57,3 +57,8 @@
         (!defined(CONFIG_BFIN_EXTMEM_DCACHEABLE) && defined(CONFIG_BFIN_L2_WRITEBACK)))
 # error You are exposing Anomaly 220 in this config, either config L2 as Write Through, or make External Memory WB.
 #endif
+
+#if ANOMALY_05000475 && \
+       (defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK))
+# error "Anomaly 475 does not allow you to use Write Back cache with L2 or External Memory"
+#endif
index d98585f..d92b168 100644 (file)
@@ -276,10 +276,9 @@ void smp_send_reschedule(int cpu)
        if (cpu_is_offline(cpu))
                return;
 
-       msg = kmalloc(sizeof(*msg), GFP_ATOMIC);
+       msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
        if (!msg)
                return;
-       memset(msg, 0, sizeof(msg));
        INIT_LIST_HEAD(&msg->list);
        msg->type = BFIN_IPI_RESCHEDULE;
 
@@ -305,10 +304,9 @@ void smp_send_stop(void)
        if (cpus_empty(callmap))
                return;
 
-       msg = kmalloc(sizeof(*msg), GFP_ATOMIC);
+       msg = kzalloc(sizeof(*msg), GFP_ATOMIC);
        if (!msg)
                return;
-       memset(msg, 0, sizeof(msg));
        INIT_LIST_HEAD(&msg->list);
        msg->type = BFIN_IPI_CPU_STOP;
 
index 69dad5a..a36799e 100644 (file)
@@ -28,7 +28,7 @@
 #define dbg(x...)
 #endif
 
-#define KERNEL_START (KERNEL_BINARY_TEXT_START - 0x1000)
+#define KERNEL_START (KERNEL_BINARY_TEXT_START)
 
 extern struct unwind_table_entry __start___unwind[];
 extern struct unwind_table_entry __stop___unwind[];
index fda4baa..9dab4a4 100644 (file)
@@ -78,9 +78,6 @@ SECTIONS
         */
        . = ALIGN(PAGE_SIZE);
        data_start = .;
-       EXCEPTION_TABLE(16)
-
-       NOTES
 
        /* unwind info */
        .PARISC.unwind : {
@@ -89,6 +86,9 @@ SECTIONS
                __stop___unwind = .;
        }
 
+       EXCEPTION_TABLE(16)
+       NOTES
+
        /* Data */
        RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
 
index b6bac6f..9163695 100644 (file)
@@ -29,5 +29,16 @@ enum km_type {
        KM_TYPE_NR
 };
 
+/*
+ * This is a temporary build fix that (so they say on lkml....) should no longer
+ * be required after 2.6.33, because of changes planned to the kmap code.
+ * Let's try to remove this cruft then.
+ */
+#ifdef CONFIG_DEBUG_HIGHMEM
+#define KM_NMI         (-1)
+#define KM_NMI_PTE     (-1)
+#define KM_IRQ_PTE     (-1)
+#endif
+
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_KMAP_TYPES_H */
index c2f772d..77d1b31 100644 (file)
@@ -45,7 +45,7 @@ extern void free_initmem(void);
 #define VMEMMAP_ALIGN(x)       (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK)
 
 #define VMEMMAP_SIZE   ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \
-                         sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT)
+                         sizeof(struct page)) >> VMEMMAP_CHUNK_SHIFT)
 extern unsigned long vmemmap_table[VMEMMAP_SIZE];
 #endif
 
index d296f4a..d85d1b2 100644 (file)
@@ -79,7 +79,8 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
        struct cpuinfo_x86 *c = &cpu_data(pr->id);
 
        pr->pdc = NULL;
-       if (c->x86_vendor == X86_VENDOR_INTEL)
+       if (c->x86_vendor == X86_VENDOR_INTEL ||
+           c->x86_vendor == X86_VENDOR_CENTAUR)
                init_intel_pdc(pr, c);
 
        return;
index e5aeb2b..e28e276 100644 (file)
@@ -23,3 +23,8 @@ config ASYNC_RAID6_RECOV
        select ASYNC_CORE
        select ASYNC_PQ
 
+config ASYNC_TX_DISABLE_PQ_VAL_DMA
+       bool
+
+config ASYNC_TX_DISABLE_XOR_VAL_DMA
+       bool
index 6b5cc4f..ec87f53 100644 (file)
@@ -240,6 +240,16 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks,
 }
 EXPORT_SYMBOL_GPL(async_gen_syndrome);
 
+static inline struct dma_chan *
+pq_val_chan(struct async_submit_ctl *submit, struct page **blocks, int disks, size_t len)
+{
+       #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
+       return NULL;
+       #endif
+       return async_tx_find_channel(submit, DMA_PQ_VAL, NULL, 0,  blocks,
+                                    disks, len);
+}
+
 /**
  * async_syndrome_val - asynchronously validate a raid6 syndrome
  * @blocks: source blocks from idx 0..disks-3, P @ disks-2 and Q @ disks-1
@@ -260,9 +270,7 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
                   size_t len, enum sum_check_flags *pqres, struct page *spare,
                   struct async_submit_ctl *submit)
 {
-       struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ_VAL,
-                                                     NULL, 0,  blocks, disks,
-                                                     len);
+       struct dma_chan *chan = pq_val_chan(submit, blocks, disks, len);
        struct dma_device *device = chan ? chan->device : NULL;
        struct dma_async_tx_descriptor *tx;
        unsigned char coefs[disks-2];
index 79182dc..079ae8c 100644 (file)
@@ -234,6 +234,17 @@ static int page_is_zero(struct page *p, unsigned int offset, size_t len)
                memcmp(a, a + 4, len - 4) == 0);
 }
 
+static inline struct dma_chan *
+xor_val_chan(struct async_submit_ctl *submit, struct page *dest,
+                struct page **src_list, int src_cnt, size_t len)
+{
+       #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
+       return NULL;
+       #endif
+       return async_tx_find_channel(submit, DMA_XOR_VAL, &dest, 1, src_list,
+                                    src_cnt, len);
+}
+
 /**
  * async_xor_val - attempt a xor parity check with a dma engine.
  * @dest: destination page used if the xor is performed synchronously
@@ -255,9 +266,7 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset,
              int src_cnt, size_t len, enum sum_check_flags *result,
              struct async_submit_ctl *submit)
 {
-       struct dma_chan *chan = async_tx_find_channel(submit, DMA_XOR_VAL,
-                                                     &dest, 1, src_list,
-                                                     src_cnt, len);
+       struct dma_chan *chan = xor_val_chan(submit, dest, src_list, src_cnt, len);
        struct dma_device *device = chan ? chan->device : NULL;
        struct dma_async_tx_descriptor *tx = NULL;
        dma_addr_t *dma_src = NULL;
index 5fc3292..c654713 100644 (file)
@@ -40,7 +40,7 @@ struct crypto_rfc4106_ctx {
 struct crypto_gcm_ghash_ctx {
        unsigned int cryptlen;
        struct scatterlist *src;
-       crypto_completion_t complete;
+       void (*complete)(struct aead_request *req, int err);
 };
 
 struct crypto_gcm_req_priv_ctx {
@@ -267,23 +267,26 @@ static int gcm_hash_final(struct aead_request *req,
        return crypto_ahash_final(ahreq);
 }
 
-static void gcm_hash_final_done(struct crypto_async_request *areq,
-                               int err)
+static void __gcm_hash_final_done(struct aead_request *req, int err)
 {
-       struct aead_request *req = areq->data;
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
        struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
 
        if (!err)
                crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16);
 
-       gctx->complete(areq, err);
+       gctx->complete(req, err);
 }
 
-static void gcm_hash_len_done(struct crypto_async_request *areq,
-                             int err)
+static void gcm_hash_final_done(struct crypto_async_request *areq, int err)
 {
        struct aead_request *req = areq->data;
+
+       __gcm_hash_final_done(req, err);
+}
+
+static void __gcm_hash_len_done(struct aead_request *req, int err)
+{
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
 
        if (!err) {
@@ -292,13 +295,18 @@ static void gcm_hash_len_done(struct crypto_async_request *areq,
                        return;
        }
 
-       gcm_hash_final_done(areq, err);
+       __gcm_hash_final_done(req, err);
 }
 
-static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq,
-                                      int err)
+static void gcm_hash_len_done(struct crypto_async_request *areq, int err)
 {
        struct aead_request *req = areq->data;
+
+       __gcm_hash_len_done(req, err);
+}
+
+static void __gcm_hash_crypt_remain_done(struct aead_request *req, int err)
+{
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
 
        if (!err) {
@@ -307,13 +315,19 @@ static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq,
                        return;
        }
 
-       gcm_hash_len_done(areq, err);
+       __gcm_hash_len_done(req, err);
 }
 
-static void gcm_hash_crypt_done(struct crypto_async_request *areq,
-                               int err)
+static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq,
+                                      int err)
 {
        struct aead_request *req = areq->data;
+
+       __gcm_hash_crypt_remain_done(req, err);
+}
+
+static void __gcm_hash_crypt_done(struct aead_request *req, int err)
+{
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
        struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
        unsigned int remain;
@@ -327,13 +341,18 @@ static void gcm_hash_crypt_done(struct crypto_async_request *areq,
                        return;
        }
 
-       gcm_hash_crypt_remain_done(areq, err);
+       __gcm_hash_crypt_remain_done(req, err);
 }
 
-static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq,
-                                          int err)
+static void gcm_hash_crypt_done(struct crypto_async_request *areq, int err)
 {
        struct aead_request *req = areq->data;
+
+       __gcm_hash_crypt_done(req, err);
+}
+
+static void __gcm_hash_assoc_remain_done(struct aead_request *req, int err)
+{
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
        struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
        crypto_completion_t complete;
@@ -350,15 +369,21 @@ static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq,
        }
 
        if (remain)
-               gcm_hash_crypt_done(areq, err);
+               __gcm_hash_crypt_done(req, err);
        else
-               gcm_hash_crypt_remain_done(areq, err);
+               __gcm_hash_crypt_remain_done(req, err);
 }
 
-static void gcm_hash_assoc_done(struct crypto_async_request *areq,
-                               int err)
+static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq,
+                                      int err)
 {
        struct aead_request *req = areq->data;
+
+       __gcm_hash_assoc_remain_done(req, err);
+}
+
+static void __gcm_hash_assoc_done(struct aead_request *req, int err)
+{
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
        unsigned int remain;
 
@@ -371,13 +396,18 @@ static void gcm_hash_assoc_done(struct crypto_async_request *areq,
                        return;
        }
 
-       gcm_hash_assoc_remain_done(areq, err);
+       __gcm_hash_assoc_remain_done(req, err);
 }
 
-static void gcm_hash_init_done(struct crypto_async_request *areq,
-                              int err)
+static void gcm_hash_assoc_done(struct crypto_async_request *areq, int err)
 {
        struct aead_request *req = areq->data;
+
+       __gcm_hash_assoc_done(req, err);
+}
+
+static void __gcm_hash_init_done(struct aead_request *req, int err)
+{
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
        crypto_completion_t complete;
        unsigned int remain = 0;
@@ -393,9 +423,16 @@ static void gcm_hash_init_done(struct crypto_async_request *areq,
        }
 
        if (remain)
-               gcm_hash_assoc_done(areq, err);
+               __gcm_hash_assoc_done(req, err);
        else
-               gcm_hash_assoc_remain_done(areq, err);
+               __gcm_hash_assoc_remain_done(req, err);
+}
+
+static void gcm_hash_init_done(struct crypto_async_request *areq, int err)
+{
+       struct aead_request *req = areq->data;
+
+       __gcm_hash_init_done(req, err);
 }
 
 static int gcm_hash(struct aead_request *req,
@@ -457,10 +494,8 @@ static void gcm_enc_copy_hash(struct aead_request *req,
                                 crypto_aead_authsize(aead), 1);
 }
 
-static void gcm_enc_hash_done(struct crypto_async_request *areq,
-                                    int err)
+static void gcm_enc_hash_done(struct aead_request *req, int err)
 {
-       struct aead_request *req = areq->data;
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
 
        if (!err)
@@ -469,8 +504,7 @@ static void gcm_enc_hash_done(struct crypto_async_request *areq,
        aead_request_complete(req, err);
 }
 
-static void gcm_encrypt_done(struct crypto_async_request *areq,
-                                    int err)
+static void gcm_encrypt_done(struct crypto_async_request *areq, int err)
 {
        struct aead_request *req = areq->data;
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
@@ -479,9 +513,13 @@ static void gcm_encrypt_done(struct crypto_async_request *areq,
                err = gcm_hash(req, pctx);
                if (err == -EINPROGRESS || err == -EBUSY)
                        return;
+               else if (!err) {
+                       crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16);
+                       gcm_enc_copy_hash(req, pctx);
+               }
        }
 
-       gcm_enc_hash_done(areq, err);
+       aead_request_complete(req, err);
 }
 
 static int crypto_gcm_encrypt(struct aead_request *req)
@@ -538,9 +576,8 @@ static void gcm_decrypt_done(struct crypto_async_request *areq, int err)
        aead_request_complete(req, err);
 }
 
-static void gcm_dec_hash_done(struct crypto_async_request *areq, int err)
+static void gcm_dec_hash_done(struct aead_request *req, int err)
 {
-       struct aead_request *req = areq->data;
        struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req);
        struct ablkcipher_request *abreq = &pctx->u.abreq;
        struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx;
@@ -552,9 +589,11 @@ static void gcm_dec_hash_done(struct crypto_async_request *areq, int err)
                err = crypto_ablkcipher_decrypt(abreq);
                if (err == -EINPROGRESS || err == -EBUSY)
                        return;
+               else if (!err)
+                       err = crypto_gcm_verify(req, pctx);
        }
 
-       gcm_decrypt_done(areq, err);
+       aead_request_complete(req, err);
 }
 
 static int crypto_gcm_decrypt(struct aead_request *req)
index cd80d1d..57bdaf6 100644 (file)
@@ -203,8 +203,9 @@ static const union acpi_predefined_info predefined_names[] =
        {{"_BCT", 1, ACPI_RTYPE_INTEGER}},
        {{"_BDN", 0, ACPI_RTYPE_INTEGER}},
        {{"_BFS", 1, 0}},
-       {{"_BIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (9 Int),(4 Str) */
-                         {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, ACPI_RTYPE_STRING}, 4,0}},
+       {{"_BIF", 0, ACPI_RTYPE_PACKAGE} }, /* Fixed-length (9 Int),(4 Str/Buf) */
+                         {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9,
+                            ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER}, 4, 0} },
 
        {{"_BIX", 0, ACPI_RTYPE_PACKAGE}},      /* Fixed-length (16 Int),(4 Str) */
        {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING}, 4,
index e56b2a7..23e5a05 100644 (file)
@@ -224,6 +224,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
         * _OSI(Linux) helps sound
         * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"),
         * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"),
+        * T400, T500
         * _OSI(Linux) has Linux specific hooks
         * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"),
         * _OSI(Linux) is a NOP:
@@ -254,6 +255,22 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"),
                },
        },
+       {
+       .callback = dmi_enable_osi_linux,
+       .ident = "Lenovo ThinkPad T400",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                    DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T400"),
+               },
+       },
+       {
+       .callback = dmi_enable_osi_linux,
+       .ident = "Lenovo ThinkPad T500",
+       .matches = {
+                    DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                    DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"),
+               },
+       },
        {}
 };
 
index 4cc1b81..5f2c379 100644 (file)
@@ -430,6 +430,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
        },
        {
        .callback = init_set_sci_en_on_resume,
+       .ident = "Hewlett-Packard Compaq Presario C700 Notebook PC",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario C700 Notebook PC"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
        .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC",
        .matches = {
                DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
index d344db4..172b57e 100644 (file)
@@ -707,34 +707,17 @@ static unsigned int sata_fsl_dev_classify(struct ata_port *ap)
        return ata_dev_classify(&tf);
 }
 
-static int sata_fsl_prereset(struct ata_link *link, unsigned long deadline)
-{
-       /* FIXME: Never skip softreset, sata_fsl_softreset() is
-        * combination of soft and hard resets.  sata_fsl_softreset()
-        * needs to be splitted into soft and hard resets.
-        */
-       return 0;
-}
-
-static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
+static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class,
                                        unsigned long deadline)
 {
        struct ata_port *ap = link->ap;
-       struct sata_fsl_port_priv *pp = ap->private_data;
        struct sata_fsl_host_priv *host_priv = ap->host->private_data;
        void __iomem *hcr_base = host_priv->hcr_base;
-       int pmp = sata_srst_pmp(link);
        u32 temp;
-       struct ata_taskfile tf;
-       u8 *cfis;
-       u32 Serror;
        int i = 0;
        unsigned long start_jiffies;
 
-       DPRINTK("in xx_softreset\n");
-
-       if (pmp != SATA_PMP_CTRL_PORT)
-               goto issue_srst;
+       DPRINTK("in xx_hardreset\n");
 
 try_offline_again:
        /*
@@ -749,7 +732,7 @@ try_offline_again:
 
        if (temp & ONLINE) {
                ata_port_printk(ap, KERN_ERR,
-                               "Softreset failed, not off-lined %d\n", i);
+                               "Hardreset failed, not off-lined %d\n", i);
 
                /*
                 * Try to offline controller atleast twice
@@ -761,7 +744,7 @@ try_offline_again:
                        goto try_offline_again;
        }
 
-       DPRINTK("softreset, controller off-lined\n");
+       DPRINTK("hardreset, controller off-lined\n");
        VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
        VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
 
@@ -786,11 +769,11 @@ try_offline_again:
 
        if (!(temp & ONLINE)) {
                ata_port_printk(ap, KERN_ERR,
-                               "Softreset failed, not on-lined\n");
+                               "Hardreset failed, not on-lined\n");
                goto err;
        }
 
-       DPRINTK("softreset, controller off-lined & on-lined\n");
+       DPRINTK("hardreset, controller off-lined & on-lined\n");
        VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS));
        VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL));
 
@@ -806,7 +789,7 @@ try_offline_again:
                                "No Device OR PHYRDY change,Hstatus = 0x%x\n",
                                ioread32(hcr_base + HSTATUS));
                *class = ATA_DEV_NONE;
-               goto out;
+               return 0;
        }
 
        /*
@@ -819,11 +802,44 @@ try_offline_again:
        if ((temp & 0xFF) != 0x18) {
                ata_port_printk(ap, KERN_WARNING, "No Signature Update\n");
                *class = ATA_DEV_NONE;
-               goto out;
+               goto do_followup_srst;
        } else {
                ata_port_printk(ap, KERN_INFO,
                                "Signature Update detected @ %d msecs\n",
                                jiffies_to_msecs(jiffies - start_jiffies));
+               *class = sata_fsl_dev_classify(ap);
+               return 0;
+       }
+
+do_followup_srst:
+       /*
+        * request libATA to perform follow-up softreset
+        */
+       return -EAGAIN;
+
+err:
+       return -EIO;
+}
+
+static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
+                                       unsigned long deadline)
+{
+       struct ata_port *ap = link->ap;
+       struct sata_fsl_port_priv *pp = ap->private_data;
+       struct sata_fsl_host_priv *host_priv = ap->host->private_data;
+       void __iomem *hcr_base = host_priv->hcr_base;
+       int pmp = sata_srst_pmp(link);
+       u32 temp;
+       struct ata_taskfile tf;
+       u8 *cfis;
+       u32 Serror;
+
+       DPRINTK("in xx_softreset\n");
+
+       if (ata_link_offline(link)) {
+               DPRINTK("PHY reports no device\n");
+               *class = ATA_DEV_NONE;
+               return 0;
        }
 
        /*
@@ -834,7 +850,6 @@ try_offline_again:
         * reached here, we can send a command to the target device
         */
 
-issue_srst:
        DPRINTK("Sending SRST/device reset\n");
 
        ata_tf_init(link->device, &tf);
@@ -860,6 +875,8 @@ issue_srst:
                ioread32(CA + hcr_base), ioread32(CC + hcr_base));
 
        iowrite32(0xFFFF, CC + hcr_base);
+       if (pmp != SATA_PMP_CTRL_PORT)
+               iowrite32(pmp, CQPMP + hcr_base);
        iowrite32(1, CQ + hcr_base);
 
        temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000);
@@ -926,7 +943,6 @@ issue_srst:
                VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE));
        }
 
-out:
        return 0;
 
 err:
@@ -988,18 +1004,6 @@ static void sata_fsl_error_intr(struct ata_port *ap)
                ehi->err_mask |= AC_ERR_ATA_BUS;
                ehi->action |= ATA_EH_SOFTRESET;
 
-               /*
-                * Ignore serror in case of fatal errors as we always want
-                * to do a soft-reset of the FSL SATA controller. Analyzing
-                * serror may cause libata to schedule a hard-reset action,
-                * and hard-reset currently does not do controller
-                * offline/online, causing command timeouts and leads to an
-                * un-recoverable state, hence make libATA ignore
-                * autopsy in case of fatal errors.
-                */
-
-               ehi->flags |= ATA_EHI_NO_AUTOPSY;
-
                freeze = 1;
        }
 
@@ -1267,8 +1271,8 @@ static struct ata_port_operations sata_fsl_ops = {
 
        .freeze = sata_fsl_freeze,
        .thaw = sata_fsl_thaw,
-       .prereset = sata_fsl_prereset,
        .softreset = sata_fsl_softreset,
+       .hardreset = sata_fsl_hardreset,
        .pmp_softreset = sata_fsl_softreset,
        .error_handler = sata_fsl_error_handler,
        .post_internal_cmd = sata_fsl_post_internal_cmd,
index a770498..846d89e 100644 (file)
@@ -328,11 +328,11 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)
                 * necessary.
                 */
                parent = dev->parent;
-               spin_unlock_irq(&dev->power.lock);
+               spin_unlock(&dev->power.lock);
 
                pm_runtime_get_noresume(parent);
 
-               spin_lock_irq(&parent->power.lock);
+               spin_lock(&parent->power.lock);
                /*
                 * We can resume if the parent's run-time PM is disabled or it
                 * is set to ignore children.
@@ -343,9 +343,9 @@ int __pm_runtime_resume(struct device *dev, bool from_wq)
                        if (parent->power.runtime_status != RPM_ACTIVE)
                                retval = -EBUSY;
                }
-               spin_unlock_irq(&parent->power.lock);
+               spin_unlock(&parent->power.lock);
 
-               spin_lock_irq(&dev->power.lock);
+               spin_lock(&dev->power.lock);
                if (retval)
                        goto out;
                goto repeat;
@@ -777,7 +777,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
        }
 
        if (parent) {
-               spin_lock_irq(&parent->power.lock);
+               spin_lock(&parent->power.lock);
 
                /*
                 * It is invalid to put an active child under a parent that is
@@ -793,7 +793,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status)
                                atomic_inc(&parent->power.child_count);
                }
 
-               spin_unlock_irq(&parent->power.lock);
+               spin_unlock(&parent->power.lock);
 
                if (error)
                        goto out;
index 6399e50..92b1263 100644 (file)
@@ -482,7 +482,7 @@ static ssize_t host_store_rescan(struct device *dev,
 
        return count;
 }
-DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
+static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan);
 
 static ssize_t dev_show_unique_id(struct device *dev,
                                 struct device_attribute *attr,
@@ -512,7 +512,7 @@ static ssize_t dev_show_unique_id(struct device *dev,
                                sn[8], sn[9], sn[10], sn[11],
                                sn[12], sn[13], sn[14], sn[15]);
 }
-DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL);
+static DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL);
 
 static ssize_t dev_show_vendor(struct device *dev,
                               struct device_attribute *attr,
@@ -536,7 +536,7 @@ static ssize_t dev_show_vendor(struct device *dev,
        else
                return snprintf(buf, sizeof(vendor) + 1, "%s\n", drv->vendor);
 }
-DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL);
+static DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL);
 
 static ssize_t dev_show_model(struct device *dev,
                              struct device_attribute *attr,
@@ -560,7 +560,7 @@ static ssize_t dev_show_model(struct device *dev,
        else
                return snprintf(buf, sizeof(model) + 1, "%s\n", drv->model);
 }
-DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL);
+static DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL);
 
 static ssize_t dev_show_rev(struct device *dev,
                            struct device_attribute *attr,
@@ -584,7 +584,7 @@ static ssize_t dev_show_rev(struct device *dev,
        else
                return snprintf(buf, sizeof(rev) + 1, "%s\n", drv->rev);
 }
-DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL);
+static DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL);
 
 static ssize_t cciss_show_lunid(struct device *dev,
                                struct device_attribute *attr, char *buf)
@@ -609,7 +609,7 @@ static ssize_t cciss_show_lunid(struct device *dev,
                lunid[0], lunid[1], lunid[2], lunid[3],
                lunid[4], lunid[5], lunid[6], lunid[7]);
 }
-DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL);
+static DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL);
 
 static ssize_t cciss_show_raid_level(struct device *dev,
                                     struct device_attribute *attr, char *buf)
@@ -632,7 +632,7 @@ static ssize_t cciss_show_raid_level(struct device *dev,
        return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n",
                        raid_label[raid]);
 }
-DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL);
+static DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL);
 
 static ssize_t cciss_show_usage_count(struct device *dev,
                                      struct device_attribute *attr, char *buf)
@@ -651,7 +651,7 @@ static ssize_t cciss_show_usage_count(struct device *dev,
        spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
        return snprintf(buf, 20, "%d\n", count);
 }
-DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
+static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL);
 
 static struct attribute *cciss_host_attrs[] = {
        &dev_attr_rescan.attr,
index 10e1f03..3cb56a0 100644 (file)
@@ -62,6 +62,7 @@
 #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG     0x0042
 #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB     0x0044
 #define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB            0x0062
+#define PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB    0x006a
 #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG     0x0046
 
 /* cover 915 and 945 variants */
@@ -96,7 +97,8 @@
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \
                agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \
-               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB)
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB || \
+               agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB)
 
 extern int agp_memory_reserved;
 
@@ -1358,6 +1360,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
        case PCI_DEVICE_ID_INTEL_IGDNG_D_HB:
        case PCI_DEVICE_ID_INTEL_IGDNG_M_HB:
        case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB:
+       case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB:
                *gtt_offset = *gtt_size = MB(2);
                break;
        default:
@@ -2359,6 +2362,8 @@ static const struct intel_driver_description {
            "IGDNG/M", NULL, &intel_i965_driver },
        { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
            "IGDNG/MA", NULL, &intel_i965_driver },
+       { PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
+           "IGDNG/MC2", NULL, &intel_i965_driver },
        { 0, 0, 0, NULL, NULL, NULL }
 };
 
@@ -2560,6 +2565,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
        ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
        ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
        ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
+       ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB),
        { }
 };
 
index 737be95..950837c 100644 (file)
@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
 
        if (keycode >= NR_KEYS)
                if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
-                       keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1);
+                       keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
                else
                        return;
        else
index a9952b1..84c51e1 100644 (file)
@@ -236,7 +236,7 @@ static inline void ecb_crypt(const u8 *in, u8 *out, u32 *key,
        /* Padlock in ECB mode fetches at least ecb_fetch_bytes of data.
         * We could avoid some copying here but it's probably not worth it.
         */
-       if (unlikely(((unsigned long)in & PAGE_SIZE) + ecb_fetch_bytes > PAGE_SIZE)) {
+       if (unlikely(((unsigned long)in & ~PAGE_MASK) + ecb_fetch_bytes > PAGE_SIZE)) {
                ecb_crypt_copy(in, out, key, cword, count);
                return;
        }
@@ -248,7 +248,7 @@ static inline u8 *cbc_crypt(const u8 *in, u8 *out, u32 *key,
                            u8 *iv, struct cword *cword, int count)
 {
        /* Padlock in CBC mode fetches at least cbc_fetch_bytes of data. */
-       if (unlikely(((unsigned long)in & PAGE_SIZE) + cbc_fetch_bytes > PAGE_SIZE))
+       if (unlikely(((unsigned long)in & ~PAGE_MASK) + cbc_fetch_bytes > PAGE_SIZE))
                return cbc_crypt_copy(in, out, key, iv, cword, count);
 
        return rep_xcrypt_cbc(in, out, key, iv, cword, count);
index 5903a88..eb140ff 100644 (file)
@@ -26,6 +26,8 @@ config INTEL_IOATDMA
        select DMA_ENGINE
        select DCA
        select ASYNC_TX_DISABLE_CHANNEL_SWITCH
+       select ASYNC_TX_DISABLE_PQ_VAL_DMA
+       select ASYNC_TX_DISABLE_XOR_VAL_DMA
        help
          Enable support for the Intel(R) I/OAT DMA engine present
          in recent Intel Xeon chipsets.
@@ -52,7 +54,7 @@ config DW_DMAC
 
 config AT_HDMAC
        tristate "Atmel AHB DMA support"
-       depends on ARCH_AT91SAM9RL
+       depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
        select DMA_ENGINE
        help
          Support the Atmel AHB DMA controller.  This can be integrated in
index bd0b248..8f99354 100644 (file)
@@ -632,11 +632,21 @@ static bool device_has_all_tx_types(struct dma_device *device)
        #if defined(CONFIG_ASYNC_XOR) || defined(CONFIG_ASYNC_XOR_MODULE)
        if (!dma_has_cap(DMA_XOR, device->cap_mask))
                return false;
+
+       #ifndef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
+       if (!dma_has_cap(DMA_XOR_VAL, device->cap_mask))
+               return false;
+       #endif
        #endif
 
        #if defined(CONFIG_ASYNC_PQ) || defined(CONFIG_ASYNC_PQ_MODULE)
        if (!dma_has_cap(DMA_PQ, device->cap_mask))
                return false;
+
+       #ifndef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
+       if (!dma_has_cap(DMA_PQ_VAL, device->cap_mask))
+               return false;
+       #endif
        #endif
 
        return true;
index 69d0261..abd9038 100644 (file)
@@ -98,17 +98,17 @@ static int dca_enabled_in_bios(struct pci_dev *pdev)
        cpuid_level_9 = cpuid_eax(9);
        res = test_bit(0, &cpuid_level_9);
        if (!res)
-               dev_err(&pdev->dev, "DCA is disabled in BIOS\n");
+               dev_dbg(&pdev->dev, "DCA is disabled in BIOS\n");
 
        return res;
 }
 
-static int system_has_dca_enabled(struct pci_dev *pdev)
+int system_has_dca_enabled(struct pci_dev *pdev)
 {
        if (boot_cpu_has(X86_FEATURE_DCA))
                return dca_enabled_in_bios(pdev);
 
-       dev_err(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n");
+       dev_dbg(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n");
        return 0;
 }
 
index c14fdfe..45edde9 100644 (file)
@@ -297,9 +297,7 @@ static inline bool is_ioat_suspended(unsigned long status)
 /* channel was fatally programmed */
 static inline bool is_ioat_bug(unsigned long err)
 {
-       return !!(err & (IOAT_CHANERR_SRC_ADDR_ERR|IOAT_CHANERR_DEST_ADDR_ERR|
-                        IOAT_CHANERR_NEXT_ADDR_ERR|IOAT_CHANERR_CONTROL_ERR|
-                        IOAT_CHANERR_LENGTH_ERR));
+       return !!err;
 }
 
 static inline void ioat_unmap(struct pci_dev *pdev, dma_addr_t addr, size_t len,
index 96ffab7..8f1f7f0 100644 (file)
@@ -279,6 +279,8 @@ void ioat2_timer_event(unsigned long data)
                        u32 chanerr;
 
                        chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+                       dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
+                               __func__, chanerr);
                        BUG_ON(is_ioat_bug(chanerr));
                }
 
index 35d1e33..42f6f10 100644 (file)
@@ -378,6 +378,8 @@ static void ioat3_timer_event(unsigned long data)
                        u32 chanerr;
 
                        chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+                       dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
+                               __func__, chanerr);
                        BUG_ON(is_ioat_bug(chanerr));
                }
 
@@ -569,7 +571,7 @@ __ioat3_prep_xor_lock(struct dma_chan *c, enum sum_check_flags *result,
        dump_desc_dbg(ioat, compl_desc);
 
        /* we leave the channel locked to ensure in order submission */
-       return &desc->txd;
+       return &compl_desc->txd;
 }
 
 static struct dma_async_tx_descriptor *
@@ -728,7 +730,7 @@ __ioat3_prep_pq_lock(struct dma_chan *c, enum sum_check_flags *result,
        dump_desc_dbg(ioat, compl_desc);
 
        /* we leave the channel locked to ensure in order submission */
-       return &desc->txd;
+       return &compl_desc->txd;
 }
 
 static struct dma_async_tx_descriptor *
@@ -736,10 +738,16 @@ ioat3_prep_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src,
              unsigned int src_cnt, const unsigned char *scf, size_t len,
              unsigned long flags)
 {
+       /* specify valid address for disabled result */
+       if (flags & DMA_PREP_PQ_DISABLE_P)
+               dst[0] = dst[1];
+       if (flags & DMA_PREP_PQ_DISABLE_Q)
+               dst[1] = dst[0];
+
        /* handle the single source multiply case from the raid6
         * recovery path
         */
-       if (unlikely((flags & DMA_PREP_PQ_DISABLE_P) && src_cnt == 1)) {
+       if ((flags & DMA_PREP_PQ_DISABLE_P) && src_cnt == 1) {
                dma_addr_t single_source[2];
                unsigned char single_source_coef[2];
 
@@ -761,6 +769,12 @@ ioat3_prep_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src,
                  unsigned int src_cnt, const unsigned char *scf, size_t len,
                  enum sum_check_flags *pqres, unsigned long flags)
 {
+       /* specify valid address for disabled result */
+       if (flags & DMA_PREP_PQ_DISABLE_P)
+               pq[0] = pq[1];
+       if (flags & DMA_PREP_PQ_DISABLE_Q)
+               pq[1] = pq[0];
+
        /* the cleanup routine only sets bits on validate failure, it
         * does not clear bits on validate success... so clear it here
         */
@@ -778,9 +792,9 @@ ioat3_prep_pqxor(struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src,
        dma_addr_t pq[2];
 
        memset(scf, 0, src_cnt);
-       flags |= DMA_PREP_PQ_DISABLE_Q;
        pq[0] = dst;
-       pq[1] = ~0;
+       flags |= DMA_PREP_PQ_DISABLE_Q;
+       pq[1] = dst; /* specify valid address for disabled result */
 
        return __ioat3_prep_pq_lock(chan, NULL, pq, src, src_cnt, scf, len,
                                    flags);
@@ -800,9 +814,9 @@ ioat3_prep_pqxor_val(struct dma_chan *chan, dma_addr_t *src,
        *result = 0;
 
        memset(scf, 0, src_cnt);
-       flags |= DMA_PREP_PQ_DISABLE_Q;
        pq[0] = src[0];
-       pq[1] = ~0;
+       flags |= DMA_PREP_PQ_DISABLE_Q;
+       pq[1] = pq[0]; /* specify valid address for disabled result */
 
        return __ioat3_prep_pq_lock(chan, result, pq, &src[1], src_cnt - 1, scf,
                                    len, flags);
@@ -1117,6 +1131,7 @@ static int __devinit ioat3_dma_self_test(struct ioatdma_device *device)
 int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
 {
        struct pci_dev *pdev = device->pdev;
+       int dca_en = system_has_dca_enabled(pdev);
        struct dma_device *dma;
        struct dma_chan *c;
        struct ioat_chan_common *chan;
@@ -1137,6 +1152,11 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
        dma->device_prep_dma_interrupt = ioat3_prep_interrupt_lock;
 
        cap = readl(device->reg_base + IOAT_DMA_CAP_OFFSET);
+
+       /* dca is incompatible with raid operations */
+       if (dca_en && (cap & (IOAT_CAP_XOR|IOAT_CAP_PQ)))
+               cap &= ~(IOAT_CAP_XOR|IOAT_CAP_PQ);
+
        if (cap & IOAT_CAP_XOR) {
                is_raid_device = true;
                dma->max_xor = 8;
@@ -1186,6 +1206,16 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
                device->timer_fn = ioat2_timer_event;
        }
 
+       #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA
+       dma_cap_clear(DMA_PQ_VAL, dma->cap_mask);
+       dma->device_prep_dma_pq_val = NULL;
+       #endif
+
+       #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA
+       dma_cap_clear(DMA_XOR_VAL, dma->cap_mask);
+       dma->device_prep_dma_xor_val = NULL;
+       #endif
+
        /* -= IOAT ver.3 workarounds =- */
        /* Write CHANERRMSK_INT with 3E07h to mask out the errors
         * that can cause stability issues for IOAT ver.3
index 99afb12..60e6754 100644 (file)
@@ -39,6 +39,8 @@
 #define IOAT_VER_3_0            0x30    /* Version 3.0 */
 #define IOAT_VER_3_2            0x32    /* Version 3.2 */
 
+int system_has_dca_enabled(struct pci_dev *pdev);
+
 struct ioat_dma_descriptor {
        uint32_t        size;
        union {
index 63038e1..f015ec1 100644 (file)
@@ -92,9 +92,7 @@
 #define IOAT_CHANCTRL_ERR_COMPLETION_EN                0x0004
 #define IOAT_CHANCTRL_INT_REARM                        0x0001
 #define IOAT_CHANCTRL_RUN                      (IOAT_CHANCTRL_INT_REARM |\
-                                                IOAT_CHANCTRL_ERR_COMPLETION_EN |\
-                                                IOAT_CHANCTRL_ANY_ERR_ABORT_EN |\
-                                                IOAT_CHANCTRL_ERR_INT_EN)
+                                                IOAT_CHANCTRL_ANY_ERR_ABORT_EN)
 
 #define IOAT_DMA_COMP_OFFSET                   0x02    /* 16-bit DMA channel compatibility */
 #define IOAT_DMA_COMP_V1                       0x0001  /* Compatibility with DMA version 1 */
index b3b065c..034ecf0 100644 (file)
@@ -640,17 +640,16 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
 #endif
        struct sh_dmae_device *shdev;
 
+       /* get platform data */
+       if (!pdev->dev.platform_data)
+               return -ENODEV;
+
        shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL);
        if (!shdev) {
                dev_err(&pdev->dev, "No enough memory\n");
-               err = -ENOMEM;
-               goto shdev_err;
+               return -ENOMEM;
        }
 
-       /* get platform data */
-       if (!pdev->dev.platform_data)
-               goto shdev_err;
-
        /* platform data */
        memcpy(&shdev->pdata, pdev->dev.platform_data,
                        sizeof(struct sh_dmae_pdata));
@@ -722,7 +721,6 @@ eirq_err:
 rst_err:
        kfree(shdev);
 
-shdev_err:
        return err;
 }
 
index 5d52425..94260aa 100644 (file)
@@ -275,7 +275,7 @@ static void log_irqs(u32 evt)
            !(evt & OHCI1394_busReset))
                return;
 
-       fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
+       fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt,
            evt & OHCI1394_selfIDComplete       ? " selfID"             : "",
            evt & OHCI1394_RQPkt                ? " AR_req"             : "",
            evt & OHCI1394_RSPkt                ? " AR_resp"            : "",
@@ -286,6 +286,7 @@ static void log_irqs(u32 evt)
            evt & OHCI1394_postedWriteErr       ? " postedWriteErr"     : "",
            evt & OHCI1394_cycleTooLong         ? " cycleTooLong"       : "",
            evt & OHCI1394_cycle64Seconds       ? " cycle64Seconds"     : "",
+           evt & OHCI1394_cycleInconsistent    ? " cycleInconsistent"  : "",
            evt & OHCI1394_regAccessFail        ? " regAccessFail"      : "",
            evt & OHCI1394_busReset             ? " busReset"           : "",
            evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt |
@@ -293,6 +294,7 @@ static void log_irqs(u32 evt)
                    OHCI1394_respTxComplete | OHCI1394_isochRx |
                    OHCI1394_isochTx | OHCI1394_postedWriteErr |
                    OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds |
+                   OHCI1394_cycleInconsistent |
                    OHCI1394_regAccessFail | OHCI1394_busReset)
                                                ? " ?"                  : "");
 }
@@ -1439,6 +1441,17 @@ static irqreturn_t irq_handler(int irq, void *data)
                          OHCI1394_LinkControl_cycleMaster);
        }
 
+       if (unlikely(event & OHCI1394_cycleInconsistent)) {
+               /*
+                * We need to clear this event bit in order to make
+                * cycleMatch isochronous I/O work.  In theory we should
+                * stop active cycleMatch iso contexts now and restart
+                * them at least two cycles later.  (FIXME?)
+                */
+               if (printk_ratelimit())
+                       fw_notify("isochronous cycle inconsistent\n");
+       }
+
        if (event & OHCI1394_cycle64Seconds) {
                cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer);
                if ((cycle_time & 0x80000000) == 0)
@@ -1528,6 +1541,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length)
                  OHCI1394_reqTxComplete | OHCI1394_respTxComplete |
                  OHCI1394_isochRx | OHCI1394_isochTx |
                  OHCI1394_postedWriteErr | OHCI1394_cycleTooLong |
+                 OHCI1394_cycleInconsistent |
                  OHCI1394_cycle64Seconds | OHCI1394_regAccessFail |
                  OHCI1394_masterIntEnable);
        if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS)
@@ -1890,15 +1904,30 @@ static int handle_it_packet(struct context *context,
 {
        struct iso_context *ctx =
                container_of(context, struct iso_context, context);
+       int i;
+       struct descriptor *pd;
 
-       if (last->transfer_status == 0)
-               /* This descriptor isn't done yet, stop iteration. */
+       for (pd = d; pd <= last; pd++)
+               if (pd->transfer_status)
+                       break;
+       if (pd > last)
+               /* Descriptor(s) not done yet, stop iteration */
                return 0;
 
-       if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS)
+       i = ctx->header_length;
+       if (i + 4 < PAGE_SIZE) {
+               /* Present this value as big-endian to match the receive code */
+               *(__be32 *)(ctx->header + i) = cpu_to_be32(
+                               ((u32)le16_to_cpu(pd->transfer_status) << 16) |
+                               le16_to_cpu(pd->res_count));
+               ctx->header_length += 4;
+       }
+       if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) {
                ctx->base.callback(&ctx->base, le16_to_cpu(last->res_count),
-                                  0, NULL, ctx->base.callback_data);
-
+                                  ctx->header_length, ctx->header,
+                                  ctx->base.callback_data);
+               ctx->header_length = 0;
+       }
        return 1;
 }
 
index f831ea1..96eddd1 100644 (file)
@@ -92,6 +92,7 @@ config DRM_I830
 config DRM_I915
        tristate "i915 driver"
        depends on AGP_INTEL
+       select SHMEM
        select DRM_KMS_HELPER
        select FB_CFB_FILLRECT
        select FB_CFB_COPYAREA
index cea665d..b54ba63 100644 (file)
@@ -662,6 +662,12 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
                return NULL;
        }
 
+       /* Some EDIDs have bogus h/vtotal values */
+       if (mode->hsync_end > mode->htotal)
+               mode->htotal = mode->hsync_end + 1;
+       if (mode->vsync_end > mode->vtotal)
+               mode->vtotal = mode->vsync_end + 1;
+
        drm_mode_set_name(mode);
 
        if (pt->misc & DRM_EDID_PT_INTERLACED)
index dc8e374..65ef011 100644 (file)
@@ -599,7 +599,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
        struct drm_framebuffer *fb = fb_helper->fb;
        int depth;
 
-       if (var->pixclock == -1 || !var->pixclock)
+       if (var->pixclock != 0)
                return -EINVAL;
 
        /* Need to resize the fb object !!! */
@@ -691,7 +691,7 @@ int drm_fb_helper_set_par(struct fb_info *info)
        int ret;
        int i;
 
-       if (var->pixclock != -1) {
+       if (var->pixclock != 0) {
                DRM_ERROR("PIXEL CLCOK SET\n");
                return -EINVAL;
        }
@@ -904,7 +904,7 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
        fb_helper->fb = fb;
 
        if (new_fb) {
-               info->var.pixclock = -1;
+               info->var.pixclock = 0;
                if (register_framebuffer(info) < 0)
                        return -EINVAL;
        } else {
index 8039199..e9dbb48 100644 (file)
@@ -552,7 +552,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
        vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
        vma->vm_ops = obj->dev->driver->gem_vm_ops;
        vma->vm_private_data = map->handle;
-       vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+       vma->vm_page_prot =  pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
 
        /* Take a ref for this mapping of the object, so that the fault
         * handler can dereference the mmap offset's pointer to the object.
index c861d80..97dc5a4 100644 (file)
@@ -103,6 +103,11 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic)
        return child;
 }
 
+/* drm_mm_pre_get() - pre allocate drm_mm_node structure
+ * drm_mm:     memory manager struct we are pre-allocating for
+ *
+ * Returns 0 on success or -ENOMEM if allocation fails.
+ */
 int drm_mm_pre_get(struct drm_mm *mm)
 {
        struct drm_mm_node *node;
@@ -253,12 +258,14 @@ void drm_mm_put_block(struct drm_mm_node *cur)
                                prev_node->size += next_node->size;
                                list_del(&next_node->ml_entry);
                                list_del(&next_node->fl_entry);
+                               spin_lock(&mm->unused_lock);
                                if (mm->num_unused < MM_UNUSED_TARGET) {
                                        list_add(&next_node->fl_entry,
                                                 &mm->unused_nodes);
                                        ++mm->num_unused;
                                } else
                                        kfree(next_node);
+                               spin_unlock(&mm->unused_lock);
                        } else {
                                next_node->size += cur->size;
                                next_node->start = cur->start;
@@ -271,11 +278,13 @@ void drm_mm_put_block(struct drm_mm_node *cur)
                list_add(&cur->fl_entry, &mm->fl_entry);
        } else {
                list_del(&cur->ml_entry);
+               spin_lock(&mm->unused_lock);
                if (mm->num_unused < MM_UNUSED_TARGET) {
                        list_add(&cur->fl_entry, &mm->unused_nodes);
                        ++mm->num_unused;
                } else
                        kfree(cur);
+               spin_unlock(&mm->unused_lock);
        }
 }
 
index f8ce9a3..26bf055 100644 (file)
@@ -267,10 +267,10 @@ static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_co
        uint32_t *mem;
 
        for (page = 0; page < page_count; page++) {
-               mem = kmap(pages[page]);
+               mem = kmap_atomic(pages[page], KM_USER0);
                for (i = 0; i < PAGE_SIZE; i += 4)
                        seq_printf(m, "%08x :  %08x\n", i, mem[i / 4]);
-               kunmap(pages[page]);
+               kunmap_atomic(pages[page], KM_USER0);
        }
 }
 
index 57204e2..a725f65 100644 (file)
@@ -296,6 +296,7 @@ typedef struct drm_i915_private {
        u32 saveVBLANK_A;
        u32 saveVSYNC_A;
        u32 saveBCLRPAT_A;
+       u32 saveTRANSACONF;
        u32 saveTRANS_HTOTAL_A;
        u32 saveTRANS_HBLANK_A;
        u32 saveTRANS_HSYNC_A;
@@ -326,6 +327,7 @@ typedef struct drm_i915_private {
        u32 saveVBLANK_B;
        u32 saveVSYNC_B;
        u32 saveBCLRPAT_B;
+       u32 saveTRANSBCONF;
        u32 saveTRANS_HTOTAL_B;
        u32 saveTRANS_HBLANK_B;
        u32 saveTRANS_HSYNC_B;
@@ -414,6 +416,16 @@ typedef struct drm_i915_private {
        u32 savePFB_WIN_SZ;
        u32 savePFA_WIN_POS;
        u32 savePFB_WIN_POS;
+       u32 savePCH_DREF_CONTROL;
+       u32 saveDISP_ARB_CTL;
+       u32 savePIPEA_DATA_M1;
+       u32 savePIPEA_DATA_N1;
+       u32 savePIPEA_LINK_M1;
+       u32 savePIPEA_LINK_N1;
+       u32 savePIPEB_DATA_M1;
+       u32 savePIPEB_DATA_N1;
+       u32 savePIPEB_LINK_M1;
+       u32 savePIPEB_LINK_N1;
 
        struct {
                struct drm_mm gtt_space;
index c3ceffa..aa7fd82 100644 (file)
@@ -254,10 +254,15 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
        int ret = IRQ_NONE;
-       u32 de_iir, gt_iir;
+       u32 de_iir, gt_iir, de_ier;
        u32 new_de_iir, new_gt_iir;
        struct drm_i915_master_private *master_priv;
 
+       /* disable master interrupt before clearing iir  */
+       de_ier = I915_READ(DEIER);
+       I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
+       (void)I915_READ(DEIER);
+
        de_iir = I915_READ(DEIIR);
        gt_iir = I915_READ(GTIIR);
 
@@ -290,6 +295,9 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
                gt_iir = new_gt_iir;
        }
 
+       I915_WRITE(DEIER, de_ier);
+       (void)I915_READ(DEIER);
+
        return ret;
 }
 
index 992d561..6eec817 100644 (file)
@@ -239,6 +239,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
        if (drm_core_check_feature(dev, DRIVER_MODESET))
                return;
 
+       if (IS_IGDNG(dev)) {
+               dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL);
+               dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL);
+       }
+
        /* Pipe & plane A info */
        dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
        dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
@@ -263,6 +268,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
                dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
 
        if (IS_IGDNG(dev)) {
+               dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1);
+               dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1);
+               dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1);
+               dev_priv->savePIPEA_LINK_N1 = I915_READ(PIPEA_LINK_N1);
+
                dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL);
                dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL);
 
@@ -270,6 +280,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
                dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ);
                dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS);
 
+               dev_priv->saveTRANSACONF = I915_READ(TRANSACONF);
                dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A);
                dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A);
                dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A);
@@ -314,6 +325,11 @@ static void i915_save_modeset_reg(struct drm_device *dev)
                dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B);
 
        if (IS_IGDNG(dev)) {
+               dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1);
+               dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1);
+               dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1);
+               dev_priv->savePIPEB_LINK_N1 = I915_READ(PIPEB_LINK_N1);
+
                dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL);
                dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL);
 
@@ -321,6 +337,7 @@ static void i915_save_modeset_reg(struct drm_device *dev)
                dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ);
                dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS);
 
+               dev_priv->saveTRANSBCONF = I915_READ(TRANSBCONF);
                dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B);
                dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B);
                dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B);
@@ -368,6 +385,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                fpb1_reg = FPB1;
        }
 
+       if (IS_IGDNG(dev)) {
+               I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL);
+               I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL);
+       }
+
        /* Pipe & plane A info */
        /* Prime the clock */
        if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
@@ -395,6 +417,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
 
        if (IS_IGDNG(dev)) {
+               I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1);
+               I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1);
+               I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1);
+               I915_WRITE(PIPEA_LINK_N1, dev_priv->savePIPEA_LINK_N1);
+
                I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL);
                I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL);
 
@@ -402,6 +429,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ);
                I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS);
 
+               I915_WRITE(TRANSACONF, dev_priv->saveTRANSACONF);
                I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A);
                I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A);
                I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A);
@@ -439,7 +467,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
        /* Actually enable it */
        I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B);
        DRM_UDELAY(150);
-       if (IS_I965G(dev))
+       if (IS_I965G(dev) && !IS_IGDNG(dev))
                I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
        DRM_UDELAY(150);
 
@@ -454,6 +482,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
 
        if (IS_IGDNG(dev)) {
+               I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1);
+               I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1);
+               I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1);
+               I915_WRITE(PIPEB_LINK_N1, dev_priv->savePIPEB_LINK_N1);
+
                I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL);
                I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL);
 
@@ -461,6 +494,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
                I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ);
                I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS);
 
+               I915_WRITE(TRANSBCONF, dev_priv->saveTRANSBCONF);
                I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B);
                I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B);
                I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B);
index 212e227..e505144 100644 (file)
@@ -262,8 +262,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
                } while (time_after(timeout, jiffies));
        }
 
-       if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
-           CRT_HOTPLUG_MONITOR_COLOR)
+       if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) !=
+           CRT_HOTPLUG_MONITOR_NONE)
                return true;
 
        return false;
index 3ba6546..099f420 100644 (file)
@@ -863,10 +863,8 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        intel_clock_t clock;
-       int max_n;
-       bool found;
        int err_most = 47;
-       found = false;
+       int err_min = 10000;
 
        /* eDP has only 2 clock choice, no n/m/p setting */
        if (HAS_eDP)
@@ -890,10 +888,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
        }
 
        memset(best_clock, 0, sizeof(*best_clock));
-       max_n = limit->n.max;
        for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) {
                /* based on hardware requriment prefer smaller n to precision */
-               for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) {
+               for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) {
                        /* based on hardware requirment prefere larger m1,m2 */
                        for (clock.m1 = limit->m1.max;
                             clock.m1 >= limit->m1.min; clock.m1--) {
@@ -907,18 +904,18 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
                                        this_err = abs((10000 - (target*10000/clock.dot)));
                                        if (this_err < err_most) {
                                                *best_clock = clock;
-                                               err_most = this_err;
-                                               max_n = clock.n;
-                                               found = true;
                                                /* found on first matching */
                                                goto out;
+                                       } else if (this_err < err_min) {
+                                               *best_clock = clock;
+                                               err_min = this_err;
                                        }
                                }
                        }
                }
        }
 out:
-       return found;
+       return true;
 }
 
 /* DisplayPort has only two frequencies, 162MHz and 270MHz */
index 663ab6d..c33451a 100644 (file)
@@ -77,14 +77,32 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode)
        struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv;
        u32 temp;
 
-       if (mode != DRM_MODE_DPMS_ON) {
-               temp = I915_READ(hdmi_priv->sdvox_reg);
+       temp = I915_READ(hdmi_priv->sdvox_reg);
+
+       /* HW workaround, need to toggle enable bit off and on for 12bpc, but
+        * we do this anyway which shows more stable in testing.
+        */
+       if (IS_IGDNG(dev)) {
                I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE);
+               POSTING_READ(hdmi_priv->sdvox_reg);
+       }
+
+       if (mode != DRM_MODE_DPMS_ON) {
+               temp &= ~SDVO_ENABLE;
        } else {
-               temp = I915_READ(hdmi_priv->sdvox_reg);
-               I915_WRITE(hdmi_priv->sdvox_reg, temp | SDVO_ENABLE);
+               temp |= SDVO_ENABLE;
        }
+
+       I915_WRITE(hdmi_priv->sdvox_reg, temp);
        POSTING_READ(hdmi_priv->sdvox_reg);
+
+       /* HW workaround, need to write this twice for issue that may result
+        * in first write getting masked.
+        */
+       if (IS_IGDNG(dev)) {
+               I915_WRITE(hdmi_priv->sdvox_reg, temp);
+               POSTING_READ(hdmi_priv->sdvox_reg);
+       }
 }
 
 static void intel_hdmi_save(struct drm_connector *connector)
index 901befe..d67c425 100644 (file)
@@ -107,6 +107,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
                        base += 3;
                        break;
                case ATOM_IIO_WRITE:
+                       (void)ctx->card->reg_read(ctx->card, CU16(base + 1));
                        ctx->card->reg_write(ctx->card, CU16(base + 1), temp);
                        base += 3;
                        break;
index 757f5cd..224506a 100644 (file)
@@ -519,6 +519,7 @@ typedef int (*radeon_packet3_check_t)(struct radeon_cs_parser *p,
  * AGP
  */
 int radeon_agp_init(struct radeon_device *rdev);
+void radeon_agp_resume(struct radeon_device *rdev);
 void radeon_agp_fini(struct radeon_device *rdev);
 
 
index 23ea995..54bf49a 100644 (file)
@@ -237,6 +237,18 @@ int radeon_agp_init(struct radeon_device *rdev)
 #endif
 }
 
+void radeon_agp_resume(struct radeon_device *rdev)
+{
+#if __OS_HAS_AGP
+       int r;
+       if (rdev->flags & RADEON_IS_AGP) {
+               r = radeon_agp_init(rdev);
+               if (r)
+                       dev_warn(rdev->dev, "radeon AGP reinit failed\n");
+       }
+#endif
+}
+
 void radeon_agp_fini(struct radeon_device *rdev)
 {
 #if __OS_HAS_AGP
index fce4c40..29763ce 100644 (file)
@@ -566,8 +566,9 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect
                radeon_i2c_do_lock(radeon_connector, 0);
 
                if (!radeon_connector->edid) {
-                       DRM_ERROR("DDC responded but not EDID found for %s\n",
-                                 drm_get_connector_name(connector));
+                       DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
+                                       drm_get_connector_name(connector));
+                       ret = connector_status_connected;
                } else {
                        radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
 
@@ -720,8 +721,8 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
                radeon_i2c_do_lock(radeon_connector, 0);
 
                if (!radeon_connector->edid) {
-                       DRM_ERROR("DDC responded but not EDID found for %s\n",
-                                 drm_get_connector_name(connector));
+                       DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
+                                       drm_get_connector_name(connector));
                } else {
                        radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
 
@@ -1149,6 +1150,13 @@ radeon_add_legacy_connector(struct drm_device *dev,
                        if (ret)
                                goto failed;
                        radeon_connector->dac_load_detect = true;
+                       /* RS400,RC410,RS480 chipset seems to report a lot
+                        * of false positive on load detect, we haven't yet
+                        * found a way to make load detect reliable on those
+                        * chipset, thus just disable it for TV.
+                        */
+                       if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480)
+                               radeon_connector->dac_load_detect = false;
                        drm_connector_attach_property(&radeon_connector->base,
                                                      rdev->mode_info.load_detect_property,
                                                      1);
index e3f9edf..41bb76f 100644 (file)
@@ -688,6 +688,8 @@ int radeon_resume_kms(struct drm_device *dev)
                return -1;
        }
        pci_set_master(dev->pdev);
+       /* resume AGP if in use */
+       radeon_agp_resume(rdev);
        radeon_resume(rdev);
        radeon_restore_bios_scratch_regs(rdev);
        fb_set_suspend(rdev->fbdev_info, 0);
index 7935f79..ba68c9f 100644 (file)
@@ -137,8 +137,6 @@ int rv515_mc_wait_for_idle(struct radeon_device *rdev)
 
 void rv515_vga_render_disable(struct radeon_device *rdev)
 {
-       WREG32(R_000330_D1VGA_CONTROL, 0);
-       WREG32(R_000338_D2VGA_CONTROL, 0);
        WREG32(R_000300_VGA_RENDER_CONTROL,
                RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL);
 }
@@ -382,7 +380,6 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
        save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL);
 
        /* Stop all video */
-       WREG32(R_000330_D1VGA_CONTROL, 0);
        WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
        WREG32(R_000300_VGA_RENDER_CONTROL, 0);
        WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
@@ -391,6 +388,8 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
        WREG32(R_006880_D2CRTC_CONTROL, 0);
        WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
        WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
+       WREG32(R_000330_D1VGA_CONTROL, 0);
+       WREG32(R_000338_D2VGA_CONTROL, 0);
 }
 
 void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
@@ -404,14 +403,14 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
        WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control);
        mdelay(1);
        /* Restore video state */
+       WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control);
+       WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control);
        WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
        WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1);
        WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control);
        WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control);
        WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
        WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
-       WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control);
-       WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control);
        WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control);
 }
 
index 1fca590..fbab684 100644 (file)
@@ -650,7 +650,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev)
        return 0;
 
 out_irq:
-       free_irq(alg_data->irq, alg_data);
+       free_irq(alg_data->irq, i2c_pnx->adapter);
 out_clock:
        i2c_pnx->set_clock_stop(pdev);
 out_unmap:
@@ -669,7 +669,7 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev)
        struct i2c_adapter *adap = i2c_pnx->adapter;
        struct i2c_pnx_algo_data *alg_data = adap->algo_data;
 
-       free_irq(alg_data->irq, alg_data);
+       free_irq(alg_data->irq, i2c_pnx->adapter);
        i2c_del_adapter(adap);
        i2c_pnx->set_clock_stop(pdev);
        iounmap((void *)alg_data->ioaddr);
index aa96bd2..a0702f3 100644 (file)
@@ -257,6 +257,7 @@ static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
 
 static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
 {
+       struct tsl2550_data *data = i2c_get_clientdata(client);
        u8 ch0, ch1;
        int ret;
 
@@ -274,6 +275,8 @@ static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
        ret = tsl2550_calculate_lux(ch0, ch1);
        if (ret < 0)
                return ret;
+       if (data->operating_mode == 1)
+               ret *= 5;
 
        return sprintf(buf, "%d\n", ret);
 }
index 8d80fce..2965043 100644 (file)
@@ -762,6 +762,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
 {
        int res = 0;
        struct i2c_adapter *found;
+       struct i2c_client *client, *next;
 
        /* First make sure that this adapter was ever added */
        mutex_lock(&core_lock);
@@ -781,6 +782,16 @@ int i2c_del_adapter(struct i2c_adapter *adap)
        if (res)
                return res;
 
+       /* Remove devices instantiated from sysfs */
+       list_for_each_entry_safe(client, next, &userspace_devices, detected) {
+               if (client->adapter == adap) {
+                       dev_dbg(&adap->dev, "Removing %s at 0x%x\n",
+                               client->name, client->addr);
+                       list_del(&client->detected);
+                       i2c_unregister_device(client);
+               }
+       }
+
        /* Detach any active clients. This can't fail, thus we do not
           checking the returned value. */
        res = device_for_each_child(&adap->dev, NULL, __unregister_client);
index d3440b5..6e7ae2b 100644 (file)
@@ -162,7 +162,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
        if (tf->command == ATA_CMD_SET_FEATURES &&
            tf->feature == SETFEATURES_XFER &&
            tf->nsect >= XFER_SW_DMA_0) {
-               xfer_rate = ide_find_dma_mode(drive, XFER_UDMA_6);
+               xfer_rate = ide_find_dma_mode(drive, tf->nsect);
                if (xfer_rate != tf->nsect) {
                        err = -EINVAL;
                        goto abort;
index 96a2959..7c544f7 100644 (file)
@@ -260,15 +260,12 @@ static int ieee802154_fake_close(struct net_device *dev)
 static netdev_tx_t ieee802154_fake_xmit(struct sk_buff *skb,
                                              struct net_device *dev)
 {
-       skb->iif = dev->ifindex;
-       skb->dev = dev;
        dev->stats.tx_packets++;
        dev->stats.tx_bytes += skb->len;
 
-       dev->trans_start = jiffies;
-
        /* FIXME: do hardware work here ... */
 
+       dev_kfree_skb(skb);
        return NETDEV_TX_OK;
 }
 
index 655474b..abd4791 100644 (file)
@@ -64,7 +64,7 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
 
        ir->ir_type = ir_type;
 
-       memset(ir->ir_codes, sizeof(ir->ir_codes), 0);
+       memset(ir->ir_codes, 0, sizeof(ir->ir_codes));
 
        /*
         * FIXME: This is a temporary workaround to use the new IR tables
index f65591f..2a53dd0 100644 (file)
@@ -663,6 +663,14 @@ static struct zl10353_config cxusb_zl10353_xc3028_config = {
        .parallel_ts = 1,
 };
 
+static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = {
+       .demod_address = 0x0f,
+       .if2 = 45600,
+       .no_tuner = 1,
+       .parallel_ts = 1,
+       .disable_i2c_gate_ctrl = 1,
+};
+
 static struct mt352_config cxusb_mt352_xc3028_config = {
        .demod_address = 0x0f,
        .if2 = 4560,
@@ -894,7 +902,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap)
        cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1);
 
        if ((adap->fe = dvb_attach(zl10353_attach,
-                                  &cxusb_zl10353_xc3028_config,
+                                  &cxusb_zl10353_xc3028_config_no_i2c_gate,
                                   &adap->dev->i2c_adap)) == NULL)
                return -EIO;
 
index 8c1aed7..85a222c 100644 (file)
@@ -4,7 +4,7 @@
 
 config SMS_SIANO_MDTV
        tristate "Siano SMS1xxx based MDTV receiver"
-       depends on DVB_CORE && INPUT
+       depends on DVB_CORE && INPUT && HAS_DMA
        ---help---
          Choose Y or M here if you have MDTV receiver with a Siano chipset.
 
index c3f579d..c6cf116 100644 (file)
@@ -181,12 +181,10 @@ static void gemtek_pci_mute(struct gemtek_pci *card)
 
 static void gemtek_pci_unmute(struct gemtek_pci *card)
 {
-       mutex_lock(&card->lock);
        if (card->mute) {
                gemtek_pci_setfrequency(card, card->current_frequency);
                card->mute = false;
        }
-       mutex_unlock(&card->lock);
 }
 
 static int gemtek_pci_getsignal(struct gemtek_pci *card)
index c015da8..d14cfb2 100644 (file)
@@ -1426,7 +1426,6 @@ static __init int vpif_probe(struct platform_device *pdev)
        struct vpif_display_config *config;
        int i, j = 0, k, q, m, err = 0;
        struct i2c_adapter *i2c_adap;
-       struct vpif_config *config;
        struct common_obj *common;
        struct channel_obj *ch;
        struct video_device *vfd;
index bdb249b..c0fd5c6 100644 (file)
@@ -1584,8 +1584,8 @@ struct em28xx_board em28xx_boards[] = {
        [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = {
                .name          = "Reddo DVB-C USB TV Box",
                .tuner_type    = TUNER_ABSENT,
+               .tuner_gpio    = reddo_dvb_c_usb_box,
                .has_dvb       = 1,
-               .dvb_gpio      = reddo_dvb_c_usb_box,
        },
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
index 5f37952..7280229 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/moduleparam.h>
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
+#include <linux/sched.h>
 #include <linux/time.h>
 #include <linux/version.h>
 #include <linux/videodev2.h>
index dff2e5e..7db82bd 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/clk.h>
 #include <linux/vmalloc.h>
 #include <linux/interrupt.h>
+#include <linux/sched.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
index 2f78b4f..9c8b7c7 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/platform_device.h>
 #include <linux/videodev2.h>
 #include <linux/pm_runtime.h>
+#include <linux/sched.h>
 
 #include <media/v4l2-common.h>
 #include <media/v4l2-dev.h>
@@ -1723,11 +1724,12 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
 
        err = soc_camera_host_register(&pcdev->ici);
        if (err)
-               goto exit_free_irq;
+               goto exit_free_clk;
 
        return 0;
 
-exit_free_irq:
+exit_free_clk:
+       pm_runtime_disable(&pdev->dev);
        free_irq(pcdev->irq, pcdev);
 exit_release_mem:
        if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
@@ -1747,6 +1749,7 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
                                        struct sh_mobile_ceu_dev, ici);
 
        soc_camera_host_unregister(soc_host);
+       pm_runtime_disable(&pdev->dev);
        free_irq(pcdev->irq, pcdev);
        if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
                dma_release_declared_memory(&pdev->dev);
index 36e617b..95fdeb2 100644 (file)
@@ -1097,6 +1097,13 @@ static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
        return v4l2_subdev_call(sd, video, s_crop, a);
 }
 
+static void soc_camera_device_init(struct device *dev, void *pdata)
+{
+       dev->platform_data      = pdata;
+       dev->bus                = &soc_camera_bus_type;
+       dev->release            = dummy_release;
+}
+
 int soc_camera_host_register(struct soc_camera_host *ici)
 {
        struct soc_camera_host *ix;
@@ -1158,6 +1165,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
 
        list_for_each_entry(icd, &devices, list) {
                if (icd->iface == ici->nr) {
+                       void *pdata = icd->dev.platform_data;
                        /* The bus->remove will be called */
                        device_unregister(&icd->dev);
                        /*
@@ -1169,6 +1177,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
                         * device private data.
                         */
                        memset(&icd->dev, 0, sizeof(icd->dev));
+                       soc_camera_device_init(&icd->dev, pdata);
                }
        }
 
@@ -1200,10 +1209,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
                 * man, stay reasonable... */
                return -ENOMEM;
 
-       icd->devnum = num;
-       icd->dev.bus = &soc_camera_bus_type;
-
-       icd->dev.release        = dummy_release;
+       icd->devnum             = num;
        icd->use_count          = 0;
        icd->host_priv          = NULL;
        mutex_init(&icd->video_lock);
@@ -1311,12 +1317,13 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
        icd->iface = icl->bus_id;
        icd->pdev = &pdev->dev;
        platform_set_drvdata(pdev, icd);
-       icd->dev.platform_data = icl;
 
        ret = soc_camera_device_register(icd);
        if (ret < 0)
                goto escdevreg;
 
+       soc_camera_device_init(&icd->dev, icl);
+
        icd->user_width         = DEFAULT_WIDTH;
        icd->user_height        = DEFAULT_HEIGHT;
 
index 635ffc7..c3065c4 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/dma-mapping.h>
+#include <linux/sched.h>
 #include <media/videobuf-dma-contig.h>
 
 struct videobuf_dma_contig_memory {
index db39f4a..2cb2736 100644 (file)
@@ -158,6 +158,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
        struct i2c_msg msg[2];
        u8 msgbuf[2];
        struct i2c_client *client;
+       unsigned long timeout, read_time;
        int status, i;
 
        memset(msg, 0, sizeof(msg));
@@ -183,47 +184,60 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
        if (count > io_limit)
                count = io_limit;
 
-       /* Smaller eeproms can work given some SMBus extension calls */
        if (at24->use_smbus) {
+               /* Smaller eeproms can work given some SMBus extension calls */
                if (count > I2C_SMBUS_BLOCK_MAX)
                        count = I2C_SMBUS_BLOCK_MAX;
-               status = i2c_smbus_read_i2c_block_data(client, offset,
-                               count, buf);
-               dev_dbg(&client->dev, "smbus read %zu@%d --> %d\n",
-                               count, offset, status);
-               return (status < 0) ? -EIO : status;
+       } else {
+               /*
+                * When we have a better choice than SMBus calls, use a
+                * combined I2C message. Write address; then read up to
+                * io_limit data bytes. Note that read page rollover helps us
+                * here (unlike writes). msgbuf is u8 and will cast to our
+                * needs.
+                */
+               i = 0;
+               if (at24->chip.flags & AT24_FLAG_ADDR16)
+                       msgbuf[i++] = offset >> 8;
+               msgbuf[i++] = offset;
+
+               msg[0].addr = client->addr;
+               msg[0].buf = msgbuf;
+               msg[0].len = i;
+
+               msg[1].addr = client->addr;
+               msg[1].flags = I2C_M_RD;
+               msg[1].buf = buf;
+               msg[1].len = count;
        }
 
        /*
-        * When we have a better choice than SMBus calls, use a combined
-        * I2C message. Write address; then read up to io_limit data bytes.
-        * Note that read page rollover helps us here (unlike writes).
-        * msgbuf is u8 and will cast to our needs.
+        * Reads fail if the previous write didn't complete yet. We may
+        * loop a few times until this one succeeds, waiting at least
+        * long enough for one entire page write to work.
         */
-       i = 0;
-       if (at24->chip.flags & AT24_FLAG_ADDR16)
-               msgbuf[i++] = offset >> 8;
-       msgbuf[i++] = offset;
-
-       msg[0].addr = client->addr;
-       msg[0].buf = msgbuf;
-       msg[0].len = i;
+       timeout = jiffies + msecs_to_jiffies(write_timeout);
+       do {
+               read_time = jiffies;
+               if (at24->use_smbus) {
+                       status = i2c_smbus_read_i2c_block_data(client, offset,
+                                       count, buf);
+               } else {
+                       status = i2c_transfer(client->adapter, msg, 2);
+                       if (status == 2)
+                               status = count;
+               }
+               dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n",
+                               count, offset, status, jiffies);
 
-       msg[1].addr = client->addr;
-       msg[1].flags = I2C_M_RD;
-       msg[1].buf = buf;
-       msg[1].len = count;
+               if (status == count)
+                       return count;
 
-       status = i2c_transfer(client->adapter, msg, 2);
-       dev_dbg(&client->dev, "i2c read %zu@%d --> %d\n",
-                       count, offset, status);
+               /* REVISIT: at HZ=100, this is sloooow */
+               msleep(1);
+       } while (time_before(read_time, timeout));
 
-       if (status == 2)
-               return count;
-       else if (status >= 0)
-               return -EIO;
-       else
-               return status;
+       return -ETIMEDOUT;
 }
 
 static ssize_t at24_read(struct at24_data *at24,
index 705a589..90d168a 100644 (file)
@@ -56,7 +56,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired)
                                clk = 255;
                        host->cclk = host->mclk / (2 * (clk + 1));
                }
-               if (host->hw_designer == 0x80)
+               if (host->hw_designer == AMBA_VENDOR_ST)
                        clk |= MCI_FCEN; /* Bug fix in ST IP block */
                clk |= MCI_CLK_ENABLE;
                /* This hasn't proven to be worthwhile */
index e19ca4b..b2f71f7 100644 (file)
@@ -975,7 +975,7 @@ config ENC28J60_WRITEVERIFY
 
 config ETHOC
        tristate "OpenCores 10/100 Mbps Ethernet MAC support"
-       depends on NET_ETHERNET && HAS_IOMEM
+       depends on NET_ETHERNET && HAS_IOMEM && HAS_DMA
        select MII
        select PHYLIB
        select CRC32
index 2be49c8..b25467a 100644 (file)
@@ -628,15 +628,6 @@ static int ep93xx_open(struct net_device *dev)
        if (ep93xx_alloc_buffers(ep))
                return -ENOMEM;
 
-       if (is_zero_ether_addr(dev->dev_addr)) {
-               random_ether_addr(dev->dev_addr);
-               printk(KERN_INFO "%s: generated random MAC address "
-                       "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", dev->name,
-                       dev->dev_addr[0], dev->dev_addr[1],
-                       dev->dev_addr[2], dev->dev_addr[3],
-                       dev->dev_addr[4], dev->dev_addr[5]);
-       }
-
        napi_enable(&ep->napi);
 
        if (ep93xx_start_hw(dev)) {
@@ -877,6 +868,9 @@ static int ep93xx_eth_probe(struct platform_device *pdev)
        ep->mii.mdio_write = ep93xx_mdio_write;
        ep->mdc_divisor = 40;   /* Max HCLK 100 MHz, min MDIO clk 2.5 MHz.  */
 
+       if (is_zero_ether_addr(dev->dev_addr))
+               random_ether_addr(dev->dev_addr);
+
        err = register_netdev(dev);
        if (err) {
                dev_err(&pdev->dev, "Failed to register netdev\n");
index ce6f1ac..3f4b430 100644 (file)
@@ -1088,7 +1088,14 @@ static struct net_device * au1000_probe(int port_num)
                return NULL;
        }
 
-       if ((err = register_netdev(dev)) != 0) {
+       dev->base_addr = base;
+       dev->irq = irq;
+       dev->netdev_ops = &au1000_netdev_ops;
+       SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
+       dev->watchdog_timeo = ETH_TX_TIMEOUT;
+
+       err = register_netdev(dev);
+       if (err != 0) {
                printk(KERN_ERR "%s: Cannot register net device, error %d\n",
                                DRV_NAME, err);
                free_netdev(dev);
@@ -1209,12 +1216,6 @@ static struct net_device * au1000_probe(int port_num)
                aup->tx_db_inuse[i] = pDB;
        }
 
-       dev->base_addr = base;
-       dev->irq = irq;
-       dev->netdev_ops = &au1000_netdev_ops;
-       SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
-       dev->watchdog_timeo = ETH_TX_TIMEOUT;
-
        /*
         * The boot code uses the ethernet controller, so reset it to start
         * fresh.  au1000_init() expects that the device is in reset state.
index e046943..2a91323 100644 (file)
@@ -912,9 +912,6 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id)
                        bp->istat = istat;
                        __b44_disable_ints(bp);
                        __napi_schedule(&bp->napi);
-               } else {
-                       printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
-                              dev->name);
                }
 
 irq_ack:
index db63803..e347831 100644 (file)
@@ -164,16 +164,14 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
 # define EMAC_MBP_MCASTCHAN(ch)                ((ch) & 0x7)
 
 /* EMAC mac_control register */
-#define EMAC_MACCONTROL_TXPTYPE                (0x200)
-#define EMAC_MACCONTROL_TXPACEEN       (0x40)
-#define EMAC_MACCONTROL_MIIEN          (0x20)
-#define EMAC_MACCONTROL_GIGABITEN      (0x80)
-#define EMAC_MACCONTROL_GIGABITEN_SHIFT (7)
-#define EMAC_MACCONTROL_FULLDUPLEXEN   (0x1)
+#define EMAC_MACCONTROL_TXPTYPE                BIT(9)
+#define EMAC_MACCONTROL_TXPACEEN       BIT(6)
+#define EMAC_MACCONTROL_GMIIEN         BIT(5)
+#define EMAC_MACCONTROL_GIGABITEN      BIT(7)
+#define EMAC_MACCONTROL_FULLDUPLEXEN   BIT(0)
 #define EMAC_MACCONTROL_RMIISPEED_MASK BIT(15)
 
 /* GIGABIT MODE related bits */
-#define EMAC_DM646X_MACCONTORL_GMIIEN  BIT(5)
 #define EMAC_DM646X_MACCONTORL_GIG     BIT(7)
 #define EMAC_DM646X_MACCONTORL_GIGFORCE        BIT(17)
 
@@ -192,10 +190,10 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
 #define EMAC_RX_BUFFER_OFFSET_MASK     (0xFFFF)
 
 /* MAC_IN_VECTOR (0x180) register bit fields */
-#define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT           (0x20000)
-#define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT       (0x10000)
-#define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC         (0x0100)
-#define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC         (0x01)
+#define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT     BIT(17)
+#define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT BIT(16)
+#define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC   BIT(8)
+#define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC   BIT(0)
 
 /** NOTE:: For DM646x the IN_VECTOR has changed */
 #define EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC   BIT(EMAC_DEF_RX_CH)
@@ -203,7 +201,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
 #define EMAC_DM646X_MAC_IN_VECTOR_HOST_INT     BIT(26)
 #define EMAC_DM646X_MAC_IN_VECTOR_STATPEND_INT BIT(27)
 
-
 /* CPPI bit positions */
 #define EMAC_CPPI_SOP_BIT              BIT(31)
 #define EMAC_CPPI_EOP_BIT              BIT(30)
@@ -750,8 +747,7 @@ static void emac_update_phystatus(struct emac_priv *priv)
 
        if (priv->speed == SPEED_1000 && (priv->version == EMAC_VERSION_2)) {
                mac_control = emac_read(EMAC_MACCONTROL);
-               mac_control |= (EMAC_DM646X_MACCONTORL_GMIIEN |
-                               EMAC_DM646X_MACCONTORL_GIG |
+               mac_control |= (EMAC_DM646X_MACCONTORL_GIG |
                                EMAC_DM646X_MACCONTORL_GIGFORCE);
        } else {
                /* Clear the GIG bit and GIGFORCE bit */
@@ -2108,7 +2104,7 @@ static int emac_hw_enable(struct emac_priv *priv)
 
        /* Enable MII */
        val = emac_read(EMAC_MACCONTROL);
-       val |= (EMAC_MACCONTROL_MIIEN);
+       val |= (EMAC_MACCONTROL_GMIIEN);
        emac_write(EMAC_MACCONTROL, val);
 
        /* Enable NAPI and interrupts */
index 3c29a20..d269a68 100644 (file)
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/mii.h>
@@ -602,6 +603,7 @@ struct nic {
        struct mem *mem;
        dma_addr_t dma_addr;
 
+       struct pci_pool *cbs_pool;
        dma_addr_t cbs_dma_addr;
        u8 adaptive_ifs;
        u8 tx_threshold;
@@ -1793,9 +1795,7 @@ static void e100_clean_cbs(struct nic *nic)
                        nic->cb_to_clean = nic->cb_to_clean->next;
                        nic->cbs_avail++;
                }
-               pci_free_consistent(nic->pdev,
-                       sizeof(struct cb) * nic->params.cbs.count,
-                       nic->cbs, nic->cbs_dma_addr);
+               pci_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr);
                nic->cbs = NULL;
                nic->cbs_avail = 0;
        }
@@ -1813,8 +1813,8 @@ static int e100_alloc_cbs(struct nic *nic)
        nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL;
        nic->cbs_avail = 0;
 
-       nic->cbs = pci_alloc_consistent(nic->pdev,
-               sizeof(struct cb) * count, &nic->cbs_dma_addr);
+       nic->cbs = pci_pool_alloc(nic->cbs_pool, GFP_KERNEL,
+                                 &nic->cbs_dma_addr);
        if (!nic->cbs)
                return -ENOMEM;
 
@@ -2841,7 +2841,11 @@ static int __devinit e100_probe(struct pci_dev *pdev,
                DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n");
                goto err_out_free;
        }
-
+       nic->cbs_pool = pci_pool_create(netdev->name,
+                          nic->pdev,
+                          nic->params.cbs.count * sizeof(struct cb),
+                          sizeof(u32),
+                          0);
        DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
                (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0),
                pdev->irq, netdev->dev_addr);
@@ -2871,6 +2875,7 @@ static void __devexit e100_remove(struct pci_dev *pdev)
                unregister_netdev(netdev);
                e100_free(nic);
                pci_iounmap(pdev, nic->csr);
+               pci_pool_destroy(nic->cbs_pool);
                free_netdev(netdev);
                pci_release_regions(pdev);
                pci_disable_device(pdev);
index 189dfa2..3e187b0 100644 (file)
@@ -141,6 +141,8 @@ struct e1000_info;
 #define HV_TNCRS_UPPER         PHY_REG(778, 29) /* Transmit with no CRS */
 #define HV_TNCRS_LOWER         PHY_REG(778, 30)
 
+#define E1000_FCRTV_PCH     0x05F40 /* PCH Flow Control Refresh Timer Value */
+
 /* BM PHY Copper Specific Status */
 #define BM_CS_STATUS                      17
 #define BM_CS_STATUS_LINK_UP              0x0400
index 1bf4d2a..e82638e 100644 (file)
@@ -327,10 +327,18 @@ static int e1000_set_pauseparam(struct net_device *netdev,
 
                hw->fc.current_mode = hw->fc.requested_mode;
 
-               retval = ((hw->phy.media_type == e1000_media_type_fiber) ?
-                         hw->mac.ops.setup_link(hw) : e1000e_force_mac_fc(hw));
+               if (hw->phy.media_type == e1000_media_type_fiber) {
+                       retval = hw->mac.ops.setup_link(hw);
+                       /* implicit goto out */
+               } else {
+                       retval = e1000e_force_mac_fc(hw);
+                       if (retval)
+                               goto out;
+                       e1000e_set_fc_watermarks(hw);
+               }
        }
 
+out:
        clear_bit(__E1000_RESETTING, &adapter->state);
        return retval;
 }
index 51ddb04..eff3f47 100644 (file)
@@ -1118,7 +1118,8 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
                        oem_reg |= HV_OEM_BITS_LPLU;
        }
        /* Restart auto-neg to activate the bits */
-       oem_reg |= HV_OEM_BITS_RESTART_AN;
+       if (!e1000_check_reset_block(hw))
+               oem_reg |= HV_OEM_BITS_RESTART_AN;
        ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg);
 
 out:
@@ -3558,6 +3559,7 @@ struct e1000_info e1000_pch_info = {
                                  | FLAG_HAS_AMT
                                  | FLAG_HAS_FLASH
                                  | FLAG_HAS_JUMBO_FRAMES
+                                 | FLAG_DISABLE_FC_PAUSE_TIME /* errata */
                                  | FLAG_APME_IN_WUC,
        .pba                    = 26,
        .max_hw_frame_size      = 4096,
index 0687c6a..fad8f9e 100644 (file)
@@ -2769,25 +2769,38 @@ void e1000e_reset(struct e1000_adapter *adapter)
        /*
         * flow control settings
         *
-        * The high water mark must be low enough to fit two full frame
+        * The high water mark must be low enough to fit one full frame
         * (or the size used for early receive) above it in the Rx FIFO.
         * Set it to the lower of:
         * - 90% of the Rx FIFO size, and
         * - the full Rx FIFO size minus the early receive size (for parts
         *   with ERT support assuming ERT set to E1000_ERT_2048), or
-        * - the full Rx FIFO size minus two full frames
+        * - the full Rx FIFO size minus one full frame
         */
-       if ((adapter->flags & FLAG_HAS_ERT) &&
-           (adapter->netdev->mtu > ETH_DATA_LEN))
-               hwm = min(((pba << 10) * 9 / 10),
-                         ((pba << 10) - (E1000_ERT_2048 << 3)));
-       else
-               hwm = min(((pba << 10) * 9 / 10),
-                         ((pba << 10) - (2 * adapter->max_frame_size)));
+       if (hw->mac.type == e1000_pchlan) {
+               /*
+                * Workaround PCH LOM adapter hangs with certain network
+                * loads.  If hangs persist, try disabling Tx flow control.
+                */
+               if (adapter->netdev->mtu > ETH_DATA_LEN) {
+                       fc->high_water = 0x3500;
+                       fc->low_water  = 0x1500;
+               } else {
+                       fc->high_water = 0x5000;
+                       fc->low_water  = 0x3000;
+               }
+       } else {
+               if ((adapter->flags & FLAG_HAS_ERT) &&
+                   (adapter->netdev->mtu > ETH_DATA_LEN))
+                       hwm = min(((pba << 10) * 9 / 10),
+                                 ((pba << 10) - (E1000_ERT_2048 << 3)));
+               else
+                       hwm = min(((pba << 10) * 9 / 10),
+                                 ((pba << 10) - adapter->max_frame_size));
 
-       fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
-       fc->low_water = (fc->high_water - (2 * adapter->max_frame_size));
-       fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */
+               fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
+               fc->low_water = fc->high_water - 8;
+       }
 
        if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
                fc->pause_time = 0xFFFF;
@@ -2813,6 +2826,10 @@ void e1000e_reset(struct e1000_adapter *adapter)
        if (mac->ops.init_hw(hw))
                e_err("Hardware Error\n");
 
+       /* additional part of the flow-control workaround above */
+       if (hw->mac.type == e1000_pchlan)
+               ew32(FCRTV_PCH, 0x1000);
+
        e1000_update_mng_vlan(adapter);
 
        /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
@@ -3610,7 +3627,7 @@ static void e1000_watchdog_task(struct work_struct *work)
                        case SPEED_100:
                                txb2b = 0;
                                netdev->tx_queue_len = 100;
-                               /* maybe add some timeout factor ? */
+                               adapter->tx_timeout_factor = 10;
                                break;
                        }
 
@@ -4288,8 +4305,10 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 
        while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
                msleep(1);
-       /* e1000e_down has a dependency on max_frame_size */
+       /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
        adapter->max_frame_size = max_frame;
+       e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
+       netdev->mtu = new_mtu;
        if (netif_running(netdev))
                e1000e_down(adapter);
 
@@ -4319,9 +4338,6 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
                adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
                                         + ETH_FCS_LEN;
 
-       e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
-       netdev->mtu = new_mtu;
-
        if (netif_running(netdev))
                e1000e_up(adapter);
        else
index 03175b3..85f955f 100644 (file)
@@ -71,7 +71,6 @@ static const u16 e1000_igp_2_cable_length_table[] =
 #define I82577_CFG_ASSERT_CRS_ON_TX       (1 << 15)
 #define I82577_CFG_ENABLE_DOWNSHIFT       (3 << 10) /* auto downshift 100/10 */
 #define I82577_CTRL_REG                   23
-#define I82577_CTRL_DOWNSHIFT_MASK        (7 << 10)
 
 /* 82577 specific PHY registers */
 #define I82577_PHY_CTRL_2            18
@@ -660,15 +659,6 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
        phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
 
        ret_val = phy->ops.write_phy_reg(hw, I82577_CFG_REG, phy_data);
-       if (ret_val)
-               goto out;
-
-       /* Set number of link attempts before downshift */
-       ret_val = phy->ops.read_phy_reg(hw, I82577_CTRL_REG, &phy_data);
-       if (ret_val)
-               goto out;
-       phy_data &= ~I82577_CTRL_DOWNSHIFT_MASK;
-       ret_val = phy->ops.write_phy_reg(hw, I82577_CTRL_REG, phy_data);
 
 out:
        return ret_val;
@@ -2658,19 +2648,18 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
                page = 0;
 
        if (reg > MAX_PHY_MULTI_PAGE_REG) {
-               if ((hw->phy.type != e1000_phy_82578) ||
-                   ((reg != I82578_ADDR_REG) &&
-                    (reg != I82578_ADDR_REG + 1))) {
-                       u32 phy_addr = hw->phy.addr;
+               u32 phy_addr = hw->phy.addr;
 
-                       hw->phy.addr = 1;
+               hw->phy.addr = 1;
 
-                       /* Page is shifted left, PHY expects (page x 32) */
-                       ret_val = e1000e_write_phy_reg_mdic(hw,
-                                                    IGP01E1000_PHY_PAGE_SELECT,
-                                                    (page << IGP_PAGE_SHIFT));
-                       hw->phy.addr = phy_addr;
-               }
+               /* Page is shifted left, PHY expects (page x 32) */
+               ret_val = e1000e_write_phy_reg_mdic(hw,
+                                            IGP01E1000_PHY_PAGE_SELECT,
+                                            (page << IGP_PAGE_SHIFT));
+               hw->phy.addr = phy_addr;
+
+               if (ret_val)
+                       goto out;
        }
 
        ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
@@ -2678,7 +2667,7 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data,
 out:
        /* Revert to MDIO fast mode, if applicable */
        if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
-               ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+               ret_val |= e1000_set_mdio_slow_mode_hv(hw, false);
 
        if (!locked)
                hw->phy.ops.release_phy(hw);
@@ -2784,19 +2773,18 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
        }
 
        if (reg > MAX_PHY_MULTI_PAGE_REG) {
-               if ((hw->phy.type != e1000_phy_82578) ||
-                   ((reg != I82578_ADDR_REG) &&
-                    (reg != I82578_ADDR_REG + 1))) {
-                       u32 phy_addr = hw->phy.addr;
+               u32 phy_addr = hw->phy.addr;
 
-                       hw->phy.addr = 1;
+               hw->phy.addr = 1;
 
-                       /* Page is shifted left, PHY expects (page x 32) */
-                       ret_val = e1000e_write_phy_reg_mdic(hw,
-                                                    IGP01E1000_PHY_PAGE_SELECT,
-                                                    (page << IGP_PAGE_SHIFT));
-                       hw->phy.addr = phy_addr;
-               }
+               /* Page is shifted left, PHY expects (page x 32) */
+               ret_val = e1000e_write_phy_reg_mdic(hw,
+                                            IGP01E1000_PHY_PAGE_SELECT,
+                                            (page << IGP_PAGE_SHIFT));
+               hw->phy.addr = phy_addr;
+
+               if (ret_val)
+                       goto out;
        }
 
        ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
@@ -2805,7 +2793,7 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
 out:
        /* Revert to MDIO fast mode, if applicable */
        if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
-               ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+               ret_val |= e1000_set_mdio_slow_mode_hv(hw, false);
 
        if (!locked)
                hw->phy.ops.release_phy(hw);
index a5036f7..a456578 100644 (file)
@@ -240,11 +240,11 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
 static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter,
                                       struct ixgbe_ring *tx_ring)
 {
-       int tc;
        u32 txoff = IXGBE_TFCS_TXOFF;
 
 #ifdef CONFIG_IXGBE_DCB
        if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+               int tc;
                int reg_idx = tx_ring->reg_idx;
                int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
 
index 0be14d7..c146304 100644 (file)
@@ -568,6 +568,16 @@ static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len)
                iowrite16(*wptr++, ks->hw_addr);
 }
 
+static void ks_disable_int(struct ks_net *ks)
+{
+       ks_wrreg16(ks, KS_IER, 0x0000);
+}  /* ks_disable_int */
+
+static void ks_enable_int(struct ks_net *ks)
+{
+       ks_wrreg16(ks, KS_IER, ks->rc_ier);
+}  /* ks_enable_int */
+
 /**
  * ks_tx_fifo_space - return the available hardware buffer size.
  * @ks: The chip information
@@ -681,6 +691,47 @@ static void ks_soft_reset(struct ks_net *ks, unsigned op)
 }
 
 
+void ks_enable_qmu(struct ks_net *ks)
+{
+       u16 w;
+
+       w = ks_rdreg16(ks, KS_TXCR);
+       /* Enables QMU Transmit (TXCR). */
+       ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE);
+
+       /*
+        * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame
+        * Enable
+        */
+
+       w = ks_rdreg16(ks, KS_RXQCR);
+       ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE);
+
+       /* Enables QMU Receive (RXCR1). */
+       w = ks_rdreg16(ks, KS_RXCR1);
+       ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE);
+       ks->enabled = true;
+}  /* ks_enable_qmu */
+
+static void ks_disable_qmu(struct ks_net *ks)
+{
+       u16     w;
+
+       w = ks_rdreg16(ks, KS_TXCR);
+
+       /* Disables QMU Transmit (TXCR). */
+       w  &= ~TXCR_TXE;
+       ks_wrreg16(ks, KS_TXCR, w);
+
+       /* Disables QMU Receive (RXCR1). */
+       w = ks_rdreg16(ks, KS_RXCR1);
+       w &= ~RXCR1_RXE ;
+       ks_wrreg16(ks, KS_RXCR1, w);
+
+       ks->enabled = false;
+
+}  /* ks_disable_qmu */
+
 /**
  * ks_read_qmu - read 1 pkt data from the QMU.
  * @ks: The chip information
@@ -752,7 +803,7 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev)
                        (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) {
                        skb_reserve(skb, 2);
                        /* read data block including CRC 4 bytes */
-                       ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len + 4);
+                       ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len);
                        skb_put(skb, frame_hdr->len);
                        skb->dev = netdev;
                        skb->protocol = eth_type_trans(skb, netdev);
@@ -861,7 +912,7 @@ static int ks_net_open(struct net_device *netdev)
                ks_dbg(ks, "%s - entry\n", __func__);
 
        /* reset the HW */
-       err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, ks);
+       err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev);
 
        if (err) {
                printk(KERN_ERR "Failed to request IRQ: %d: %d\n",
@@ -869,6 +920,15 @@ static int ks_net_open(struct net_device *netdev)
                return err;
        }
 
+       /* wake up powermode to normal mode */
+       ks_set_powermode(ks, PMECR_PM_NORMAL);
+       mdelay(1);      /* wait for normal mode to take effect */
+
+       ks_wrreg16(ks, KS_ISR, 0xffff);
+       ks_enable_int(ks);
+       ks_enable_qmu(ks);
+       netif_start_queue(ks->netdev);
+
        if (netif_msg_ifup(ks))
                ks_dbg(ks, "network device %s up\n", netdev->name);
 
@@ -892,19 +952,14 @@ static int ks_net_stop(struct net_device *netdev)
 
        netif_stop_queue(netdev);
 
-       kfree(ks->frame_head_info);
-
        mutex_lock(&ks->lock);
 
        /* turn off the IRQs and ack any outstanding */
        ks_wrreg16(ks, KS_IER, 0x0000);
        ks_wrreg16(ks, KS_ISR, 0xffff);
 
-       /* shutdown RX process */
-       ks_wrreg16(ks, KS_RXCR1, 0x0000);
-
-       /* shutdown TX process */
-       ks_wrreg16(ks, KS_TXCR, 0x0000);
+       /* shutdown RX/TX QMU */
+       ks_disable_qmu(ks);
 
        /* set powermode to soft power down to save power */
        ks_set_powermode(ks, PMECR_PM_SOFTDOWN);
@@ -929,17 +984,8 @@ static int ks_net_stop(struct net_device *netdev)
  */
 static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len)
 {
-       unsigned fid = ks->fid;
-
-       fid = ks->fid;
-       ks->fid = (ks->fid + 1) & TXFR_TXFID_MASK;
-
-       /* reduce the tx interrupt occurrances. */
-       if (!fid)
-               fid |= TXFR_TXIC;       /* irq on completion */
-
        /* start header at txb[0] to align txw entries */
-       ks->txh.txw[0] = cpu_to_le16(fid);
+       ks->txh.txw[0] = 0;
        ks->txh.txw[1] = cpu_to_le16(len);
 
        /* 1. set sudo-DMA mode */
@@ -957,16 +1003,6 @@ static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len)
                ;
 }
 
-static void ks_disable_int(struct ks_net *ks)
-{
-       ks_wrreg16(ks, KS_IER, 0x0000);
-}  /* ks_disable_int */
-
-static void ks_enable_int(struct ks_net *ks)
-{
-       ks_wrreg16(ks, KS_IER, ks->rc_ier);
-}  /* ks_enable_int */
-
 /**
  * ks_start_xmit - transmit packet
  * @skb                : The buffer to transmit
@@ -1410,25 +1446,6 @@ static int ks_read_selftest(struct ks_net *ks)
        return ret;
 }
 
-static void ks_disable(struct ks_net *ks)
-{
-       u16     w;
-
-       w = ks_rdreg16(ks, KS_TXCR);
-
-       /* Disables QMU Transmit (TXCR). */
-       w  &= ~TXCR_TXE;
-       ks_wrreg16(ks, KS_TXCR, w);
-
-       /* Disables QMU Receive (RXCR1). */
-       w = ks_rdreg16(ks, KS_RXCR1);
-       w &= ~RXCR1_RXE ;
-       ks_wrreg16(ks, KS_RXCR1, w);
-
-       ks->enabled = false;
-
-}  /* ks_disable */
-
 static void ks_setup(struct ks_net *ks)
 {
        u16     w;
@@ -1463,7 +1480,7 @@ static void ks_setup(struct ks_net *ks)
        w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP;
        ks_wrreg16(ks, KS_TXCR, w);
 
-       w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE;
+       w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC;
 
        if (ks->promiscuous)         /* bPromiscuous */
                w |= (RXCR1_RXAE | RXCR1_RXINVF);
@@ -1486,28 +1503,6 @@ static void ks_setup_int(struct ks_net *ks)
        ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI);
 }  /* ks_setup_int */
 
-void ks_enable(struct ks_net *ks)
-{
-       u16 w;
-
-       w = ks_rdreg16(ks, KS_TXCR);
-       /* Enables QMU Transmit (TXCR). */
-       ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE);
-
-       /*
-        * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame
-        * Enable
-        */
-
-       w = ks_rdreg16(ks, KS_RXQCR);
-       ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE);
-
-       /* Enables QMU Receive (RXCR1). */
-       w = ks_rdreg16(ks, KS_RXCR1);
-       ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE);
-       ks->enabled = true;
-}  /* ks_enable */
-
 static int ks_hw_init(struct ks_net *ks)
 {
 #define        MHEADER_SIZE    (sizeof(struct type_frame_head) * MAX_RECV_FRAMES)
@@ -1612,11 +1607,9 @@ static int __devinit ks8851_probe(struct platform_device *pdev)
 
        ks_soft_reset(ks, GRR_GSR);
        ks_hw_init(ks);
-       ks_disable(ks);
+       ks_disable_qmu(ks);
        ks_setup(ks);
        ks_setup_int(ks);
-       ks_enable_int(ks);
-       ks_enable(ks);
        memcpy(netdev->dev_addr, ks->mac_addr, 6);
 
        data = ks_rdreg16(ks, KS_OBCR);
@@ -1658,6 +1651,7 @@ static int __devexit ks8851_remove(struct platform_device *pdev)
        struct ks_net *ks = netdev_priv(netdev);
        struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
+       kfree(ks->frame_head_info);
        unregister_netdev(netdev);
        iounmap(ks->hw_addr);
        free_netdev(netdev);
index 3aabfd9..2490aa3 100644 (file)
@@ -360,6 +360,7 @@ static int macvlan_init(struct net_device *dev)
        dev->state              = (dev->state & ~MACVLAN_STATE_MASK) |
                                  (lowerdev->state & MACVLAN_STATE_MASK);
        dev->features           = lowerdev->features & MACVLAN_FEATURES;
+       dev->gso_max_size       = lowerdev->gso_max_size;
        dev->iflink             = lowerdev->ifindex;
        dev->hard_header_len    = lowerdev->hard_header_len;
 
@@ -596,6 +597,7 @@ static int macvlan_device_event(struct notifier_block *unused,
        case NETDEV_FEAT_CHANGE:
                list_for_each_entry(vlan, &port->vlans, list) {
                        vlan->dev->features = dev->features & MACVLAN_FEATURES;
+                       vlan->dev->gso_max_size = dev->gso_max_size;
                        netdev_features_change(vlan->dev);
                }
                break;
index 7384f59..e1237b8 100644 (file)
@@ -1163,6 +1163,8 @@ struct netxen_adapter {
        u32 int_vec_bit;
        u32 heartbit;
 
+       u8 mac_addr[ETH_ALEN];
+
        struct netxen_adapter_stats stats;
 
        struct netxen_recv_context recv_ctx;
index 1c46da6..17bb381 100644 (file)
@@ -545,6 +545,8 @@ enum {
 #define        NETXEN_NIU_TEST_MUX_CTL         (NETXEN_CRB_NIU + 0x00094)
 #define        NETXEN_NIU_XG_PAUSE_CTL         (NETXEN_CRB_NIU + 0x00098)
 #define        NETXEN_NIU_XG_PAUSE_LEVEL       (NETXEN_CRB_NIU + 0x000dc)
+#define        NETXEN_NIU_FRAME_COUNT_SELECT   (NETXEN_CRB_NIU + 0x000ac)
+#define        NETXEN_NIU_FRAME_COUNT          (NETXEN_CRB_NIU + 0x000b0)
 #define        NETXEN_NIU_XG_SEL               (NETXEN_CRB_NIU + 0x00128)
 #define NETXEN_NIU_GB_PAUSE_CTL                (NETXEN_CRB_NIU + 0x0030c)
 
index 3185a98..52a3798 100644 (file)
@@ -383,24 +383,51 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
 
 int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
 {
-       __u32 reg;
+       u32 mac_cfg;
+       u32 cnt = 0;
+       __u32 reg = 0x0200;
        u32 port = adapter->physical_port;
+       u16 board_type = adapter->ahw.board_type;
 
        if (port > NETXEN_NIU_MAX_XG_PORTS)
                return -EINVAL;
 
-       reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
-       if (mode == NETXEN_NIU_PROMISC_MODE)
-               reg = (reg | 0x2000UL);
-       else
-               reg = (reg & ~0x2000UL);
+       mac_cfg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port));
+       mac_cfg &= ~0x4;
+       NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg);
 
-       if (mode == NETXEN_NIU_ALLMULTI_MODE)
-               reg = (reg | 0x1000UL);
-       else
-               reg = (reg & ~0x1000UL);
+       if ((board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) ||
+                       (board_type == NETXEN_BRDTYPE_P2_SB31_10G_HMEZ))
+               reg = (0x20 << port);
+
+       NXWR32(adapter, NETXEN_NIU_FRAME_COUNT_SELECT, reg);
+
+       mdelay(10);
+
+       while (NXRD32(adapter, NETXEN_NIU_FRAME_COUNT) && ++cnt < 20)
+               mdelay(10);
+
+       if (cnt < 20) {
+
+               reg = NXRD32(adapter,
+                       NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
+
+               if (mode == NETXEN_NIU_PROMISC_MODE)
+                       reg = (reg | 0x2000UL);
+               else
+                       reg = (reg & ~0x2000UL);
+
+               if (mode == NETXEN_NIU_ALLMULTI_MODE)
+                       reg = (reg | 0x1000UL);
+               else
+                       reg = (reg & ~0x1000UL);
+
+               NXWR32(adapter,
+                       NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+       }
 
-       NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+       mac_cfg |= 0x4;
+       NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg);
 
        return 0;
 }
@@ -436,7 +463,7 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
 {
        u32     val = 0;
        u16 port = adapter->physical_port;
-       u8 *addr = adapter->netdev->dev_addr;
+       u8 *addr = adapter->mac_addr;
 
        if (adapter->mc_enabled)
                return 0;
@@ -465,7 +492,7 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter)
 {
        u32     val = 0;
        u16 port = adapter->physical_port;
-       u8 *addr = adapter->netdev->dev_addr;
+       u8 *addr = adapter->mac_addr;
 
        if (!adapter->mc_enabled)
                return 0;
@@ -660,7 +687,7 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
 
        list_splice_tail_init(&adapter->mac_list, &del_list);
 
-       nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list);
+       nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list);
        nx_p3_nic_add_mac(adapter, bcast_addr, &del_list);
 
        if (netdev->flags & IFF_PROMISC) {
index e40b914..8a09043 100644 (file)
@@ -544,6 +544,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
                                continue;
                        if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */
                                continue;
+                       if ((off & 0x0ff00000) == NETXEN_CRB_DDR_NET)
+                               continue;
                        if (off == (NETXEN_CRB_PEG_NET_1 + 0x18))
                                buf[i].data = 0x1020;
                        /* skip the function enable register */
index 0b4a56a..3bf78db 100644 (file)
@@ -437,6 +437,7 @@ netxen_read_mac_addr(struct netxen_adapter *adapter)
                netdev->dev_addr[i] = *(p + 5 - i);
 
        memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
+       memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len);
 
        /* set station address */
 
@@ -459,6 +460,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p)
                netxen_napi_disable(adapter);
        }
 
+       memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len);
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
        adapter->macaddr_set(adapter, addr->sa_data);
 
@@ -956,7 +958,7 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
                return err;
        }
        if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
-               adapter->macaddr_set(adapter, netdev->dev_addr);
+               adapter->macaddr_set(adapter, adapter->mac_addr);
 
        adapter->set_multi(netdev);
        adapter->set_mtu(adapter, netdev->mtu);
index b9221bd..0fe2fc9 100644 (file)
@@ -3235,6 +3235,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
        flush_scheduled_work();
 
        unregister_netdev(dev);
+
+       /* restore original MAC address */
+       rtl_rar_set(tp, dev->perm_addr);
+
        rtl_disable_msi(pdev, tp);
        rtl8169_release_board(pdev, dev, tp->mmio_addr);
        pci_set_drvdata(pdev, NULL);
@@ -4881,6 +4885,9 @@ static void rtl_shutdown(struct pci_dev *pdev)
 
        rtl8169_net_suspend(dev);
 
+       /* restore original MAC address */
+       rtl_rar_set(tp, dev->perm_addr);
+
        spin_lock_irq(&tp->lock);
 
        rtl8169_asic_down(ioaddr);
index 05c91ee..f12206b 100644 (file)
@@ -2283,7 +2283,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev)
 
        ndev->irq = ires->start;
 
-       if (ires->flags & IRQF_TRIGGER_MASK)
+       if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK)
                irq_flags = ires->flags & IRQF_TRIGGER_MASK;
 
        ret = smc_request_attrib(pdev, ndev);
index b4909a2..0f79092 100644 (file)
@@ -252,6 +252,9 @@ static int smsc9420_ethtool_get_settings(struct net_device *dev,
 {
        struct smsc9420_pdata *pd = netdev_priv(dev);
 
+       if (!pd->phy_dev)
+               return -ENODEV;
+
        cmd->maxtxpkt = 1;
        cmd->maxrxpkt = 1;
        return phy_ethtool_gset(pd->phy_dev, cmd);
@@ -262,6 +265,9 @@ static int smsc9420_ethtool_set_settings(struct net_device *dev,
 {
        struct smsc9420_pdata *pd = netdev_priv(dev);
 
+       if (!pd->phy_dev)
+               return -ENODEV;
+
        return phy_ethtool_sset(pd->phy_dev, cmd);
 }
 
@@ -290,6 +296,10 @@ static void smsc9420_ethtool_set_msglevel(struct net_device *netdev, u32 data)
 static int smsc9420_ethtool_nway_reset(struct net_device *netdev)
 {
        struct smsc9420_pdata *pd = netdev_priv(netdev);
+
+       if (!pd->phy_dev)
+               return -ENODEV;
+
        return phy_start_aneg(pd->phy_dev);
 }
 
@@ -312,6 +322,10 @@ smsc9420_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs,
        for (i = 0; i < 0x100; i += (sizeof(u32)))
                data[j++] = smsc9420_reg_read(pd, i);
 
+       // cannot read phy registers if the net device is down
+       if (!phy_dev)
+               return;
+
        for (i = 0; i <= 31; i++)
                data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i);
 }
index c2f14dc..9542995 100644 (file)
@@ -416,13 +416,8 @@ static void init_dma_desc_rings(struct net_device *dev)
        unsigned int txsize = priv->dma_tx_size;
        unsigned int rxsize = priv->dma_rx_size;
        unsigned int bfsize = priv->dma_buf_sz;
-       int buff2_needed = 0;
-       int dis_ic = 0;
+       int buff2_needed = 0, dis_ic = 0;
 
-#ifdef CONFIG_STMMAC_TIMER
-       /* Using Timers disable interrupts on completion for the reception */
-       dis_ic = 1;
-#endif
        /* Set the Buffer size according to the MTU;
         * indeed, in case of jumbo we need to bump-up the buffer sizes.
         */
@@ -437,6 +432,11 @@ static void init_dma_desc_rings(struct net_device *dev)
        else
                bfsize = DMA_BUFFER_SIZE;
 
+#ifdef CONFIG_STMMAC_TIMER
+       /* Disable interrupts on completion for the reception if timer is on */
+       if (likely(priv->tm->enable))
+               dis_ic = 1;
+#endif
        /* If the MTU exceeds 8k so use the second buffer in the chain */
        if (bfsize >= BUF_SIZE_8KiB)
                buff2_needed = 1;
@@ -809,20 +809,22 @@ static void stmmac_tx(struct stmmac_priv *priv)
 
 static inline void stmmac_enable_irq(struct stmmac_priv *priv)
 {
-#ifndef CONFIG_STMMAC_TIMER
-       writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA);
-#else
-       priv->tm->timer_start(tmrate);
+#ifdef CONFIG_STMMAC_TIMER
+       if (likely(priv->tm->enable))
+               priv->tm->timer_start(tmrate);
+       else
 #endif
+       writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA);
 }
 
 static inline void stmmac_disable_irq(struct stmmac_priv *priv)
 {
-#ifndef CONFIG_STMMAC_TIMER
-       writel(0, priv->dev->base_addr + DMA_INTR_ENA);
-#else
-       priv->tm->timer_stop();
+#ifdef CONFIG_STMMAC_TIMER
+       if (likely(priv->tm->enable))
+               priv->tm->timer_stop();
+       else
 #endif
+       writel(0, priv->dev->base_addr + DMA_INTR_ENA);
 }
 
 static int stmmac_has_work(struct stmmac_priv *priv)
@@ -1031,22 +1033,23 @@ static int stmmac_open(struct net_device *dev)
        }
 
 #ifdef CONFIG_STMMAC_TIMER
-       priv->tm = kmalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
+       priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
        if (unlikely(priv->tm == NULL)) {
                pr_err("%s: ERROR: timer memory alloc failed \n", __func__);
                return -ENOMEM;
        }
        priv->tm->freq = tmrate;
 
-       /* Test if the HW timer can be actually used.
-        * In case of failure continue with no timer. */
+       /* Test if the external timer can be actually used.
+        * In case of failure continue without timer. */
        if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
-               pr_warning("stmmaceth: cannot attach the HW timer\n");
+               pr_warning("stmmaceth: cannot attach the external timer.\n");
                tmrate = 0;
                priv->tm->freq = 0;
                priv->tm->timer_start = stmmac_no_timer_started;
                priv->tm->timer_stop = stmmac_no_timer_stopped;
-       }
+       } else
+               priv->tm->enable = 1;
 #endif
 
        /* Create and initialize the TX/RX descriptors chains. */
@@ -1322,9 +1325,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* Interrupt on completition only for the latest segment */
        priv->mac_type->ops->close_tx_desc(desc);
+
 #ifdef CONFIG_STMMAC_TIMER
-       /* Clean IC while using timers */
-       priv->mac_type->ops->clear_tx_ic(desc);
+       /* Clean IC while using timer */
+       if (likely(priv->tm->enable))
+               priv->mac_type->ops->clear_tx_ic(desc);
 #endif
        /* To avoid raise condition */
        priv->mac_type->ops->set_tx_owner(first);
@@ -2028,7 +2033,8 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state)
 
 #ifdef CONFIG_STMMAC_TIMER
                priv->tm->timer_stop();
-               dis_ic = 1;
+               if (likely(priv->tm->enable))
+                       dis_ic = 1;
 #endif
                napi_disable(&priv->napi);
 
index b838c65..679f61f 100644 (file)
@@ -63,7 +63,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
 
        stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
        if (stmmac_rtc == NULL) {
-               pr_error("open rtc device failed\n");
+               pr_err("open rtc device failed\n");
                return -ENODEV;
        }
 
@@ -71,7 +71,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
 
        /* Periodic mode is not supported */
        if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) {
-               pr_error("set periodic failed\n");
+               pr_err("set periodic failed\n");
                rtc_irq_unregister(stmmac_rtc, &stmmac_task);
                rtc_class_close(stmmac_rtc);
                return -1;
index f795cae..6863590 100644 (file)
@@ -26,6 +26,7 @@ struct stmmac_timer {
        void (*timer_start) (unsigned int new_freq);
        void (*timer_stop) (void);
        unsigned int freq;
+       unsigned int enable;
 };
 
 /* Open the HW timer device and return 0 in case of success */
index fa4e581..43bc3fc 100644 (file)
@@ -378,7 +378,7 @@ static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
 }
 
 #define DUMP(buf_, len_)       \
-       dbg_dump(__LINE__, __func__, buf_, len_)
+       dbg_dump(__LINE__, __func__, (unsigned char *)buf_, len_)
 
 #define DUMP1(buf_, len_)                      \
        do {                                    \
@@ -1363,7 +1363,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
        /* reset the rts and dtr */
        /* do the actual close */
        serial->open_count--;
-       kref_put(&serial->parent->ref, hso_serial_ref_free);
+
        if (serial->open_count <= 0) {
                serial->open_count = 0;
                spin_lock_irq(&serial->serial_lock);
@@ -1383,6 +1383,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
                usb_autopm_put_interface(serial->parent->interface);
 
        mutex_unlock(&serial->parent->mutex);
+
+       kref_put(&serial->parent->ref, hso_serial_ref_free);
 }
 
 /* close the requested serial port */
@@ -1527,7 +1529,7 @@ static void tiocmget_intr_callback(struct urb *urb)
                dev_warn(&usb->dev,
                         "hso received invalid serial state notification\n");
                DUMP(serial_state_notification,
-                    sizeof(hso_serial_state_notifation))
+                    sizeof(struct hso_serial_state_notification));
        } else {
 
                UART_state_bitmap = le16_to_cpu(serial_state_notification->
index ade5b34..52af501 100644 (file)
@@ -210,32 +210,29 @@ rx_drop:
 static struct net_device_stats *veth_get_stats(struct net_device *dev)
 {
        struct veth_priv *priv;
-       struct net_device_stats *dev_stats;
        int cpu;
-       struct veth_net_stats *stats;
+       struct veth_net_stats *stats, total = {0};
 
        priv = netdev_priv(dev);
-       dev_stats = &dev->stats;
-
-       dev_stats->rx_packets = 0;
-       dev_stats->tx_packets = 0;
-       dev_stats->rx_bytes = 0;
-       dev_stats->tx_bytes = 0;
-       dev_stats->tx_dropped = 0;
-       dev_stats->rx_dropped = 0;
 
-       for_each_online_cpu(cpu) {
+       for_each_possible_cpu(cpu) {
                stats = per_cpu_ptr(priv->stats, cpu);
 
-               dev_stats->rx_packets += stats->rx_packets;
-               dev_stats->tx_packets += stats->tx_packets;
-               dev_stats->rx_bytes += stats->rx_bytes;
-               dev_stats->tx_bytes += stats->tx_bytes;
-               dev_stats->tx_dropped += stats->tx_dropped;
-               dev_stats->rx_dropped += stats->rx_dropped;
+               total.rx_packets += stats->rx_packets;
+               total.tx_packets += stats->tx_packets;
+               total.rx_bytes   += stats->rx_bytes;
+               total.tx_bytes   += stats->tx_bytes;
+               total.tx_dropped += stats->tx_dropped;
+               total.rx_dropped += stats->rx_dropped;
        }
-
-       return dev_stats;
+       dev->stats.rx_packets = total.rx_packets;
+       dev->stats.tx_packets = total.tx_packets;
+       dev->stats.rx_bytes   = total.rx_bytes;
+       dev->stats.tx_bytes   = total.tx_bytes;
+       dev->stats.tx_dropped = total.tx_dropped;
+       dev->stats.rx_dropped = total.rx_dropped;
+
+       return &dev->stats;
 }
 
 static int veth_open(struct net_device *dev)
index e2c33c0..8e25ca7 100644 (file)
@@ -907,6 +907,7 @@ static ssize_t cosa_write(struct file *file,
                        current->state = TASK_RUNNING;
                        chan->tx_status = 1;
                        spin_unlock_irqrestore(&cosa->lock, flags);
+                       up(&chan->wsem);
                        return -ERESTARTSYS;
                }
        }
index 52bed89..43d2be9 100644 (file)
@@ -1555,6 +1555,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
                BIT(NL80211_IFTYPE_ADHOC) |
                BIT(NL80211_IFTYPE_MESH_POINT);
 
+       hw->wiphy->ps_default = false;
+
        hw->queues = 4;
        hw->max_rates = 4;
        hw->channel_change_time = 5000;
index fb9bcfa..b7e196e 100644 (file)
@@ -1277,8 +1277,16 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
                return -ENXIO;
        }
 
+       if (priv->stations[sta_id].tid[tid].agg.state ==
+                               IWL_EMPTYING_HW_QUEUE_ADDBA) {
+               IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
+               ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, ra, tid);
+               priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
+               return 0;
+       }
+
        if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
-               IWL_WARN(priv, "Stopping AGG while state not IWL_AGG_ON\n");
+               IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
 
        tid_data = &priv->stations[sta_id].tid[tid];
        ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
index 0a8f735..ab64522 100644 (file)
@@ -52,7 +52,7 @@
  */
 #undef START_IN_KERNEL_MODE
 
-#define DRV_VER "0.5.17"
+#define DRV_VER "0.5.18"
 
 /*
  * According to the Atom N270 datasheet,
@@ -61,7 +61,7 @@
  * measured by the on-die thermal monitor are within 0 <= Tj <= 90. So,
  * assume 89°C is critical temperature.
  */
-#define ACERHDF_TEMP_CRIT 89
+#define ACERHDF_TEMP_CRIT 89000
 #define ACERHDF_FAN_OFF 0
 #define ACERHDF_FAN_AUTO 1
 
@@ -69,7 +69,7 @@
  * No matter what value the user puts into the fanon variable, turn on the fan
  * at 80 degree Celsius to prevent hardware damage
  */
-#define ACERHDF_MAX_FANON 80
+#define ACERHDF_MAX_FANON 80000
 
 /*
  * Maximum interval between two temperature checks is 15 seconds, as the die
@@ -85,8 +85,8 @@ static int kernelmode;
 #endif
 
 static unsigned int interval = 10;
-static unsigned int fanon = 63;
-static unsigned int fanoff = 58;
+static unsigned int fanon = 63000;
+static unsigned int fanoff = 58000;
 static unsigned int verbose;
 static unsigned int fanstate = ACERHDF_FAN_AUTO;
 static char force_bios[16];
@@ -171,7 +171,7 @@ static int acerhdf_get_temp(int *temp)
        if (ec_read(bios_cfg->tempreg, &read_temp))
                return -EINVAL;
 
-       *temp = read_temp;
+       *temp = read_temp * 1000;
 
        return 0;
 }
index d93108d..a848c7e 100644 (file)
@@ -1680,36 +1680,48 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv)
                          | (__bv1) << 8 | (__bv2) }
 
 #define TPV_Q_X(__v, __bid1, __bid2, __bv1, __bv2,     \
-               __eid1, __eid2, __ev1, __ev2)           \
+               __eid, __ev1, __ev2)                    \
        { .vendor       = (__v),                        \
          .bios         = TPID(__bid1, __bid2),         \
-         .ec           = TPID(__eid1, __eid2),         \
+         .ec           = __eid,                        \
          .quirks       = (__ev1) << 24 | (__ev2) << 16 \
                          | (__bv1) << 8 | (__bv2) }
 
 #define TPV_QI0(__id1, __id2, __bv1, __bv2) \
        TPV_Q(PCI_VENDOR_ID_IBM, __id1, __id2, __bv1, __bv2)
 
+/* Outdated IBM BIOSes often lack the EC id string */
 #define TPV_QI1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \
        TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2,        \
-               __bv1, __bv2, __id1, __id2, __ev1, __ev2)
+               __bv1, __bv2, TPID(__id1, __id2),       \
+               __ev1, __ev2),                          \
+       TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2,        \
+               __bv1, __bv2, TPACPI_MATCH_UNKNOWN,     \
+               __ev1, __ev2)
 
+/* Outdated IBM BIOSes often lack the EC id string */
 #define TPV_QI2(__bid1, __bid2, __bv1, __bv2,          \
                __eid1, __eid2, __ev1, __ev2)           \
        TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2,      \
-               __bv1, __bv2, __eid1, __eid2, __ev1, __ev2)
+               __bv1, __bv2, TPID(__eid1, __eid2),     \
+               __ev1, __ev2),                          \
+       TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2,      \
+               __bv1, __bv2, TPACPI_MATCH_UNKNOWN,     \
+               __ev1, __ev2)
 
 #define TPV_QL0(__id1, __id2, __bv1, __bv2) \
        TPV_Q(PCI_VENDOR_ID_LENOVO, __id1, __id2, __bv1, __bv2)
 
 #define TPV_QL1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \
        TPV_Q_X(PCI_VENDOR_ID_LENOVO, __id1, __id2,     \
-               __bv1, __bv2, __id1, __id2, __ev1, __ev2)
+               __bv1, __bv2, TPID(__id1, __id2),       \
+               __ev1, __ev2)
 
 #define TPV_QL2(__bid1, __bid2, __bv1, __bv2,          \
                __eid1, __eid2, __ev1, __ev2)           \
        TPV_Q_X(PCI_VENDOR_ID_LENOVO, __bid1, __bid2,   \
-               __bv1, __bv2, __eid1, __eid2, __ev1, __ev2)
+               __bv1, __bv2, TPID(__eid1, __eid2),     \
+               __ev1, __ev2)
 
 static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = {
        /*  Numeric models ------------------ */
@@ -6313,7 +6325,7 @@ static int brightness_write(char *buf)
         * Doing it this way makes the syscall restartable in case of EINTR
         */
        rc = brightness_set(level);
-       return (rc == -EINTR)? ERESTARTSYS : rc;
+       return (rc == -EINTR)? -ERESTARTSYS : rc;
 }
 
 static struct ibm_struct brightness_driver_data = {
index 5fd2da4..c968cc3 100644 (file)
@@ -164,8 +164,8 @@ void scsi_remove_host(struct Scsi_Host *shost)
                        return;
                }
        spin_unlock_irqrestore(shost->host_lock, flags);
-       mutex_unlock(&shost->scan_mutex);
        scsi_forget_host(shost);
+       mutex_unlock(&shost->scan_mutex);
        scsi_proc_host_rm(shost);
 
        spin_lock_irqsave(shost->host_lock, flags);
index 0547a7f..47291bc 100644 (file)
@@ -952,16 +952,6 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
        return SCSI_SCAN_LUN_PRESENT;
 }
 
-static inline void scsi_destroy_sdev(struct scsi_device *sdev)
-{
-       scsi_device_set_state(sdev, SDEV_DEL);
-       if (sdev->host->hostt->slave_destroy)
-               sdev->host->hostt->slave_destroy(sdev);
-       transport_destroy_device(&sdev->sdev_gendev);
-       put_device(&sdev->sdev_dev);
-       put_device(&sdev->sdev_gendev);
-}
-
 #ifdef CONFIG_SCSI_LOGGING
 /** 
  * scsi_inq_str - print INQUIRY data from min to max index, strip trailing whitespace
@@ -1139,7 +1129,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
                        }
                }
        } else
-               scsi_destroy_sdev(sdev);
+               __scsi_remove_device(sdev);
  out:
        return res;
 }
@@ -1500,7 +1490,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
                /*
                 * the sdev we used didn't appear in the report luns scan
                 */
-               scsi_destroy_sdev(sdev);
+               __scsi_remove_device(sdev);
        return ret;
 }
 
@@ -1710,7 +1700,7 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
        shost_for_each_device(sdev, shost) {
                if (!scsi_host_scan_allowed(shost) ||
                    scsi_sysfs_add_sdev(sdev) != 0)
-                       scsi_destroy_sdev(sdev);
+                       __scsi_remove_device(sdev);
        }
 }
 
@@ -1943,7 +1933,7 @@ void scsi_free_host_dev(struct scsi_device *sdev)
 {
        BUG_ON(sdev->id != sdev->host->this_id);
 
-       scsi_destroy_sdev(sdev);
+       __scsi_remove_device(sdev);
 }
 EXPORT_SYMBOL(scsi_free_host_dev);
 
index 5c7eb63..392d8db 100644 (file)
@@ -854,82 +854,73 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
        transport_configure_device(&starget->dev);
        error = device_add(&sdev->sdev_gendev);
        if (error) {
-               put_device(sdev->sdev_gendev.parent);
                printk(KERN_INFO "error 1\n");
-               return error;
+               goto out_remove;
        }
        error = device_add(&sdev->sdev_dev);
        if (error) {
                printk(KERN_INFO "error 2\n");
-               goto clean_device;
+               device_del(&sdev->sdev_gendev);
+               goto out_remove;
        }
+       transport_add_device(&sdev->sdev_gendev);
+       sdev->is_visible = 1;
 
        /* create queue files, which may be writable, depending on the host */
        if (sdev->host->hostt->change_queue_depth)
                error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw);
        else
                error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth);
-       if (error) {
-               __scsi_remove_device(sdev);
-               goto out;
-       }
+       if (error)
+               goto out_remove;
+
        if (sdev->host->hostt->change_queue_type)
                error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw);
        else
                error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type);
-       if (error) {
-               __scsi_remove_device(sdev);
-               goto out;
-       }
+       if (error)
+               goto out_remove;
 
        error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL);
 
        if (error)
+               /* we're treating error on bsg register as non-fatal,
+                * so pretend nothing went wrong */
                sdev_printk(KERN_INFO, sdev,
                            "Failed to register bsg queue, errno=%d\n", error);
 
-       /* we're treating error on bsg register as non-fatal, so pretend
-        * nothing went wrong */
-       error = 0;
-
        /* add additional host specific attributes */
        if (sdev->host->hostt->sdev_attrs) {
                for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) {
                        error = device_create_file(&sdev->sdev_gendev,
                                        sdev->host->hostt->sdev_attrs[i]);
-                       if (error) {
-                               __scsi_remove_device(sdev);
-                               goto out;
-                       }
+                       if (error)
+                               goto out_remove;
                }
        }
 
-       transport_add_device(&sdev->sdev_gendev);
- out:
-       return error;
-
- clean_device:
-       scsi_device_set_state(sdev, SDEV_CANCEL);
-
-       device_del(&sdev->sdev_gendev);
-       transport_destroy_device(&sdev->sdev_gendev);
-       put_device(&sdev->sdev_dev);
-       put_device(&sdev->sdev_gendev);
+       return 0;
 
+ out_remove:
+       __scsi_remove_device(sdev);
        return error;
+
 }
 
 void __scsi_remove_device(struct scsi_device *sdev)
 {
        struct device *dev = &sdev->sdev_gendev;
 
-       if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
-               return;
+       if (sdev->is_visible) {
+               if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0)
+                       return;
 
-       bsg_unregister_queue(sdev->request_queue);
-       device_unregister(&sdev->sdev_dev);
-       transport_remove_device(dev);
-       device_del(dev);
+               bsg_unregister_queue(sdev->request_queue);
+               device_unregister(&sdev->sdev_dev);
+               transport_remove_device(dev);
+               device_del(dev);
+       } else
+               put_device(&sdev->sdev_dev);
        scsi_device_set_state(sdev, SDEV_DEL);
        if (sdev->host->hostt->slave_destroy)
                sdev->host->hostt->slave_destroy(sdev);
index 88da977..84be621 100644 (file)
@@ -418,7 +418,7 @@ error:
                  __func__, virt, phys, be32_to_cpu(sdt->ref_tag),
                  be16_to_cpu(sdt->app_tag));
 
-       return -EIO;
+       return -EILSEQ;
 }
 
 /*
index a2d4a19..ed7d958 100644 (file)
@@ -53,20 +53,21 @@ void sunserial_unregister_minors(struct uart_driver *drv, int count)
 EXPORT_SYMBOL(sunserial_unregister_minors);
 
 int sunserial_console_match(struct console *con, struct device_node *dp,
-                           struct uart_driver *drv, int line)
+                           struct uart_driver *drv, int line, bool ignore_line)
 {
-       int off;
-
        if (!con || of_console_device != dp)
                return 0;
 
-       off = 0;
-       if (of_console_options &&
-           *of_console_options == 'b')
-               off = 1;
+       if (!ignore_line) {
+               int off = 0;
 
-       if ((line & 1) != off)
-               return 0;
+               if (of_console_options &&
+                   *of_console_options == 'b')
+                       off = 1;
+
+               if ((line & 1) != off)
+                       return 0;
+       }
 
        con->index = line;
        drv->cons = con;
@@ -76,23 +77,24 @@ int sunserial_console_match(struct console *con, struct device_node *dp,
 }
 EXPORT_SYMBOL(sunserial_console_match);
 
-void
-sunserial_console_termios(struct console *con)
+void sunserial_console_termios(struct console *con, struct device_node *uart_dp)
 {
-       struct device_node *dp;
-       const char *od, *mode, *s;
+       const char *mode, *s;
        char mode_prop[] = "ttyX-mode";
        int baud, bits, stop, cflag;
        char parity;
 
-       dp = of_find_node_by_path("/options");
-       od = of_get_property(dp, "output-device", NULL);
-       if (!strcmp(od, "rsc")) {
-               mode = of_get_property(of_console_device,
+       if (!strcmp(uart_dp->name, "rsc") ||
+           !strcmp(uart_dp->name, "rsc-console") ||
+           !strcmp(uart_dp->name, "rsc-control")) {
+               mode = of_get_property(uart_dp,
                                       "ssp-console-modes", NULL);
                if (!mode)
                        mode = "115200,8,n,1,-";
+       } else if (!strcmp(uart_dp->name, "lom-console")) {
+               mode = "9600,8,n,1,-";
        } else {
+               struct device_node *dp;
                char c;
 
                c = 'a';
@@ -101,6 +103,7 @@ sunserial_console_termios(struct console *con)
 
                mode_prop[3] = c;
 
+               dp = of_find_node_by_path("/options");
                mode = of_get_property(dp, mode_prop, NULL);
                if (!mode)
                        mode = "9600,8,n,1,-";
index 042668a..db20579 100644 (file)
@@ -26,7 +26,8 @@ extern int sunserial_register_minors(struct uart_driver *, int);
 extern void sunserial_unregister_minors(struct uart_driver *, int);
 
 extern int sunserial_console_match(struct console *, struct device_node *,
-                                  struct uart_driver *, int);
-extern void sunserial_console_termios(struct console *);
+                                  struct uart_driver *, int, bool);
+extern void sunserial_console_termios(struct console *,
+                                     struct device_node *);
 
 #endif /* !(_SERIAL_SUN_H) */
index d548652..d14cca7 100644 (file)
@@ -566,7 +566,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m
                goto out_free_con_read_page;
 
        sunserial_console_match(&sunhv_console, op->node,
-                               &sunhv_reg, port->line);
+                               &sunhv_reg, port->line, false);
 
        err = uart_add_one_port(&sunhv_reg, port);
        if (err)
index d1ad341..d514e28 100644 (file)
@@ -883,7 +883,7 @@ static int sunsab_console_setup(struct console *con, char *options)
        printk("Console: ttyS%d (SAB82532)\n",
               (sunsab_reg.minor - 64) + con->index);
 
-       sunserial_console_termios(con);
+       sunserial_console_termios(con, to_of_device(up->port.dev)->node);
 
        switch (con->cflag & CBAUD) {
        case B150: baud = 150; break;
@@ -1027,10 +1027,12 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
                goto out1;
 
        sunserial_console_match(SUNSAB_CONSOLE(), op->node,
-                               &sunsab_reg, up[0].port.line);
+                               &sunsab_reg, up[0].port.line,
+                               false);
 
        sunserial_console_match(SUNSAB_CONSOLE(), op->node,
-                               &sunsab_reg, up[1].port.line);
+                               &sunsab_reg, up[1].port.line,
+                               false);
 
        err = uart_add_one_port(&sunsab_reg, &up[0].port);
        if (err)
@@ -1116,7 +1118,6 @@ static int __init sunsab_init(void)
                if (!sunsab_ports)
                        return -ENOMEM;
 
-               sunsab_reg.cons = SUNSAB_CONSOLE();
                err = sunserial_register_minors(&sunsab_reg, num_channels);
                if (err) {
                        kfree(sunsab_ports);
index 68d262b..170d3d6 100644 (file)
@@ -1329,11 +1329,9 @@ static void sunsu_console_write(struct console *co, const char *s,
  */
 static int __init sunsu_console_setup(struct console *co, char *options)
 {
+       static struct ktermios dummy;
+       struct ktermios termios;
        struct uart_port *port;
-       int baud = 9600;
-       int bits = 8;
-       int parity = 'n';
-       int flow = 'n';
 
        printk("Console: ttyS%d (SU)\n",
               (sunsu_reg.minor - 64) + co->index);
@@ -1352,10 +1350,15 @@ static int __init sunsu_console_setup(struct console *co, char *options)
         */
        spin_lock_init(&port->lock);
 
-       if (options)
-               uart_parse_options(options, &baud, &parity, &bits, &flow);
+       /* Get firmware console settings.  */
+       sunserial_console_termios(co, to_of_device(port->dev)->node);
 
-       return uart_set_options(port, co, baud, parity, bits, flow);
+       memset(&termios, 0, sizeof(struct ktermios));
+       termios.c_cflag = co->cflag;
+       port->mctrl |= TIOCM_DTR;
+       port->ops->set_termios(port, &termios, &dummy);
+
+       return 0;
 }
 
 static struct console sunsu_console = {
@@ -1409,6 +1412,7 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
        struct uart_sunsu_port *up;
        struct resource *rp;
        enum su_type type;
+       bool ignore_line;
        int err;
 
        type = su_get_type(dp);
@@ -1467,8 +1471,14 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m
 
        up->port.ops = &sunsu_pops;
 
+       ignore_line = false;
+       if (!strcmp(dp->name, "rsc-console") ||
+           !strcmp(dp->name, "lom-console"))
+               ignore_line = true;
+
        sunserial_console_match(SUNSU_CONSOLE(), dp,
-                               &sunsu_reg, up->port.line);
+                               &sunsu_reg, up->port.line,
+                               ignore_line);
        err = uart_add_one_port(&sunsu_reg, &up->port);
        if (err)
                goto out_unmap;
@@ -1517,6 +1527,10 @@ static const struct of_device_id su_match[] = {
                .name = "serial",
                .compatible = "su",
        },
+       {
+               .type = "serial",
+               .compatible = "su",
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, su_match);
@@ -1548,6 +1562,12 @@ static int __init sunsu_init(void)
                                num_uart++;
                }
        }
+       for_each_node_by_type(dp, "serial") {
+               if (of_device_is_compatible(dp, "su")) {
+                       if (su_get_type(dp) == SU_PORT_PORT)
+                               num_uart++;
+               }
+       }
 
        if (num_uart) {
                err = sunserial_register_minors(&sunsu_reg, num_uart);
index ef693ae..2c7a66a 100644 (file)
@@ -1180,7 +1180,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options)
               (sunzilog_reg.minor - 64) + con->index, con->index);
 
        /* Get firmware console settings.  */
-       sunserial_console_termios(con);
+       sunserial_console_termios(con, to_of_device(up->port.dev)->node);
 
        /* Firmware console speed is limited to 150-->38400 baud so
         * this hackish cflag thing is OK.
@@ -1416,7 +1416,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
 
        if (!keyboard_mouse) {
                if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
-                                           &sunzilog_reg, up[0].port.line))
+                                           &sunzilog_reg, up[0].port.line,
+                                           false))
                        up->flags |= SUNZILOG_FLAG_IS_CONS;
                err = uart_add_one_port(&sunzilog_reg, &up[0].port);
                if (err) {
@@ -1425,7 +1426,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m
                        return err;
                }
                if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
-                                           &sunzilog_reg, up[1].port.line))
+                                           &sunzilog_reg, up[1].port.line,
+                                           false))
                        up->flags |= SUNZILOG_FLAG_IS_CONS;
                err = uart_add_one_port(&sunzilog_reg, &up[1].port);
                if (err) {
index 8c85a9c..f4a6541 100644 (file)
@@ -261,7 +261,7 @@ static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
 
        memset(buf, 0xcd, 6);
        usb = go->hpi_context;
-       if (down_interruptible(&usb->i2c_lock) != 0) {
+       if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
                printk(KERN_INFO "i2c lock failed\n");
                kfree(buf);
                return -EINTR;
@@ -270,7 +270,7 @@ static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
                kfree(buf);
                return -EFAULT;
        }
-       up(&usb->i2c_lock);
+       mutex_unlock(&usb->i2c_lock);
 
        *val = (buf[0] << 8) | buf[1];
        kfree(buf);
diff --git a/drivers/staging/go7007/s2250-loader.h b/drivers/staging/go7007/s2250-loader.h
new file mode 100644 (file)
index 0000000..b7c301a
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2005-2006 Micronas USA Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ */
+
+#ifndef _S2250_LOADER_H_
+#define _S2250_LOADER_H_
+
+extern int s2250loader_init(void);
+extern void s2250loader_cleanup(void);
+
+#endif
index 42230e6..31a58e5 100644 (file)
@@ -170,7 +170,7 @@ static u32 cvm_oct_get_link(struct net_device *dev)
        return ret;
 }
 
-struct const ethtool_ops cvm_oct_ethtool_ops = {
+const struct ethtool_ops cvm_oct_ethtool_ops = {
        .get_drvinfo = cvm_oct_get_drvinfo,
        .get_settings = cvm_oct_get_settings,
        .set_settings = cvm_oct_set_settings,
index 66190b0..00dc0f4 100644 (file)
@@ -317,6 +317,6 @@ void cvm_oct_spi_uninit(struct net_device *dev)
                        cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0);
                        cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0);
                }
-               free_irq(8 + 46, &number_spi_ports);
+               free_irq(OCTEON_IRQ_RML, &number_spi_ports);
        }
 }
index b847951..492c502 100644 (file)
@@ -111,6 +111,16 @@ MODULE_PARM_DESC(disable_core_queueing, "\n"
        "\tallows packets to be sent without lock contention in the packet\n"
        "\tscheduler resulting in some cases in improved throughput.\n");
 
+
+/*
+ * The offset from mac_addr_base that should be used for the next port
+ * that is configured.  By convention, if any mgmt ports exist on the
+ * chip, they get the first mac addresses, The ports controlled by
+ * this driver are numbered sequencially following any mgmt addresses
+ * that may exist.
+ */
+static unsigned int cvm_oct_mac_addr_offset;
+
 /**
  * Periodic timer to check auto negotiation
  */
@@ -474,16 +484,30 @@ static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr)
  */
 int cvm_oct_common_init(struct net_device *dev)
 {
-       static int count;
-       char mac[8] = { 0x00, 0x00,
-               octeon_bootinfo->mac_addr_base[0],
-               octeon_bootinfo->mac_addr_base[1],
-               octeon_bootinfo->mac_addr_base[2],
-               octeon_bootinfo->mac_addr_base[3],
-               octeon_bootinfo->mac_addr_base[4],
-               octeon_bootinfo->mac_addr_base[5] + count
-       };
        struct octeon_ethernet *priv = netdev_priv(dev);
+       struct sockaddr sa;
+       u64 mac = ((u64)(octeon_bootinfo->mac_addr_base[0] & 0xff) << 40) |
+               ((u64)(octeon_bootinfo->mac_addr_base[1] & 0xff) << 32) |
+               ((u64)(octeon_bootinfo->mac_addr_base[2] & 0xff) << 24) |
+               ((u64)(octeon_bootinfo->mac_addr_base[3] & 0xff) << 16) |
+               ((u64)(octeon_bootinfo->mac_addr_base[4] & 0xff) << 8) |
+               (u64)(octeon_bootinfo->mac_addr_base[5] & 0xff);
+
+       mac += cvm_oct_mac_addr_offset;
+       sa.sa_data[0] = (mac >> 40) & 0xff;
+       sa.sa_data[1] = (mac >> 32) & 0xff;
+       sa.sa_data[2] = (mac >> 24) & 0xff;
+       sa.sa_data[3] = (mac >> 16) & 0xff;
+       sa.sa_data[4] = (mac >> 8) & 0xff;
+       sa.sa_data[5] = mac & 0xff;
+
+       if (cvm_oct_mac_addr_offset >= octeon_bootinfo->mac_addr_count)
+               printk(KERN_DEBUG "%s: Using MAC outside of the assigned range:"
+                       " %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
+                       sa.sa_data[0] & 0xff, sa.sa_data[1] & 0xff,
+                       sa.sa_data[2] & 0xff, sa.sa_data[3] & 0xff,
+                       sa.sa_data[4] & 0xff, sa.sa_data[5] & 0xff);
+       cvm_oct_mac_addr_offset++;
 
        /*
         * Force the interface to use the POW send if always_use_pow
@@ -496,14 +520,12 @@ int cvm_oct_common_init(struct net_device *dev)
        if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM)
                dev->features |= NETIF_F_IP_CSUM;
 
-       count++;
-
        /* We do our own locking, Linux doesn't need to */
        dev->features |= NETIF_F_LLTX;
        SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops);
 
        cvm_oct_mdio_setup_device(dev);
-       dev->netdev_ops->ndo_set_mac_address(dev, mac);
+       dev->netdev_ops->ndo_set_mac_address(dev, &sa);
        dev->netdev_ops->ndo_change_mtu(dev, dev->mtu);
 
        /*
@@ -620,6 +642,13 @@ static int __init cvm_oct_init_module(void)
 
        pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION);
 
+       if (OCTEON_IS_MODEL(OCTEON_CN52XX))
+               cvm_oct_mac_addr_offset = 2; /* First two are the mgmt ports. */
+       else if (OCTEON_IS_MODEL(OCTEON_CN56XX))
+               cvm_oct_mac_addr_offset = 1; /* First one is the mgmt port. */
+       else
+               cvm_oct_mac_addr_offset = 0;
+
        cvm_oct_proc_initialize();
        cvm_oct_rx_initialize();
        cvm_oct_configure_common_hw();
index f24d041..4d227b1 100644 (file)
@@ -317,7 +317,7 @@ static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
 
 static struct platform_driver platform_wdt_driver = {
        .driver = {
-               .name = "watchdog",
+               .name = "pnx4008-watchdog",
                .owner  = THIS_MODULE,
        },
        .probe = pnx4008_wdt_probe,
@@ -352,4 +352,4 @@ MODULE_PARM_DESC(nowayout,
 
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
-MODULE_ALIAS("platform:watchdog");
+MODULE_ALIAS("platform:pnx4008-watchdog");
index 51c94e2..bcc5357 100644 (file)
@@ -343,18 +343,7 @@ int __v9fs_fscache_release_page(struct page *page, gfp_t gfp)
 
        BUG_ON(!vcookie->fscache);
 
-       if (PageFsCache(page)) {
-               if (fscache_check_page_write(vcookie->fscache, page)) {
-                       if (!(gfp & __GFP_WAIT))
-                               return 0;
-                       fscache_wait_on_page_write(vcookie->fscache, page);
-               }
-
-               fscache_uncache_page(vcookie->fscache, page);
-               ClearPageFsCache(page);
-       }
-
-       return 1;
+       return fscache_maybe_release_page(vnode->cache, page, gfp);
 }
 
 void __v9fs_fscache_invalidate_page(struct page *page)
@@ -368,7 +357,6 @@ void __v9fs_fscache_invalidate_page(struct page *page)
                fscache_wait_on_page_write(vcookie->fscache, page);
                BUG_ON(!PageLocked(page));
                fscache_uncache_page(vcookie->fscache, page);
-               ClearPageFsCache(page);
        }
 }
 
index 681c2a7..39b3016 100644 (file)
@@ -315,7 +315,6 @@ static void afs_invalidatepage(struct page *page, unsigned long offset)
                        struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
                        fscache_wait_on_page_write(vnode->cache, page);
                        fscache_uncache_page(vnode->cache, page);
-                       ClearPageFsCache(page);
                }
 #endif
 
@@ -349,17 +348,9 @@ static int afs_releasepage(struct page *page, gfp_t gfp_flags)
        /* deny if page is being written to the cache and the caller hasn't
         * elected to wait */
 #ifdef CONFIG_AFS_FSCACHE
-       if (PageFsCache(page)) {
-               if (fscache_check_page_write(vnode->cache, page)) {
-                       if (!(gfp_flags & __GFP_WAIT)) {
-                               _leave(" = F [cache busy]");
-                               return 0;
-                       }
-                       fscache_wait_on_page_write(vnode->cache, page);
-               }
-
-               fscache_uncache_page(vnode->cache, page);
-               ClearPageFsCache(page);
+       if (!fscache_maybe_release_page(vnode->cache, page, gfp_flags)) {
+               _leave(" = F [cache busy]");
+               return 0;
        }
 #endif
 
index 431accd..2708931 100644 (file)
@@ -114,8 +114,9 @@ nomem_lookup_data:
 
 /*
  * attempt to look up the nominated node in this cache
+ * - return -ETIMEDOUT to be scheduled again
  */
-static void cachefiles_lookup_object(struct fscache_object *_object)
+static int cachefiles_lookup_object(struct fscache_object *_object)
 {
        struct cachefiles_lookup_data *lookup_data;
        struct cachefiles_object *parent, *object;
@@ -145,13 +146,15 @@ static void cachefiles_lookup_object(struct fscache_object *_object)
            object->fscache.cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX)
                cachefiles_attr_changed(&object->fscache);
 
-       if (ret < 0) {
-               printk(KERN_WARNING "CacheFiles: Lookup failed error %d\n",
-                      ret);
+       if (ret < 0 && ret != -ETIMEDOUT) {
+               if (ret != -ENOBUFS)
+                       printk(KERN_WARNING
+                              "CacheFiles: Lookup failed error %d\n", ret);
                fscache_object_lookup_error(&object->fscache);
        }
 
        _leave(" [%d]", ret);
+       return ret;
 }
 
 /*
@@ -331,6 +334,7 @@ static void cachefiles_put_object(struct fscache_object *_object)
                }
 
                cache = object->fscache.cache;
+               fscache_object_destroy(&object->fscache);
                kmem_cache_free(cachefiles_object_jar, object);
                fscache_object_destroyed(cache);
        }
@@ -403,12 +407,26 @@ static int cachefiles_attr_changed(struct fscache_object *_object)
        if (oi_size == ni_size)
                return 0;
 
-       newattrs.ia_size = ni_size;
-       newattrs.ia_valid = ATTR_SIZE;
-
        cachefiles_begin_secure(cache, &saved_cred);
        mutex_lock(&object->backer->d_inode->i_mutex);
+
+       /* if there's an extension to a partial page at the end of the backing
+        * file, we need to discard the partial page so that we pick up new
+        * data after it */
+       if (oi_size & ~PAGE_MASK && ni_size > oi_size) {
+               _debug("discard tail %llx", oi_size);
+               newattrs.ia_valid = ATTR_SIZE;
+               newattrs.ia_size = oi_size & PAGE_MASK;
+               ret = notify_change(object->backer, &newattrs);
+               if (ret < 0)
+                       goto truncate_failed;
+       }
+
+       newattrs.ia_valid = ATTR_SIZE;
+       newattrs.ia_size = ni_size;
        ret = notify_change(object->backer, &newattrs);
+
+truncate_failed:
        mutex_unlock(&object->backer->d_inode->i_mutex);
        cachefiles_end_secure(cache, saved_cred);
 
index 4ce818a..14ac480 100644 (file)
 #include <linux/security.h>
 #include "internal.h"
 
-static int cachefiles_wait_bit(void *flags)
+#define CACHEFILES_KEYBUF_SIZE 512
+
+/*
+ * dump debugging info about an object
+ */
+static noinline
+void __cachefiles_printk_object(struct cachefiles_object *object,
+                               const char *prefix,
+                               u8 *keybuf)
 {
-       schedule();
-       return 0;
+       struct fscache_cookie *cookie;
+       unsigned keylen, loop;
+
+       printk(KERN_ERR "%sobject: OBJ%x\n",
+              prefix, object->fscache.debug_id);
+       printk(KERN_ERR "%sobjstate=%s fl=%lx swfl=%lx ev=%lx[%lx]\n",
+              prefix, fscache_object_states[object->fscache.state],
+              object->fscache.flags, object->fscache.work.flags,
+              object->fscache.events,
+              object->fscache.event_mask & FSCACHE_OBJECT_EVENTS_MASK);
+       printk(KERN_ERR "%sops=%u inp=%u exc=%u\n",
+              prefix, object->fscache.n_ops, object->fscache.n_in_progress,
+              object->fscache.n_exclusive);
+       printk(KERN_ERR "%sparent=%p\n",
+              prefix, object->fscache.parent);
+
+       spin_lock(&object->fscache.lock);
+       cookie = object->fscache.cookie;
+       if (cookie) {
+               printk(KERN_ERR "%scookie=%p [pr=%p nd=%p fl=%lx]\n",
+                      prefix,
+                      object->fscache.cookie,
+                      object->fscache.cookie->parent,
+                      object->fscache.cookie->netfs_data,
+                      object->fscache.cookie->flags);
+               if (keybuf)
+                       keylen = cookie->def->get_key(cookie->netfs_data, keybuf,
+                                                     CACHEFILES_KEYBUF_SIZE);
+               else
+                       keylen = 0;
+       } else {
+               printk(KERN_ERR "%scookie=NULL\n", prefix);
+               keylen = 0;
+       }
+       spin_unlock(&object->fscache.lock);
+
+       if (keylen) {
+               printk(KERN_ERR "%skey=[%u] '", prefix, keylen);
+               for (loop = 0; loop < keylen; loop++)
+                       printk("%02x", keybuf[loop]);
+               printk("'\n");
+       }
+}
+
+/*
+ * dump debugging info about a pair of objects
+ */
+static noinline void cachefiles_printk_object(struct cachefiles_object *object,
+                                             struct cachefiles_object *xobject)
+{
+       u8 *keybuf;
+
+       keybuf = kmalloc(CACHEFILES_KEYBUF_SIZE, GFP_NOIO);
+       if (object)
+               __cachefiles_printk_object(object, "", keybuf);
+       if (xobject)
+               __cachefiles_printk_object(xobject, "x", keybuf);
+       kfree(keybuf);
 }
 
 /*
  * record the fact that an object is now active
  */
-static void cachefiles_mark_object_active(struct cachefiles_cache *cache,
-                                         struct cachefiles_object *object)
+static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
+                                        struct cachefiles_object *object)
 {
        struct cachefiles_object *xobject;
        struct rb_node **_p, *_parent = NULL;
@@ -42,8 +106,11 @@ static void cachefiles_mark_object_active(struct cachefiles_cache *cache,
 try_again:
        write_lock(&cache->active_lock);
 
-       if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags))
+       if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
+               printk(KERN_ERR "CacheFiles: Error: Object already active\n");
+               cachefiles_printk_object(object, NULL);
                BUG();
+       }
 
        dentry = object->dentry;
        _p = &cache->active_nodes.rb_node;
@@ -66,8 +133,8 @@ try_again:
        rb_insert_color(&object->active_node, &cache->active_nodes);
 
        write_unlock(&cache->active_lock);
-       _leave("");
-       return;
+       _leave(" = 0");
+       return 0;
 
        /* an old object from a previous incarnation is hogging the slot - we
         * need to wait for it to be destroyed */
@@ -76,44 +143,70 @@ wait_for_old_object:
                printk(KERN_ERR "\n");
                printk(KERN_ERR "CacheFiles: Error:"
                       " Unexpected object collision\n");
-               printk(KERN_ERR "xobject: OBJ%x\n",
-                      xobject->fscache.debug_id);
-               printk(KERN_ERR "xobjstate=%s\n",
-                      fscache_object_states[xobject->fscache.state]);
-               printk(KERN_ERR "xobjflags=%lx\n", xobject->fscache.flags);
-               printk(KERN_ERR "xobjevent=%lx [%lx]\n",
-                      xobject->fscache.events, xobject->fscache.event_mask);
-               printk(KERN_ERR "xops=%u inp=%u exc=%u\n",
-                      xobject->fscache.n_ops, xobject->fscache.n_in_progress,
-                      xobject->fscache.n_exclusive);
-               printk(KERN_ERR "xcookie=%p [pr=%p nd=%p fl=%lx]\n",
-                      xobject->fscache.cookie,
-                      xobject->fscache.cookie->parent,
-                      xobject->fscache.cookie->netfs_data,
-                      xobject->fscache.cookie->flags);
-               printk(KERN_ERR "xparent=%p\n",
-                      xobject->fscache.parent);
-               printk(KERN_ERR "object: OBJ%x\n",
-                      object->fscache.debug_id);
-               printk(KERN_ERR "cookie=%p [pr=%p nd=%p fl=%lx]\n",
-                      object->fscache.cookie,
-                      object->fscache.cookie->parent,
-                      object->fscache.cookie->netfs_data,
-                      object->fscache.cookie->flags);
-               printk(KERN_ERR "parent=%p\n",
-                      object->fscache.parent);
+               cachefiles_printk_object(object, xobject);
                BUG();
        }
        atomic_inc(&xobject->usage);
        write_unlock(&cache->active_lock);
 
-       _debug(">>> wait");
-       wait_on_bit(&xobject->flags, CACHEFILES_OBJECT_ACTIVE,
-                   cachefiles_wait_bit, TASK_UNINTERRUPTIBLE);
-       _debug("<<< waited");
+       if (test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) {
+               wait_queue_head_t *wq;
+
+               signed long timeout = 60 * HZ;
+               wait_queue_t wait;
+               bool requeue;
+
+               /* if the object we're waiting for is queued for processing,
+                * then just put ourselves on the queue behind it */
+               if (slow_work_is_queued(&xobject->fscache.work)) {
+                       _debug("queue OBJ%x behind OBJ%x immediately",
+                              object->fscache.debug_id,
+                              xobject->fscache.debug_id);
+                       goto requeue;
+               }
+
+               /* otherwise we sleep until either the object we're waiting for
+                * is done, or the slow-work facility wants the thread back to
+                * do other work */
+               wq = bit_waitqueue(&xobject->flags, CACHEFILES_OBJECT_ACTIVE);
+               init_wait(&wait);
+               requeue = false;
+               do {
+                       prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
+                       if (!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags))
+                               break;
+                       requeue = slow_work_sleep_till_thread_needed(
+                               &object->fscache.work, &timeout);
+               } while (timeout > 0 && !requeue);
+               finish_wait(wq, &wait);
+
+               if (requeue &&
+                   test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) {
+                       _debug("queue OBJ%x behind OBJ%x after wait",
+                              object->fscache.debug_id,
+                              xobject->fscache.debug_id);
+                       goto requeue;
+               }
+
+               if (timeout <= 0) {
+                       printk(KERN_ERR "\n");
+                       printk(KERN_ERR "CacheFiles: Error: Overlong"
+                              " wait for old active object to go away\n");
+                       cachefiles_printk_object(object, xobject);
+                       goto requeue;
+               }
+       }
+
+       ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags));
 
        cache->cache.ops->put_object(&xobject->fscache);
        goto try_again;
+
+requeue:
+       clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
+       cache->cache.ops->put_object(&xobject->fscache);
+       _leave(" = -ETIMEDOUT");
+       return -ETIMEDOUT;
 }
 
 /*
@@ -254,7 +347,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
 
        dir = dget_parent(object->dentry);
 
-       mutex_lock(&dir->d_inode->i_mutex);
+       mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
        ret = cachefiles_bury_object(cache, dir, object->dentry);
 
        dput(dir);
@@ -307,7 +400,7 @@ lookup_again:
        /* search the current directory for the element name */
        _debug("lookup '%s'", name);
 
-       mutex_lock(&dir->d_inode->i_mutex);
+       mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
 
        start = jiffies;
        next = lookup_one_len(name, dir, nlen);
@@ -418,12 +511,15 @@ lookup_again:
        }
 
        /* note that we're now using this object */
-       cachefiles_mark_object_active(cache, object);
+       ret = cachefiles_mark_object_active(cache, object);
 
        mutex_unlock(&dir->d_inode->i_mutex);
        dput(dir);
        dir = NULL;
 
+       if (ret == -ETIMEDOUT)
+               goto mark_active_timed_out;
+
        _debug("=== OBTAINED_OBJECT ===");
 
        if (object->new) {
@@ -467,6 +563,10 @@ create_error:
                cachefiles_io_error(cache, "Create/mkdir failed");
        goto error;
 
+mark_active_timed_out:
+       _debug("mark active timed out");
+       goto release_dentry;
+
 check_error:
        _debug("check error %d", ret);
        write_lock(&cache->active_lock);
@@ -474,7 +574,7 @@ check_error:
        clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
        wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE);
        write_unlock(&cache->active_lock);
-
+release_dentry:
        dput(object->dentry);
        object->dentry = NULL;
        goto error_out;
@@ -495,9 +595,6 @@ error:
 error_out2:
        dput(dir);
 error_out:
-       if (ret == -ENOSPC)
-               ret = -ENOBUFS;
-
        _leave(" = error %d", -ret);
        return ret;
 }
index a69787e..1d83325 100644 (file)
@@ -40,8 +40,10 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode,
 
        _debug("--- monitor %p %lx ---", page, page->flags);
 
-       if (!PageUptodate(page) && !PageError(page))
-               dump_stack();
+       if (!PageUptodate(page) && !PageError(page)) {
+               /* unlocked, not uptodate and not erronous? */
+               _debug("page probably truncated");
+       }
 
        /* remove from the waitqueue */
        list_del(&wait->task_list);
@@ -60,6 +62,84 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode,
        return 0;
 }
 
+/*
+ * handle a probably truncated page
+ * - check to see if the page is still relevant and reissue the read if
+ *   possible
+ * - return -EIO on error, -ENODATA if the page is gone, -EINPROGRESS if we
+ *   must wait again and 0 if successful
+ */
+static int cachefiles_read_reissue(struct cachefiles_object *object,
+                                  struct cachefiles_one_read *monitor)
+{
+       struct address_space *bmapping = object->backer->d_inode->i_mapping;
+       struct page *backpage = monitor->back_page, *backpage2;
+       int ret;
+
+       kenter("{ino=%lx},{%lx,%lx}",
+              object->backer->d_inode->i_ino,
+              backpage->index, backpage->flags);
+
+       /* skip if the page was truncated away completely */
+       if (backpage->mapping != bmapping) {
+               kleave(" = -ENODATA [mapping]");
+               return -ENODATA;
+       }
+
+       backpage2 = find_get_page(bmapping, backpage->index);
+       if (!backpage2) {
+               kleave(" = -ENODATA [gone]");
+               return -ENODATA;
+       }
+
+       if (backpage != backpage2) {
+               put_page(backpage2);
+               kleave(" = -ENODATA [different]");
+               return -ENODATA;
+       }
+
+       /* the page is still there and we already have a ref on it, so we don't
+        * need a second */
+       put_page(backpage2);
+
+       INIT_LIST_HEAD(&monitor->op_link);
+       add_page_wait_queue(backpage, &monitor->monitor);
+
+       if (trylock_page(backpage)) {
+               ret = -EIO;
+               if (PageError(backpage))
+                       goto unlock_discard;
+               ret = 0;
+               if (PageUptodate(backpage))
+                       goto unlock_discard;
+
+               kdebug("reissue read");
+               ret = bmapping->a_ops->readpage(NULL, backpage);
+               if (ret < 0)
+                       goto unlock_discard;
+       }
+
+       /* but the page may have been read before the monitor was installed, so
+        * the monitor may miss the event - so we have to ensure that we do get
+        * one in such a case */
+       if (trylock_page(backpage)) {
+               _debug("jumpstart %p {%lx}", backpage, backpage->flags);
+               unlock_page(backpage);
+       }
+
+       /* it'll reappear on the todo list */
+       kleave(" = -EINPROGRESS");
+       return -EINPROGRESS;
+
+unlock_discard:
+       unlock_page(backpage);
+       spin_lock_irq(&object->work_lock);
+       list_del(&monitor->op_link);
+       spin_unlock_irq(&object->work_lock);
+       kleave(" = %d", ret);
+       return ret;
+}
+
 /*
  * copy data from backing pages to netfs pages to complete a read operation
  * - driven by FS-Cache's thread pool
@@ -92,20 +172,26 @@ static void cachefiles_read_copier(struct fscache_operation *_op)
 
                _debug("- copy {%lu}", monitor->back_page->index);
 
-               error = -EIO;
+       recheck:
                if (PageUptodate(monitor->back_page)) {
                        copy_highpage(monitor->netfs_page, monitor->back_page);
 
                        pagevec_add(&pagevec, monitor->netfs_page);
                        fscache_mark_pages_cached(monitor->op, &pagevec);
                        error = 0;
-               }
-
-               if (error)
+               } else if (!PageError(monitor->back_page)) {
+                       /* the page has probably been truncated */
+                       error = cachefiles_read_reissue(object, monitor);
+                       if (error == -EINPROGRESS)
+                               goto next;
+                       goto recheck;
+               } else {
                        cachefiles_io_error_obj(
                                object,
                                "Readpage failed on backing file %lx",
                                (unsigned long) monitor->back_page->flags);
+                       error = -EIO;
+               }
 
                page_cache_release(monitor->back_page);
 
@@ -114,6 +200,7 @@ static void cachefiles_read_copier(struct fscache_operation *_op)
                fscache_put_retrieval(op);
                kfree(monitor);
 
+       next:
                /* let the thread pool have some air occasionally */
                max--;
                if (max < 0 || need_resched()) {
@@ -333,7 +420,8 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
 
        shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
 
-       op->op.flags = FSCACHE_OP_FAST;
+       op->op.flags &= FSCACHE_OP_KEEP_FLAGS;
+       op->op.flags |= FSCACHE_OP_FAST;
        op->op.processor = cachefiles_read_copier;
 
        pagevec_init(&pagevec, 0);
@@ -639,7 +727,8 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
 
        pagevec_init(&pagevec, 0);
 
-       op->op.flags = FSCACHE_OP_FAST;
+       op->op.flags &= FSCACHE_OP_KEEP_FLAGS;
+       op->op.flags |= FSCACHE_OP_FAST;
        op->op.processor = cachefiles_read_copier;
 
        INIT_LIST_HEAD(&backpages);
@@ -801,7 +890,8 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
        struct cachefiles_cache *cache;
        mm_segment_t old_fs;
        struct file *file;
-       loff_t pos;
+       loff_t pos, eof;
+       size_t len;
        void *data;
        int ret;
 
@@ -835,15 +925,29 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
                ret = -EIO;
                if (file->f_op->write) {
                        pos = (loff_t) page->index << PAGE_SHIFT;
+
+                       /* we mustn't write more data than we have, so we have
+                        * to beware of a partial page at EOF */
+                       eof = object->fscache.store_limit_l;
+                       len = PAGE_SIZE;
+                       if (eof & ~PAGE_MASK) {
+                               ASSERTCMP(pos, <, eof);
+                               if (eof - pos < PAGE_SIZE) {
+                                       _debug("cut short %llx to %llx",
+                                              pos, eof);
+                                       len = eof - pos;
+                                       ASSERTCMP(pos + len, ==, eof);
+                               }
+                       }
+
                        data = kmap(page);
                        old_fs = get_fs();
                        set_fs(KERNEL_DS);
                        ret = file->f_op->write(
-                               file, (const void __user *) data, PAGE_SIZE,
-                               &pos);
+                               file, (const void __user *) data, len, &pos);
                        set_fs(old_fs);
                        kunmap(page);
-                       if (ret != PAGE_SIZE)
+                       if (ret != len)
                                ret = -EIO;
                }
                fput(file);
index 145540a..094ea65 100644 (file)
@@ -1,3 +1,12 @@
+Version 1.61
+------------
+Fix append problem to Samba servers (files opened with O_APPEND could
+have duplicated data). Fix oops in cifs_lookup. Workaround problem
+mounting to OS/400 Netserve. Fix oops in cifs_get_tcp_session.
+Disable use of server inode numbers when server only
+partially supports them (e.g. for one server querying inode numbers on
+FindFirst fails but QPathInfo queries works).
+
 Version 1.60
 -------------
 Fix memory leak in reconnect.  Fix oops in DFS mount error path.
index 9a5e4f5..29f1da7 100644 (file)
@@ -1037,7 +1037,7 @@ init_cifs(void)
        if (rc)
                goto out_unregister_key_type;
 #endif
-       rc = slow_work_register_user();
+       rc = slow_work_register_user(THIS_MODULE);
        if (rc)
                goto out_unregister_resolver_key;
 
index 627a60a..1f42f77 100644 (file)
@@ -214,8 +214,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
                posix_flags |= SMB_O_EXCL;
        if (oflags & O_TRUNC)
                posix_flags |= SMB_O_TRUNC;
-       if (oflags & O_APPEND)
-               posix_flags |= SMB_O_APPEND;
        if (oflags & O_SYNC)
                posix_flags |= SMB_O_SYNC;
        if (oflags & O_DIRECTORY)
@@ -643,9 +641,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
         * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
         * the VFS handle the create.
         */
-       if (nd->flags & LOOKUP_EXCL) {
+       if (nd && (nd->flags & LOOKUP_EXCL)) {
                d_instantiate(direntry, NULL);
-               return 0;
+               return NULL;
        }
 
        /* can not grab the rename sem here since it would
@@ -675,7 +673,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
         * reduction in network traffic in the other paths.
         */
        if (pTcon->unix_ext) {
-               if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
+               if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
                     (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
                     (nd->intent.open.flags & O_CREAT)) {
                        rc = cifs_posix_open(full_path, &newInode, nd->path.mnt,
index 9bbb8ce..864dac2 100644 (file)
@@ -54,3 +54,10 @@ config FSCACHE_DEBUG
          enabled by setting bits in /sys/modules/fscache/parameter/debug.
 
          See Documentation/filesystems/caching/fscache.txt for more information.
+
+config FSCACHE_OBJECT_LIST
+       bool "Maintain global object list for debugging purposes"
+       depends on FSCACHE && PROC_FS
+       help
+         Maintain a global list of active fscache objects that can be
+         retrieved through /proc/fs/fscache/objects for debugging purposes
index 91571b9..6d56153 100644 (file)
@@ -15,5 +15,6 @@ fscache-y := \
 fscache-$(CONFIG_PROC_FS) += proc.o
 fscache-$(CONFIG_FSCACHE_STATS) += stats.o
 fscache-$(CONFIG_FSCACHE_HISTOGRAM) += histogram.o
+fscache-$(CONFIG_FSCACHE_OBJECT_LIST) += object-list.o
 
 obj-$(CONFIG_FSCACHE) := fscache.o
index e21985b..6a3c48a 100644 (file)
@@ -263,6 +263,7 @@ int fscache_add_cache(struct fscache_cache *cache,
        spin_lock(&cache->object_list_lock);
        list_add_tail(&ifsdef->cache_link, &cache->object_list);
        spin_unlock(&cache->object_list_lock);
+       fscache_objlist_add(ifsdef);
 
        /* add the cache's netfs definition index object to the top level index
         * cookie as a known backing object */
@@ -380,11 +381,15 @@ void fscache_withdraw_cache(struct fscache_cache *cache)
 
        /* make sure all pages pinned by operations on behalf of the netfs are
         * written to disk */
+       fscache_stat(&fscache_n_cop_sync_cache);
        cache->ops->sync_cache(cache);
+       fscache_stat_d(&fscache_n_cop_sync_cache);
 
        /* dissociate all the netfs pages backed by this cache from the block
         * mappings in the cache */
+       fscache_stat(&fscache_n_cop_dissociate_pages);
        cache->ops->dissociate_pages(cache);
+       fscache_stat_d(&fscache_n_cop_dissociate_pages);
 
        /* we now have to destroy all the active objects pertaining to this
         * cache - which we do by passing them off to thread pool to be
index 72fd18f..9905350 100644 (file)
@@ -36,6 +36,7 @@ void fscache_cookie_init_once(void *_cookie)
 
        memset(cookie, 0, sizeof(*cookie));
        spin_lock_init(&cookie->lock);
+       spin_lock_init(&cookie->stores_lock);
        INIT_HLIST_HEAD(&cookie->backing_objects);
 }
 
@@ -102,7 +103,9 @@ struct fscache_cookie *__fscache_acquire_cookie(
        cookie->netfs_data      = netfs_data;
        cookie->flags           = 0;
 
-       INIT_RADIX_TREE(&cookie->stores, GFP_NOFS);
+       /* radix tree insertion won't use the preallocation pool unless it's
+        * told it may not wait */
+       INIT_RADIX_TREE(&cookie->stores, GFP_NOFS & ~__GFP_WAIT);
 
        switch (cookie->def->type) {
        case FSCACHE_COOKIE_TYPE_INDEX:
@@ -249,7 +252,9 @@ static int fscache_alloc_object(struct fscache_cache *cache,
 
        /* ask the cache to allocate an object (we may end up with duplicate
         * objects at this stage, but we sort that out later) */
+       fscache_stat(&fscache_n_cop_alloc_object);
        object = cache->ops->alloc_object(cache, cookie);
+       fscache_stat_d(&fscache_n_cop_alloc_object);
        if (IS_ERR(object)) {
                fscache_stat(&fscache_n_object_no_alloc);
                ret = PTR_ERR(object);
@@ -270,8 +275,11 @@ static int fscache_alloc_object(struct fscache_cache *cache,
        /* only attach if we managed to allocate all we needed, otherwise
         * discard the object we just allocated and instead use the one
         * attached to the cookie */
-       if (fscache_attach_object(cookie, object) < 0)
+       if (fscache_attach_object(cookie, object) < 0) {
+               fscache_stat(&fscache_n_cop_put_object);
                cache->ops->put_object(object);
+               fscache_stat_d(&fscache_n_cop_put_object);
+       }
 
        _leave(" = 0");
        return 0;
@@ -287,7 +295,9 @@ object_already_extant:
        return 0;
 
 error_put:
+       fscache_stat(&fscache_n_cop_put_object);
        cache->ops->put_object(object);
+       fscache_stat_d(&fscache_n_cop_put_object);
 error:
        _leave(" = %d", ret);
        return ret;
@@ -349,6 +359,8 @@ static int fscache_attach_object(struct fscache_cookie *cookie,
        object->cookie = cookie;
        atomic_inc(&cookie->usage);
        hlist_add_head(&object->cookie_link, &cookie->backing_objects);
+
+       fscache_objlist_add(object);
        ret = 0;
 
 cant_attach_object:
@@ -403,6 +415,8 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
        unsigned long event;
 
        fscache_stat(&fscache_n_relinquishes);
+       if (retire)
+               fscache_stat(&fscache_n_relinquishes_retire);
 
        if (!cookie) {
                fscache_stat(&fscache_n_relinquishes_null);
@@ -428,12 +442,8 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
 
        event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;
 
-       /* detach pointers back to the netfs */
        spin_lock(&cookie->lock);
 
-       cookie->netfs_data      = NULL;
-       cookie->def             = NULL;
-
        /* break links with all the active objects */
        while (!hlist_empty(&cookie->backing_objects)) {
                object = hlist_entry(cookie->backing_objects.first,
@@ -456,6 +466,10 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
                        BUG();
        }
 
+       /* detach pointers back to the netfs */
+       cookie->netfs_data      = NULL;
+       cookie->def             = NULL;
+
        spin_unlock(&cookie->lock);
 
        if (cookie->parent) {
index 1c34130..edd7434 100644 (file)
@@ -17,6 +17,7 @@
  * - cache->object_list_lock
  * - object->lock
  * - object->parent->lock
+ * - cookie->stores_lock
  * - fscache_thread_lock
  *
  */
@@ -88,10 +89,23 @@ extern int fscache_wait_bit_interruptible(void *);
 /*
  * object.c
  */
+extern const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5];
+
 extern void fscache_withdrawing_object(struct fscache_cache *,
                                       struct fscache_object *);
 extern void fscache_enqueue_object(struct fscache_object *);
 
+/*
+ * object-list.c
+ */
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+extern const struct file_operations fscache_objlist_fops;
+
+extern void fscache_objlist_add(struct fscache_object *);
+#else
+#define fscache_objlist_add(object) do {} while(0)
+#endif
+
 /*
  * operation.c
  */
@@ -99,6 +113,7 @@ extern int fscache_submit_exclusive_op(struct fscache_object *,
                                       struct fscache_operation *);
 extern int fscache_submit_op(struct fscache_object *,
                             struct fscache_operation *);
+extern int fscache_cancel_op(struct fscache_operation *);
 extern void fscache_abort_object(struct fscache_object *);
 extern void fscache_start_operations(struct fscache_object *);
 extern void fscache_operation_gc(struct work_struct *);
@@ -127,6 +142,8 @@ extern atomic_t fscache_n_op_enqueue;
 extern atomic_t fscache_n_op_deferred_release;
 extern atomic_t fscache_n_op_release;
 extern atomic_t fscache_n_op_gc;
+extern atomic_t fscache_n_op_cancelled;
+extern atomic_t fscache_n_op_rejected;
 
 extern atomic_t fscache_n_attr_changed;
 extern atomic_t fscache_n_attr_changed_ok;
@@ -138,6 +155,8 @@ extern atomic_t fscache_n_allocs;
 extern atomic_t fscache_n_allocs_ok;
 extern atomic_t fscache_n_allocs_wait;
 extern atomic_t fscache_n_allocs_nobufs;
+extern atomic_t fscache_n_allocs_intr;
+extern atomic_t fscache_n_allocs_object_dead;
 extern atomic_t fscache_n_alloc_ops;
 extern atomic_t fscache_n_alloc_op_waits;
 
@@ -148,6 +167,7 @@ extern atomic_t fscache_n_retrievals_nodata;
 extern atomic_t fscache_n_retrievals_nobufs;
 extern atomic_t fscache_n_retrievals_intr;
 extern atomic_t fscache_n_retrievals_nomem;
+extern atomic_t fscache_n_retrievals_object_dead;
 extern atomic_t fscache_n_retrieval_ops;
 extern atomic_t fscache_n_retrieval_op_waits;
 
@@ -158,6 +178,14 @@ extern atomic_t fscache_n_stores_nobufs;
 extern atomic_t fscache_n_stores_oom;
 extern atomic_t fscache_n_store_ops;
 extern atomic_t fscache_n_store_calls;
+extern atomic_t fscache_n_store_pages;
+extern atomic_t fscache_n_store_radix_deletes;
+extern atomic_t fscache_n_store_pages_over_limit;
+
+extern atomic_t fscache_n_store_vmscan_not_storing;
+extern atomic_t fscache_n_store_vmscan_gone;
+extern atomic_t fscache_n_store_vmscan_busy;
+extern atomic_t fscache_n_store_vmscan_cancelled;
 
 extern atomic_t fscache_n_marks;
 extern atomic_t fscache_n_uncaches;
@@ -176,6 +204,7 @@ extern atomic_t fscache_n_updates_run;
 extern atomic_t fscache_n_relinquishes;
 extern atomic_t fscache_n_relinquishes_null;
 extern atomic_t fscache_n_relinquishes_waitcrt;
+extern atomic_t fscache_n_relinquishes_retire;
 
 extern atomic_t fscache_n_cookie_index;
 extern atomic_t fscache_n_cookie_data;
@@ -186,6 +215,7 @@ extern atomic_t fscache_n_object_no_alloc;
 extern atomic_t fscache_n_object_lookups;
 extern atomic_t fscache_n_object_lookups_negative;
 extern atomic_t fscache_n_object_lookups_positive;
+extern atomic_t fscache_n_object_lookups_timed_out;
 extern atomic_t fscache_n_object_created;
 extern atomic_t fscache_n_object_avail;
 extern atomic_t fscache_n_object_dead;
@@ -195,15 +225,41 @@ extern atomic_t fscache_n_checkaux_okay;
 extern atomic_t fscache_n_checkaux_update;
 extern atomic_t fscache_n_checkaux_obsolete;
 
+extern atomic_t fscache_n_cop_alloc_object;
+extern atomic_t fscache_n_cop_lookup_object;
+extern atomic_t fscache_n_cop_lookup_complete;
+extern atomic_t fscache_n_cop_grab_object;
+extern atomic_t fscache_n_cop_update_object;
+extern atomic_t fscache_n_cop_drop_object;
+extern atomic_t fscache_n_cop_put_object;
+extern atomic_t fscache_n_cop_sync_cache;
+extern atomic_t fscache_n_cop_attr_changed;
+extern atomic_t fscache_n_cop_read_or_alloc_page;
+extern atomic_t fscache_n_cop_read_or_alloc_pages;
+extern atomic_t fscache_n_cop_allocate_page;
+extern atomic_t fscache_n_cop_allocate_pages;
+extern atomic_t fscache_n_cop_write_page;
+extern atomic_t fscache_n_cop_uncache_page;
+extern atomic_t fscache_n_cop_dissociate_pages;
+
 static inline void fscache_stat(atomic_t *stat)
 {
        atomic_inc(stat);
 }
 
+static inline void fscache_stat_d(atomic_t *stat)
+{
+       atomic_dec(stat);
+}
+
+#define __fscache_stat(stat) (stat)
+
 extern const struct file_operations fscache_stats_fops;
 #else
 
+#define __fscache_stat(stat) (NULL)
 #define fscache_stat(stat) do {} while (0)
+#define fscache_stat_d(stat) do {} while (0)
 #endif
 
 /*
index 4de41b5..add6bdb 100644 (file)
@@ -48,7 +48,7 @@ static int __init fscache_init(void)
 {
        int ret;
 
-       ret = slow_work_register_user();
+       ret = slow_work_register_user(THIS_MODULE);
        if (ret < 0)
                goto error_slow_work;
 
@@ -80,7 +80,7 @@ error_kobj:
 error_cookie_jar:
        fscache_proc_cleanup();
 error_proc:
-       slow_work_unregister_user();
+       slow_work_unregister_user(THIS_MODULE);
 error_slow_work:
        return ret;
 }
@@ -97,7 +97,7 @@ static void __exit fscache_exit(void)
        kobject_put(fscache_root);
        kmem_cache_destroy(fscache_cookie_jar);
        fscache_proc_cleanup();
-       slow_work_unregister_user();
+       slow_work_unregister_user(THIS_MODULE);
        printk(KERN_NOTICE "FS-Cache: Unloaded\n");
 }
 
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c
new file mode 100644 (file)
index 0000000..e590242
--- /dev/null
@@ -0,0 +1,432 @@
+/* Global fscache object list maintainer and viewer
+ *
+ * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define FSCACHE_DEBUG_LEVEL COOKIE
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/key.h>
+#include <keys/user-type.h>
+#include "internal.h"
+
+static struct rb_root fscache_object_list;
+static DEFINE_RWLOCK(fscache_object_list_lock);
+
+struct fscache_objlist_data {
+       unsigned long   config;         /* display configuration */
+#define FSCACHE_OBJLIST_CONFIG_KEY     0x00000001      /* show object keys */
+#define FSCACHE_OBJLIST_CONFIG_AUX     0x00000002      /* show object auxdata */
+#define FSCACHE_OBJLIST_CONFIG_COOKIE  0x00000004      /* show objects with cookies */
+#define FSCACHE_OBJLIST_CONFIG_NOCOOKIE        0x00000008      /* show objects without cookies */
+#define FSCACHE_OBJLIST_CONFIG_BUSY    0x00000010      /* show busy objects */
+#define FSCACHE_OBJLIST_CONFIG_IDLE    0x00000020      /* show idle objects */
+#define FSCACHE_OBJLIST_CONFIG_PENDWR  0x00000040      /* show objects with pending writes */
+#define FSCACHE_OBJLIST_CONFIG_NOPENDWR        0x00000080      /* show objects without pending writes */
+#define FSCACHE_OBJLIST_CONFIG_READS   0x00000100      /* show objects with active reads */
+#define FSCACHE_OBJLIST_CONFIG_NOREADS 0x00000200      /* show objects without active reads */
+#define FSCACHE_OBJLIST_CONFIG_EVENTS  0x00000400      /* show objects with events */
+#define FSCACHE_OBJLIST_CONFIG_NOEVENTS        0x00000800      /* show objects without no events */
+#define FSCACHE_OBJLIST_CONFIG_WORK    0x00001000      /* show objects with slow work */
+#define FSCACHE_OBJLIST_CONFIG_NOWORK  0x00002000      /* show objects without slow work */
+
+       u8              buf[512];       /* key and aux data buffer */
+};
+
+/*
+ * Add an object to the object list
+ * - we use the address of the fscache_object structure as the key into the
+ *   tree
+ */
+void fscache_objlist_add(struct fscache_object *obj)
+{
+       struct fscache_object *xobj;
+       struct rb_node **p = &fscache_object_list.rb_node, *parent = NULL;
+
+       write_lock(&fscache_object_list_lock);
+
+       while (*p) {
+               parent = *p;
+               xobj = rb_entry(parent, struct fscache_object, objlist_link);
+
+               if (obj < xobj)
+                       p = &(*p)->rb_left;
+               else if (obj > xobj)
+                       p = &(*p)->rb_right;
+               else
+                       BUG();
+       }
+
+       rb_link_node(&obj->objlist_link, parent, p);
+       rb_insert_color(&obj->objlist_link, &fscache_object_list);
+
+       write_unlock(&fscache_object_list_lock);
+}
+
+/**
+ * fscache_object_destroy - Note that a cache object is about to be destroyed
+ * @object: The object to be destroyed
+ *
+ * Note the imminent destruction and deallocation of a cache object record.
+ */
+void fscache_object_destroy(struct fscache_object *obj)
+{
+       write_lock(&fscache_object_list_lock);
+
+       BUG_ON(RB_EMPTY_ROOT(&fscache_object_list));
+       rb_erase(&obj->objlist_link, &fscache_object_list);
+
+       write_unlock(&fscache_object_list_lock);
+}
+EXPORT_SYMBOL(fscache_object_destroy);
+
+/*
+ * find the object in the tree on or after the specified index
+ */
+static struct fscache_object *fscache_objlist_lookup(loff_t *_pos)
+{
+       struct fscache_object *pobj, *obj, *minobj = NULL;
+       struct rb_node *p;
+       unsigned long pos;
+
+       if (*_pos >= (unsigned long) ERR_PTR(-ENOENT))
+               return NULL;
+       pos = *_pos;
+
+       /* banners (can't represent line 0 by pos 0 as that would involve
+        * returning a NULL pointer) */
+       if (pos == 0)
+               return (struct fscache_object *) ++(*_pos);
+       if (pos < 3)
+               return (struct fscache_object *)pos;
+
+       pobj = (struct fscache_object *)pos;
+       p = fscache_object_list.rb_node;
+       while (p) {
+               obj = rb_entry(p, struct fscache_object, objlist_link);
+               if (pobj < obj) {
+                       if (!minobj || minobj > obj)
+                               minobj = obj;
+                       p = p->rb_left;
+               } else if (pobj > obj) {
+                       p = p->rb_right;
+               } else {
+                       minobj = obj;
+                       break;
+               }
+               obj = NULL;
+       }
+
+       if (!minobj)
+               *_pos = (unsigned long) ERR_PTR(-ENOENT);
+       else if (minobj != obj)
+               *_pos = (unsigned long) minobj;
+       return minobj;
+}
+
+/*
+ * set up the iterator to start reading from the first line
+ */
+static void *fscache_objlist_start(struct seq_file *m, loff_t *_pos)
+       __acquires(&fscache_object_list_lock)
+{
+       read_lock(&fscache_object_list_lock);
+       return fscache_objlist_lookup(_pos);
+}
+
+/*
+ * move to the next line
+ */
+static void *fscache_objlist_next(struct seq_file *m, void *v, loff_t *_pos)
+{
+       (*_pos)++;
+       return fscache_objlist_lookup(_pos);
+}
+
+/*
+ * clean up after reading
+ */
+static void fscache_objlist_stop(struct seq_file *m, void *v)
+       __releases(&fscache_object_list_lock)
+{
+       read_unlock(&fscache_object_list_lock);
+}
+
+/*
+ * display an object
+ */
+static int fscache_objlist_show(struct seq_file *m, void *v)
+{
+       struct fscache_objlist_data *data = m->private;
+       struct fscache_object *obj = v;
+       unsigned long config = data->config;
+       uint16_t keylen, auxlen;
+       char _type[3], *type;
+       bool no_cookie;
+       u8 *buf = data->buf, *p;
+
+       if ((unsigned long) v == 1) {
+               seq_puts(m, "OBJECT   PARENT   STAT CHLDN OPS OOP IPR EX READS"
+                        " EM EV F S"
+                        " | NETFS_COOKIE_DEF TY FL NETFS_DATA");
+               if (config & (FSCACHE_OBJLIST_CONFIG_KEY |
+                             FSCACHE_OBJLIST_CONFIG_AUX))
+                       seq_puts(m, "       ");
+               if (config & FSCACHE_OBJLIST_CONFIG_KEY)
+                       seq_puts(m, "OBJECT_KEY");
+               if ((config & (FSCACHE_OBJLIST_CONFIG_KEY |
+                              FSCACHE_OBJLIST_CONFIG_AUX)) ==
+                   (FSCACHE_OBJLIST_CONFIG_KEY | FSCACHE_OBJLIST_CONFIG_AUX))
+                       seq_puts(m, ", ");
+               if (config & FSCACHE_OBJLIST_CONFIG_AUX)
+                       seq_puts(m, "AUX_DATA");
+               seq_puts(m, "\n");
+               return 0;
+       }
+
+       if ((unsigned long) v == 2) {
+               seq_puts(m, "======== ======== ==== ===== === === === == ====="
+                        " == == = ="
+                        " | ================ == == ================");
+               if (config & (FSCACHE_OBJLIST_CONFIG_KEY |
+                             FSCACHE_OBJLIST_CONFIG_AUX))
+                       seq_puts(m, " ================");
+               seq_puts(m, "\n");
+               return 0;
+       }
+
+       /* filter out any unwanted objects */
+#define FILTER(criterion, _yes, _no)                                   \
+       do {                                                            \
+               unsigned long yes = FSCACHE_OBJLIST_CONFIG_##_yes;      \
+               unsigned long no = FSCACHE_OBJLIST_CONFIG_##_no;        \
+               if (criterion) {                                        \
+                       if (!(config & yes))                            \
+                               return 0;                               \
+               } else {                                                \
+                       if (!(config & no))                             \
+                               return 0;                               \
+               }                                                       \
+       } while(0)
+
+       if (~config) {
+               FILTER(obj->cookie,
+                      COOKIE, NOCOOKIE);
+               FILTER(obj->state != FSCACHE_OBJECT_ACTIVE ||
+                      obj->n_ops != 0 ||
+                      obj->n_obj_ops != 0 ||
+                      obj->flags ||
+                      !list_empty(&obj->dependents),
+                      BUSY, IDLE);
+               FILTER(test_bit(FSCACHE_OBJECT_PENDING_WRITE, &obj->flags),
+                      PENDWR, NOPENDWR);
+               FILTER(atomic_read(&obj->n_reads),
+                      READS, NOREADS);
+               FILTER(obj->events & obj->event_mask,
+                      EVENTS, NOEVENTS);
+               FILTER(obj->work.flags & ~(1UL << SLOW_WORK_VERY_SLOW),
+                      WORK, NOWORK);
+       }
+
+       seq_printf(m,
+                  "%8x %8x %s %5u %3u %3u %3u %2u %5u %2lx %2lx %1lx %1lx | ",
+                  obj->debug_id,
+                  obj->parent ? obj->parent->debug_id : -1,
+                  fscache_object_states_short[obj->state],
+                  obj->n_children,
+                  obj->n_ops,
+                  obj->n_obj_ops,
+                  obj->n_in_progress,
+                  obj->n_exclusive,
+                  atomic_read(&obj->n_reads),
+                  obj->event_mask & FSCACHE_OBJECT_EVENTS_MASK,
+                  obj->events,
+                  obj->flags,
+                  obj->work.flags);
+
+       no_cookie = true;
+       keylen = auxlen = 0;
+       if (obj->cookie) {
+               spin_lock(&obj->lock);
+               if (obj->cookie) {
+                       switch (obj->cookie->def->type) {
+                       case 0:
+                               type = "IX";
+                               break;
+                       case 1:
+                               type = "DT";
+                               break;
+                       default:
+                               sprintf(_type, "%02u",
+                                       obj->cookie->def->type);
+                               type = _type;
+                               break;
+                       }
+
+                       seq_printf(m, "%-16s %s %2lx %16p",
+                                  obj->cookie->def->name,
+                                  type,
+                                  obj->cookie->flags,
+                                  obj->cookie->netfs_data);
+
+                       if (obj->cookie->def->get_key &&
+                           config & FSCACHE_OBJLIST_CONFIG_KEY)
+                               keylen = obj->cookie->def->get_key(
+                                       obj->cookie->netfs_data,
+                                       buf, 400);
+
+                       if (obj->cookie->def->get_aux &&
+                           config & FSCACHE_OBJLIST_CONFIG_AUX)
+                               auxlen = obj->cookie->def->get_aux(
+                                       obj->cookie->netfs_data,
+                                       buf + keylen, 512 - keylen);
+
+                       no_cookie = false;
+               }
+               spin_unlock(&obj->lock);
+
+               if (!no_cookie && (keylen > 0 || auxlen > 0)) {
+                       seq_printf(m, " ");
+                       for (p = buf; keylen > 0; keylen--)
+                               seq_printf(m, "%02x", *p++);
+                       if (auxlen > 0) {
+                               if (config & FSCACHE_OBJLIST_CONFIG_KEY)
+                                       seq_printf(m, ", ");
+                               for (; auxlen > 0; auxlen--)
+                                       seq_printf(m, "%02x", *p++);
+                       }
+               }
+       }
+
+       if (no_cookie)
+               seq_printf(m, "<no_cookie>\n");
+       else
+               seq_printf(m, "\n");
+       return 0;
+}
+
+static const struct seq_operations fscache_objlist_ops = {
+       .start          = fscache_objlist_start,
+       .stop           = fscache_objlist_stop,
+       .next           = fscache_objlist_next,
+       .show           = fscache_objlist_show,
+};
+
+/*
+ * get the configuration for filtering the list
+ */
+static void fscache_objlist_config(struct fscache_objlist_data *data)
+{
+#ifdef CONFIG_KEYS
+       struct user_key_payload *confkey;
+       unsigned long config;
+       struct key *key;
+       const char *buf;
+       int len;
+
+       key = request_key(&key_type_user, "fscache:objlist", NULL);
+       if (IS_ERR(key))
+               goto no_config;
+
+       config = 0;
+       rcu_read_lock();
+
+       confkey = key->payload.data;
+       buf = confkey->data;
+
+       for (len = confkey->datalen - 1; len >= 0; len--) {
+               switch (buf[len]) {
+               case 'K': config |= FSCACHE_OBJLIST_CONFIG_KEY;         break;
+               case 'A': config |= FSCACHE_OBJLIST_CONFIG_AUX;         break;
+               case 'C': config |= FSCACHE_OBJLIST_CONFIG_COOKIE;      break;
+               case 'c': config |= FSCACHE_OBJLIST_CONFIG_NOCOOKIE;    break;
+               case 'B': config |= FSCACHE_OBJLIST_CONFIG_BUSY;        break;
+               case 'b': config |= FSCACHE_OBJLIST_CONFIG_IDLE;        break;
+               case 'W': config |= FSCACHE_OBJLIST_CONFIG_PENDWR;      break;
+               case 'w': config |= FSCACHE_OBJLIST_CONFIG_NOPENDWR;    break;
+               case 'R': config |= FSCACHE_OBJLIST_CONFIG_READS;       break;
+               case 'r': config |= FSCACHE_OBJLIST_CONFIG_NOREADS;     break;
+               case 'S': config |= FSCACHE_OBJLIST_CONFIG_WORK;        break;
+               case 's': config |= FSCACHE_OBJLIST_CONFIG_NOWORK;      break;
+               }
+       }
+
+       rcu_read_unlock();
+       key_put(key);
+
+       if (!(config & (FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE)))
+           config   |= FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE;
+       if (!(config & (FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE)))
+           config   |= FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE;
+       if (!(config & (FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR)))
+           config   |= FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR;
+       if (!(config & (FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS)))
+           config   |= FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS;
+       if (!(config & (FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS)))
+           config   |= FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS;
+       if (!(config & (FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK)))
+           config   |= FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK;
+
+       data->config = config;
+       return;
+
+no_config:
+#endif
+       data->config = ULONG_MAX;
+}
+
+/*
+ * open "/proc/fs/fscache/objects" to provide a list of active objects
+ * - can be configured by a user-defined key added to the caller's keyrings
+ */
+static int fscache_objlist_open(struct inode *inode, struct file *file)
+{
+       struct fscache_objlist_data *data;
+       struct seq_file *m;
+       int ret;
+
+       ret = seq_open(file, &fscache_objlist_ops);
+       if (ret < 0)
+               return ret;
+
+       m = file->private_data;
+
+       /* buffer for key extraction */
+       data = kmalloc(sizeof(struct fscache_objlist_data), GFP_KERNEL);
+       if (!data) {
+               seq_release(inode, file);
+               return -ENOMEM;
+       }
+
+       /* get the configuration key */
+       fscache_objlist_config(data);
+
+       m->private = data;
+       return 0;
+}
+
+/*
+ * clean up on close
+ */
+static int fscache_objlist_release(struct inode *inode, struct file *file)
+{
+       struct seq_file *m = file->private_data;
+
+       kfree(m->private);
+       m->private = NULL;
+       return seq_release(inode, file);
+}
+
+const struct file_operations fscache_objlist_fops = {
+       .owner          = THIS_MODULE,
+       .open           = fscache_objlist_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = fscache_objlist_release,
+};
index 392a41b..e513ac5 100644 (file)
 
 #define FSCACHE_DEBUG_LEVEL COOKIE
 #include <linux/module.h>
+#include <linux/seq_file.h>
 #include "internal.h"
 
-const char *fscache_object_states[] = {
+const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = {
        [FSCACHE_OBJECT_INIT]           = "OBJECT_INIT",
        [FSCACHE_OBJECT_LOOKING_UP]     = "OBJECT_LOOKING_UP",
        [FSCACHE_OBJECT_CREATING]       = "OBJECT_CREATING",
@@ -33,9 +34,28 @@ const char *fscache_object_states[] = {
 };
 EXPORT_SYMBOL(fscache_object_states);
 
+const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = {
+       [FSCACHE_OBJECT_INIT]           = "INIT",
+       [FSCACHE_OBJECT_LOOKING_UP]     = "LOOK",
+       [FSCACHE_OBJECT_CREATING]       = "CRTN",
+       [FSCACHE_OBJECT_AVAILABLE]      = "AVBL",
+       [FSCACHE_OBJECT_ACTIVE]         = "ACTV",
+       [FSCACHE_OBJECT_UPDATING]       = "UPDT",
+       [FSCACHE_OBJECT_DYING]          = "DYNG",
+       [FSCACHE_OBJECT_LC_DYING]       = "LCDY",
+       [FSCACHE_OBJECT_ABORT_INIT]     = "ABTI",
+       [FSCACHE_OBJECT_RELEASING]      = "RELS",
+       [FSCACHE_OBJECT_RECYCLING]      = "RCYC",
+       [FSCACHE_OBJECT_WITHDRAWING]    = "WTHD",
+       [FSCACHE_OBJECT_DEAD]           = "DEAD",
+};
+
 static void fscache_object_slow_work_put_ref(struct slow_work *);
 static int  fscache_object_slow_work_get_ref(struct slow_work *);
 static void fscache_object_slow_work_execute(struct slow_work *);
+#ifdef CONFIG_SLOW_WORK_PROC
+static void fscache_object_slow_work_desc(struct slow_work *, struct seq_file *);
+#endif
 static void fscache_initialise_object(struct fscache_object *);
 static void fscache_lookup_object(struct fscache_object *);
 static void fscache_object_available(struct fscache_object *);
@@ -45,9 +65,13 @@ static void fscache_enqueue_dependents(struct fscache_object *);
 static void fscache_dequeue_object(struct fscache_object *);
 
 const struct slow_work_ops fscache_object_slow_work_ops = {
+       .owner          = THIS_MODULE,
        .get_ref        = fscache_object_slow_work_get_ref,
        .put_ref        = fscache_object_slow_work_put_ref,
        .execute        = fscache_object_slow_work_execute,
+#ifdef CONFIG_SLOW_WORK_PROC
+       .desc           = fscache_object_slow_work_desc,
+#endif
 };
 EXPORT_SYMBOL(fscache_object_slow_work_ops);
 
@@ -81,6 +105,7 @@ static inline void fscache_done_parent_op(struct fscache_object *object)
 static void fscache_object_state_machine(struct fscache_object *object)
 {
        enum fscache_object_state new_state;
+       struct fscache_cookie *cookie;
 
        ASSERT(object != NULL);
 
@@ -120,20 +145,31 @@ static void fscache_object_state_machine(struct fscache_object *object)
        case FSCACHE_OBJECT_UPDATING:
                clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events);
                fscache_stat(&fscache_n_updates_run);
+               fscache_stat(&fscache_n_cop_update_object);
                object->cache->ops->update_object(object);
+               fscache_stat_d(&fscache_n_cop_update_object);
                goto active_transit;
 
                /* handle an object dying during lookup or creation */
        case FSCACHE_OBJECT_LC_DYING:
                object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE);
+               fscache_stat(&fscache_n_cop_lookup_complete);
                object->cache->ops->lookup_complete(object);
+               fscache_stat_d(&fscache_n_cop_lookup_complete);
 
                spin_lock(&object->lock);
                object->state = FSCACHE_OBJECT_DYING;
-               if (test_and_clear_bit(FSCACHE_COOKIE_CREATING,
-                                      &object->cookie->flags))
-                       wake_up_bit(&object->cookie->flags,
-                                   FSCACHE_COOKIE_CREATING);
+               cookie = object->cookie;
+               if (cookie) {
+                       if (test_and_clear_bit(FSCACHE_COOKIE_LOOKING_UP,
+                                              &cookie->flags))
+                               wake_up_bit(&cookie->flags,
+                                           FSCACHE_COOKIE_LOOKING_UP);
+                       if (test_and_clear_bit(FSCACHE_COOKIE_CREATING,
+                                              &cookie->flags))
+                               wake_up_bit(&cookie->flags,
+                                           FSCACHE_COOKIE_CREATING);
+               }
                spin_unlock(&object->lock);
 
                fscache_done_parent_op(object);
@@ -165,6 +201,7 @@ static void fscache_object_state_machine(struct fscache_object *object)
                }
                spin_unlock(&object->lock);
                fscache_enqueue_dependents(object);
+               fscache_start_operations(object);
                goto terminal_transit;
 
                /* handle an abort during initialisation */
@@ -316,14 +353,29 @@ static void fscache_object_slow_work_execute(struct slow_work *work)
 
        _enter("{OBJ%x}", object->debug_id);
 
-       clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
-
        start = jiffies;
        fscache_object_state_machine(object);
        fscache_hist(fscache_objs_histogram, start);
        if (object->events & object->event_mask)
                fscache_enqueue_object(object);
+       clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+}
+
+/*
+ * describe an object for slow-work debugging
+ */
+#ifdef CONFIG_SLOW_WORK_PROC
+static void fscache_object_slow_work_desc(struct slow_work *work,
+                                         struct seq_file *m)
+{
+       struct fscache_object *object =
+               container_of(work, struct fscache_object, work);
+
+       seq_printf(m, "FSC: OBJ%x: %s",
+                  object->debug_id,
+                  fscache_object_states_short[object->state]);
 }
+#endif
 
 /*
  * initialise an object
@@ -376,7 +428,9 @@ static void fscache_initialise_object(struct fscache_object *object)
                         * binding on to us, so we need to make sure we don't
                         * add ourself to the list multiple times */
                        if (list_empty(&object->dep_link)) {
+                               fscache_stat(&fscache_n_cop_grab_object);
                                object->cache->ops->grab_object(object);
+                               fscache_stat_d(&fscache_n_cop_grab_object);
                                list_add(&object->dep_link,
                                         &parent->dependents);
 
@@ -414,6 +468,7 @@ static void fscache_lookup_object(struct fscache_object *object)
 {
        struct fscache_cookie *cookie = object->cookie;
        struct fscache_object *parent;
+       int ret;
 
        _enter("");
 
@@ -438,11 +493,20 @@ static void fscache_lookup_object(struct fscache_object *object)
               object->cache->tag->name);
 
        fscache_stat(&fscache_n_object_lookups);
-       object->cache->ops->lookup_object(object);
+       fscache_stat(&fscache_n_cop_lookup_object);
+       ret = object->cache->ops->lookup_object(object);
+       fscache_stat_d(&fscache_n_cop_lookup_object);
 
        if (test_bit(FSCACHE_OBJECT_EV_ERROR, &object->events))
                set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
 
+       if (ret == -ETIMEDOUT) {
+               /* probably stuck behind another object, so move this one to
+                * the back of the queue */
+               fscache_stat(&fscache_n_object_lookups_timed_out);
+               set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
+       }
+
        _leave("");
 }
 
@@ -546,7 +610,8 @@ static void fscache_object_available(struct fscache_object *object)
 
        spin_lock(&object->lock);
 
-       if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags))
+       if (object->cookie &&
+           test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags))
                wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING);
 
        fscache_done_parent_op(object);
@@ -562,7 +627,9 @@ static void fscache_object_available(struct fscache_object *object)
        }
        spin_unlock(&object->lock);
 
+       fscache_stat(&fscache_n_cop_lookup_complete);
        object->cache->ops->lookup_complete(object);
+       fscache_stat_d(&fscache_n_cop_lookup_complete);
        fscache_enqueue_dependents(object);
 
        fscache_hist(fscache_obj_instantiate_histogram, object->lookup_jif);
@@ -581,11 +648,16 @@ static void fscache_drop_object(struct fscache_object *object)
 
        _enter("{OBJ%x,%d}", object->debug_id, object->n_children);
 
+       ASSERTCMP(object->cookie, ==, NULL);
+       ASSERT(hlist_unhashed(&object->cookie_link));
+
        spin_lock(&cache->object_list_lock);
        list_del_init(&object->cache_link);
        spin_unlock(&cache->object_list_lock);
 
+       fscache_stat(&fscache_n_cop_drop_object);
        cache->ops->drop_object(object);
+       fscache_stat_d(&fscache_n_cop_drop_object);
 
        if (parent) {
                _debug("release parent OBJ%x {%d}",
@@ -600,7 +672,9 @@ static void fscache_drop_object(struct fscache_object *object)
        }
 
        /* this just shifts the object release to the slow work processor */
+       fscache_stat(&fscache_n_cop_put_object);
        object->cache->ops->put_object(object);
+       fscache_stat_d(&fscache_n_cop_put_object);
 
        _leave("");
 }
@@ -690,8 +764,12 @@ static int fscache_object_slow_work_get_ref(struct slow_work *work)
 {
        struct fscache_object *object =
                container_of(work, struct fscache_object, work);
+       int ret;
 
-       return object->cache->ops->grab_object(object) ? 0 : -EAGAIN;
+       fscache_stat(&fscache_n_cop_grab_object);
+       ret = object->cache->ops->grab_object(object) ? 0 : -EAGAIN;
+       fscache_stat_d(&fscache_n_cop_grab_object);
+       return ret;
 }
 
 /*
@@ -702,7 +780,9 @@ static void fscache_object_slow_work_put_ref(struct slow_work *work)
        struct fscache_object *object =
                container_of(work, struct fscache_object, work);
 
-       return object->cache->ops->put_object(object);
+       fscache_stat(&fscache_n_cop_put_object);
+       object->cache->ops->put_object(object);
+       fscache_stat_d(&fscache_n_cop_put_object);
 }
 
 /*
@@ -739,7 +819,9 @@ static void fscache_enqueue_dependents(struct fscache_object *object)
 
                /* sort onto appropriate lists */
                fscache_enqueue_object(dep);
+               fscache_stat(&fscache_n_cop_put_object);
                dep->cache->ops->put_object(dep);
+               fscache_stat_d(&fscache_n_cop_put_object);
 
                if (!list_empty(&object->dependents))
                        cond_resched_lock(&object->lock);
index e7f8d53..313e79a 100644 (file)
@@ -13,6 +13,7 @@
 
 #define FSCACHE_DEBUG_LEVEL OPERATION
 #include <linux/module.h>
+#include <linux/seq_file.h>
 #include "internal.h"
 
 atomic_t fscache_op_debug_id;
@@ -31,32 +32,33 @@ void fscache_enqueue_operation(struct fscache_operation *op)
        _enter("{OBJ%x OP%x,%u}",
               op->object->debug_id, op->debug_id, atomic_read(&op->usage));
 
+       fscache_set_op_state(op, "EnQ");
+
+       ASSERT(list_empty(&op->pend_link));
        ASSERT(op->processor != NULL);
        ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE);
        ASSERTCMP(atomic_read(&op->usage), >, 0);
 
-       if (list_empty(&op->pend_link)) {
-               switch (op->flags & FSCACHE_OP_TYPE) {
-               case FSCACHE_OP_FAST:
-                       _debug("queue fast");
-                       atomic_inc(&op->usage);
-                       if (!schedule_work(&op->fast_work))
-                               fscache_put_operation(op);
-                       break;
-               case FSCACHE_OP_SLOW:
-                       _debug("queue slow");
-                       slow_work_enqueue(&op->slow_work);
-                       break;
-               case FSCACHE_OP_MYTHREAD:
-                       _debug("queue for caller's attention");
-                       break;
-               default:
-                       printk(KERN_ERR "FS-Cache: Unexpected op type %lx",
-                              op->flags);
-                       BUG();
-                       break;
-               }
-               fscache_stat(&fscache_n_op_enqueue);
+       fscache_stat(&fscache_n_op_enqueue);
+       switch (op->flags & FSCACHE_OP_TYPE) {
+       case FSCACHE_OP_FAST:
+               _debug("queue fast");
+               atomic_inc(&op->usage);
+               if (!schedule_work(&op->fast_work))
+                       fscache_put_operation(op);
+               break;
+       case FSCACHE_OP_SLOW:
+               _debug("queue slow");
+               slow_work_enqueue(&op->slow_work);
+               break;
+       case FSCACHE_OP_MYTHREAD:
+               _debug("queue for caller's attention");
+               break;
+       default:
+               printk(KERN_ERR "FS-Cache: Unexpected op type %lx",
+                      op->flags);
+               BUG();
+               break;
        }
 }
 EXPORT_SYMBOL(fscache_enqueue_operation);
@@ -67,6 +69,8 @@ EXPORT_SYMBOL(fscache_enqueue_operation);
 static void fscache_run_op(struct fscache_object *object,
                           struct fscache_operation *op)
 {
+       fscache_set_op_state(op, "Run");
+
        object->n_in_progress++;
        if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
                wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
@@ -87,9 +91,12 @@ int fscache_submit_exclusive_op(struct fscache_object *object,
 
        _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id);
 
+       fscache_set_op_state(op, "SubmitX");
+
        spin_lock(&object->lock);
        ASSERTCMP(object->n_ops, >=, object->n_in_progress);
        ASSERTCMP(object->n_ops, >=, object->n_exclusive);
+       ASSERT(list_empty(&op->pend_link));
 
        ret = -ENOBUFS;
        if (fscache_object_is_active(object)) {
@@ -190,9 +197,12 @@ int fscache_submit_op(struct fscache_object *object,
 
        ASSERTCMP(atomic_read(&op->usage), >, 0);
 
+       fscache_set_op_state(op, "Submit");
+
        spin_lock(&object->lock);
        ASSERTCMP(object->n_ops, >=, object->n_in_progress);
        ASSERTCMP(object->n_ops, >=, object->n_exclusive);
+       ASSERT(list_empty(&op->pend_link));
 
        ostate = object->state;
        smp_rmb();
@@ -222,6 +232,11 @@ int fscache_submit_op(struct fscache_object *object,
                list_add_tail(&op->pend_link, &object->pending_ops);
                fscache_stat(&fscache_n_op_pend);
                ret = 0;
+       } else if (object->state == FSCACHE_OBJECT_DYING ||
+                  object->state == FSCACHE_OBJECT_LC_DYING ||
+                  object->state == FSCACHE_OBJECT_WITHDRAWING) {
+               fscache_stat(&fscache_n_op_rejected);
+               ret = -ENOBUFS;
        } else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) {
                fscache_report_unexpected_submission(object, op, ostate);
                ASSERT(!fscache_object_is_active(object));
@@ -264,12 +279,7 @@ void fscache_start_operations(struct fscache_object *object)
                        stop = true;
                }
                list_del_init(&op->pend_link);
-               object->n_in_progress++;
-
-               if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
-                       wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
-               if (op->processor)
-                       fscache_enqueue_operation(op);
+               fscache_run_op(object, op);
 
                /* the pending queue was holding a ref on the object */
                fscache_put_operation(op);
@@ -281,6 +291,36 @@ void fscache_start_operations(struct fscache_object *object)
               object->n_in_progress, object->debug_id);
 }
 
+/*
+ * cancel an operation that's pending on an object
+ */
+int fscache_cancel_op(struct fscache_operation *op)
+{
+       struct fscache_object *object = op->object;
+       int ret;
+
+       _enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id);
+
+       spin_lock(&object->lock);
+
+       ret = -EBUSY;
+       if (!list_empty(&op->pend_link)) {
+               fscache_stat(&fscache_n_op_cancelled);
+               list_del_init(&op->pend_link);
+               object->n_ops--;
+               if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
+                       object->n_exclusive--;
+               if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
+                       wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
+               fscache_put_operation(op);
+               ret = 0;
+       }
+
+       spin_unlock(&object->lock);
+       _leave(" = %d", ret);
+       return ret;
+}
+
 /*
  * release an operation
  * - queues pending ops if this is the last in-progress op
@@ -298,6 +338,8 @@ void fscache_put_operation(struct fscache_operation *op)
        if (!atomic_dec_and_test(&op->usage))
                return;
 
+       fscache_set_op_state(op, "Put");
+
        _debug("PUT OP");
        if (test_and_set_bit(FSCACHE_OP_DEAD, &op->flags))
                BUG();
@@ -311,6 +353,9 @@ void fscache_put_operation(struct fscache_operation *op)
 
        object = op->object;
 
+       if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags))
+               atomic_dec(&object->n_reads);
+
        /* now... we may get called with the object spinlock held, so we
         * complete the cleanup here only if we can immediately acquire the
         * lock, and defer it otherwise */
@@ -452,8 +497,27 @@ static void fscache_op_execute(struct slow_work *work)
        _leave("");
 }
 
+/*
+ * describe an operation for slow-work debugging
+ */
+#ifdef CONFIG_SLOW_WORK_PROC
+static void fscache_op_desc(struct slow_work *work, struct seq_file *m)
+{
+       struct fscache_operation *op =
+               container_of(work, struct fscache_operation, slow_work);
+
+       seq_printf(m, "FSC: OBJ%x OP%x: %s/%s fl=%lx",
+                  op->object->debug_id, op->debug_id,
+                  op->name, op->state, op->flags);
+}
+#endif
+
 const struct slow_work_ops fscache_op_slow_work_ops = {
+       .owner          = THIS_MODULE,
        .get_ref        = fscache_op_get_ref,
        .put_ref        = fscache_op_put_ref,
        .execute        = fscache_op_execute,
+#ifdef CONFIG_SLOW_WORK_PROC
+       .desc           = fscache_op_desc,
+#endif
 };
index 2568e0e..c598ea4 100644 (file)
@@ -43,18 +43,102 @@ void __fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *pa
 EXPORT_SYMBOL(__fscache_wait_on_page_write);
 
 /*
- * note that a page has finished being written to the cache
+ * decide whether a page can be released, possibly by cancelling a store to it
+ * - we're allowed to sleep if __GFP_WAIT is flagged
  */
-static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *page)
+bool __fscache_maybe_release_page(struct fscache_cookie *cookie,
+                                 struct page *page,
+                                 gfp_t gfp)
 {
        struct page *xpage;
+       void *val;
+
+       _enter("%p,%p,%x", cookie, page, gfp);
+
+       rcu_read_lock();
+       val = radix_tree_lookup(&cookie->stores, page->index);
+       if (!val) {
+               rcu_read_unlock();
+               fscache_stat(&fscache_n_store_vmscan_not_storing);
+               __fscache_uncache_page(cookie, page);
+               return true;
+       }
+
+       /* see if the page is actually undergoing storage - if so we can't get
+        * rid of it till the cache has finished with it */
+       if (radix_tree_tag_get(&cookie->stores, page->index,
+                              FSCACHE_COOKIE_STORING_TAG)) {
+               rcu_read_unlock();
+               goto page_busy;
+       }
+
+       /* the page is pending storage, so we attempt to cancel the store and
+        * discard the store request so that the page can be reclaimed */
+       spin_lock(&cookie->stores_lock);
+       rcu_read_unlock();
+
+       if (radix_tree_tag_get(&cookie->stores, page->index,
+                              FSCACHE_COOKIE_STORING_TAG)) {
+               /* the page started to undergo storage whilst we were looking,
+                * so now we can only wait or return */
+               spin_unlock(&cookie->stores_lock);
+               goto page_busy;
+       }
 
-       spin_lock(&cookie->lock);
        xpage = radix_tree_delete(&cookie->stores, page->index);
-       spin_unlock(&cookie->lock);
-       ASSERT(xpage != NULL);
+       spin_unlock(&cookie->stores_lock);
+
+       if (xpage) {
+               fscache_stat(&fscache_n_store_vmscan_cancelled);
+               fscache_stat(&fscache_n_store_radix_deletes);
+               ASSERTCMP(xpage, ==, page);
+       } else {
+               fscache_stat(&fscache_n_store_vmscan_gone);
+       }
 
        wake_up_bit(&cookie->flags, 0);
+       if (xpage)
+               page_cache_release(xpage);
+       __fscache_uncache_page(cookie, page);
+       return true;
+
+page_busy:
+       /* we might want to wait here, but that could deadlock the allocator as
+        * the slow-work threads writing to the cache may all end up sleeping
+        * on memory allocation */
+       fscache_stat(&fscache_n_store_vmscan_busy);
+       return false;
+}
+EXPORT_SYMBOL(__fscache_maybe_release_page);
+
+/*
+ * note that a page has finished being written to the cache
+ */
+static void fscache_end_page_write(struct fscache_object *object,
+                                  struct page *page)
+{
+       struct fscache_cookie *cookie;
+       struct page *xpage = NULL;
+
+       spin_lock(&object->lock);
+       cookie = object->cookie;
+       if (cookie) {
+               /* delete the page from the tree if it is now no longer
+                * pending */
+               spin_lock(&cookie->stores_lock);
+               radix_tree_tag_clear(&cookie->stores, page->index,
+                                    FSCACHE_COOKIE_STORING_TAG);
+               if (!radix_tree_tag_get(&cookie->stores, page->index,
+                                       FSCACHE_COOKIE_PENDING_TAG)) {
+                       fscache_stat(&fscache_n_store_radix_deletes);
+                       xpage = radix_tree_delete(&cookie->stores, page->index);
+               }
+               spin_unlock(&cookie->stores_lock);
+               wake_up_bit(&cookie->flags, 0);
+       }
+       spin_unlock(&object->lock);
+       if (xpage)
+               page_cache_release(xpage);
 }
 
 /*
@@ -63,14 +147,21 @@ static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *p
 static void fscache_attr_changed_op(struct fscache_operation *op)
 {
        struct fscache_object *object = op->object;
+       int ret;
 
        _enter("{OBJ%x OP%x}", object->debug_id, op->debug_id);
 
        fscache_stat(&fscache_n_attr_changed_calls);
 
-       if (fscache_object_is_active(object) &&
-           object->cache->ops->attr_changed(object) < 0)
-               fscache_abort_object(object);
+       if (fscache_object_is_active(object)) {
+               fscache_set_op_state(op, "CallFS");
+               fscache_stat(&fscache_n_cop_attr_changed);
+               ret = object->cache->ops->attr_changed(object);
+               fscache_stat_d(&fscache_n_cop_attr_changed);
+               fscache_set_op_state(op, "Done");
+               if (ret < 0)
+                       fscache_abort_object(object);
+       }
 
        _leave("");
 }
@@ -99,6 +190,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
        fscache_operation_init(op, NULL);
        fscache_operation_init_slow(op, fscache_attr_changed_op);
        op->flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_EXCLUSIVE);
+       fscache_set_op_name(op, "Attr");
 
        spin_lock(&cookie->lock);
 
@@ -184,6 +276,7 @@ static struct fscache_retrieval *fscache_alloc_retrieval(
        op->start_time  = jiffies;
        INIT_WORK(&op->op.fast_work, fscache_retrieval_work);
        INIT_LIST_HEAD(&op->to_do);
+       fscache_set_op_name(&op->op, "Retr");
        return op;
 }
 
@@ -220,6 +313,43 @@ static int fscache_wait_for_deferred_lookup(struct fscache_cookie *cookie)
        return 0;
 }
 
+/*
+ * wait for an object to become active (or dead)
+ */
+static int fscache_wait_for_retrieval_activation(struct fscache_object *object,
+                                                struct fscache_retrieval *op,
+                                                atomic_t *stat_op_waits,
+                                                atomic_t *stat_object_dead)
+{
+       int ret;
+
+       if (!test_bit(FSCACHE_OP_WAITING, &op->op.flags))
+               goto check_if_dead;
+
+       _debug(">>> WT");
+       fscache_stat(stat_op_waits);
+       if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
+                       fscache_wait_bit_interruptible,
+                       TASK_INTERRUPTIBLE) < 0) {
+               ret = fscache_cancel_op(&op->op);
+               if (ret == 0)
+                       return -ERESTARTSYS;
+
+               /* it's been removed from the pending queue by another party,
+                * so we should get to run shortly */
+               wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
+                           fscache_wait_bit, TASK_UNINTERRUPTIBLE);
+       }
+       _debug("<<< GO");
+
+check_if_dead:
+       if (unlikely(fscache_object_is_dead(object))) {
+               fscache_stat(stat_object_dead);
+               return -ENOBUFS;
+       }
+       return 0;
+}
+
 /*
  * read a page from the cache or allocate a block in which to store it
  * - we return:
@@ -257,6 +387,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
                _leave(" = -ENOMEM");
                return -ENOMEM;
        }
+       fscache_set_op_name(&op->op, "RetrRA1");
 
        spin_lock(&cookie->lock);
 
@@ -267,6 +398,9 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
 
        ASSERTCMP(object->state, >, FSCACHE_OBJECT_LOOKING_UP);
 
+       atomic_inc(&object->n_reads);
+       set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
+
        if (fscache_submit_op(object, &op->op) < 0)
                goto nobufs_unlock;
        spin_unlock(&cookie->lock);
@@ -279,23 +413,27 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
 
        /* we wait for the operation to become active, and then process it
         * *here*, in this thread, and not in the thread pool */
-       if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
-               _debug(">>> WT");
-               fscache_stat(&fscache_n_retrieval_op_waits);
-               wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
-                           fscache_wait_bit, TASK_UNINTERRUPTIBLE);
-               _debug("<<< GO");
-       }
+       ret = fscache_wait_for_retrieval_activation(
+               object, op,
+               __fscache_stat(&fscache_n_retrieval_op_waits),
+               __fscache_stat(&fscache_n_retrievals_object_dead));
+       if (ret < 0)
+               goto error;
 
        /* ask the cache to honour the operation */
        if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) {
+               fscache_stat(&fscache_n_cop_allocate_page);
                ret = object->cache->ops->allocate_page(op, page, gfp);
+               fscache_stat_d(&fscache_n_cop_allocate_page);
                if (ret == 0)
                        ret = -ENODATA;
        } else {
+               fscache_stat(&fscache_n_cop_read_or_alloc_page);
                ret = object->cache->ops->read_or_alloc_page(op, page, gfp);
+               fscache_stat_d(&fscache_n_cop_read_or_alloc_page);
        }
 
+error:
        if (ret == -ENOMEM)
                fscache_stat(&fscache_n_retrievals_nomem);
        else if (ret == -ERESTARTSYS)
@@ -347,7 +485,6 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
                                  void *context,
                                  gfp_t gfp)
 {
-       fscache_pages_retrieval_func_t func;
        struct fscache_retrieval *op;
        struct fscache_object *object;
        int ret;
@@ -369,6 +506,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
        op = fscache_alloc_retrieval(mapping, end_io_func, context);
        if (!op)
                return -ENOMEM;
+       fscache_set_op_name(&op->op, "RetrRAN");
 
        spin_lock(&cookie->lock);
 
@@ -377,6 +515,9 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
 
+       atomic_inc(&object->n_reads);
+       set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
+
        if (fscache_submit_op(object, &op->op) < 0)
                goto nobufs_unlock;
        spin_unlock(&cookie->lock);
@@ -389,21 +530,27 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
 
        /* we wait for the operation to become active, and then process it
         * *here*, in this thread, and not in the thread pool */
-       if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
-               _debug(">>> WT");
-               fscache_stat(&fscache_n_retrieval_op_waits);
-               wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
-                           fscache_wait_bit, TASK_UNINTERRUPTIBLE);
-               _debug("<<< GO");
-       }
+       ret = fscache_wait_for_retrieval_activation(
+               object, op,
+               __fscache_stat(&fscache_n_retrieval_op_waits),
+               __fscache_stat(&fscache_n_retrievals_object_dead));
+       if (ret < 0)
+               goto error;
 
        /* ask the cache to honour the operation */
-       if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags))
-               func = object->cache->ops->allocate_pages;
-       else
-               func = object->cache->ops->read_or_alloc_pages;
-       ret = func(op, pages, nr_pages, gfp);
+       if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) {
+               fscache_stat(&fscache_n_cop_allocate_pages);
+               ret = object->cache->ops->allocate_pages(
+                       op, pages, nr_pages, gfp);
+               fscache_stat_d(&fscache_n_cop_allocate_pages);
+       } else {
+               fscache_stat(&fscache_n_cop_read_or_alloc_pages);
+               ret = object->cache->ops->read_or_alloc_pages(
+                       op, pages, nr_pages, gfp);
+               fscache_stat_d(&fscache_n_cop_read_or_alloc_pages);
+       }
 
+error:
        if (ret == -ENOMEM)
                fscache_stat(&fscache_n_retrievals_nomem);
        else if (ret == -ERESTARTSYS)
@@ -461,6 +608,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
        op = fscache_alloc_retrieval(page->mapping, NULL, NULL);
        if (!op)
                return -ENOMEM;
+       fscache_set_op_name(&op->op, "RetrAL1");
 
        spin_lock(&cookie->lock);
 
@@ -475,18 +623,22 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
 
        fscache_stat(&fscache_n_alloc_ops);
 
-       if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) {
-               _debug(">>> WT");
-               fscache_stat(&fscache_n_alloc_op_waits);
-               wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
-                           fscache_wait_bit, TASK_UNINTERRUPTIBLE);
-               _debug("<<< GO");
-       }
+       ret = fscache_wait_for_retrieval_activation(
+               object, op,
+               __fscache_stat(&fscache_n_alloc_op_waits),
+               __fscache_stat(&fscache_n_allocs_object_dead));
+       if (ret < 0)
+               goto error;
 
        /* ask the cache to honour the operation */
+       fscache_stat(&fscache_n_cop_allocate_page);
        ret = object->cache->ops->allocate_page(op, page, gfp);
+       fscache_stat_d(&fscache_n_cop_allocate_page);
 
-       if (ret < 0)
+error:
+       if (ret == -ERESTARTSYS)
+               fscache_stat(&fscache_n_allocs_intr);
+       else if (ret < 0)
                fscache_stat(&fscache_n_allocs_nobufs);
        else
                fscache_stat(&fscache_n_allocs_ok);
@@ -521,7 +673,7 @@ static void fscache_write_op(struct fscache_operation *_op)
        struct fscache_storage *op =
                container_of(_op, struct fscache_storage, op);
        struct fscache_object *object = op->op.object;
-       struct fscache_cookie *cookie = object->cookie;
+       struct fscache_cookie *cookie;
        struct page *page;
        unsigned n;
        void *results[1];
@@ -529,16 +681,19 @@ static void fscache_write_op(struct fscache_operation *_op)
 
        _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage));
 
-       spin_lock(&cookie->lock);
+       fscache_set_op_state(&op->op, "GetPage");
+
        spin_lock(&object->lock);
+       cookie = object->cookie;
 
-       if (!fscache_object_is_active(object)) {
+       if (!fscache_object_is_active(object) || !cookie) {
                spin_unlock(&object->lock);
-               spin_unlock(&cookie->lock);
                _leave("");
                return;
        }
 
+       spin_lock(&cookie->stores_lock);
+
        fscache_stat(&fscache_n_store_calls);
 
        /* find a page to store */
@@ -549,23 +704,35 @@ static void fscache_write_op(struct fscache_operation *_op)
                goto superseded;
        page = results[0];
        _debug("gang %d [%lx]", n, page->index);
-       if (page->index > op->store_limit)
+       if (page->index > op->store_limit) {
+               fscache_stat(&fscache_n_store_pages_over_limit);
                goto superseded;
+       }
 
-       radix_tree_tag_clear(&cookie->stores, page->index,
-                            FSCACHE_COOKIE_PENDING_TAG);
+       if (page) {
+               radix_tree_tag_set(&cookie->stores, page->index,
+                                  FSCACHE_COOKIE_STORING_TAG);
+               radix_tree_tag_clear(&cookie->stores, page->index,
+                                    FSCACHE_COOKIE_PENDING_TAG);
+       }
 
+       spin_unlock(&cookie->stores_lock);
        spin_unlock(&object->lock);
-       spin_unlock(&cookie->lock);
 
        if (page) {
+               fscache_set_op_state(&op->op, "Store");
+               fscache_stat(&fscache_n_store_pages);
+               fscache_stat(&fscache_n_cop_write_page);
                ret = object->cache->ops->write_page(op, page);
-               fscache_end_page_write(cookie, page);
-               page_cache_release(page);
-               if (ret < 0)
+               fscache_stat_d(&fscache_n_cop_write_page);
+               fscache_set_op_state(&op->op, "EndWrite");
+               fscache_end_page_write(object, page);
+               if (ret < 0) {
+                       fscache_set_op_state(&op->op, "Abort");
                        fscache_abort_object(object);
-               else
+               } else {
                        fscache_enqueue_operation(&op->op);
+               }
        }
 
        _leave("");
@@ -575,9 +742,9 @@ superseded:
        /* this writer is going away and there aren't any more things to
         * write */
        _debug("cease");
+       spin_unlock(&cookie->stores_lock);
        clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
        spin_unlock(&object->lock);
-       spin_unlock(&cookie->lock);
        _leave("");
 }
 
@@ -634,6 +801,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
        fscache_operation_init(&op->op, fscache_release_write_op);
        fscache_operation_init_slow(&op->op, fscache_write_op);
        op->op.flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_WAITING);
+       fscache_set_op_name(&op->op, "Write1");
 
        ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM);
        if (ret < 0)
@@ -652,6 +820,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
        /* add the page to the pending-storage radix tree on the backing
         * object */
        spin_lock(&object->lock);
+       spin_lock(&cookie->stores_lock);
 
        _debug("store limit %llx", (unsigned long long) object->store_limit);
 
@@ -672,6 +841,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
        if (test_and_set_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags))
                goto already_pending;
 
+       spin_unlock(&cookie->stores_lock);
        spin_unlock(&object->lock);
 
        op->op.debug_id = atomic_inc_return(&fscache_op_debug_id);
@@ -693,6 +863,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
 already_queued:
        fscache_stat(&fscache_n_stores_again);
 already_pending:
+       spin_unlock(&cookie->stores_lock);
        spin_unlock(&object->lock);
        spin_unlock(&cookie->lock);
        radix_tree_preload_end();
@@ -702,7 +873,9 @@ already_pending:
        return 0;
 
 submit_failed:
+       spin_lock(&cookie->stores_lock);
        radix_tree_delete(&cookie->stores, page->index);
+       spin_unlock(&cookie->stores_lock);
        page_cache_release(page);
        ret = -ENOBUFS;
        goto nobufs;
@@ -763,7 +936,9 @@ void __fscache_uncache_page(struct fscache_cookie *cookie, struct page *page)
        if (TestClearPageFsCache(page) &&
            object->cache->ops->uncache_page) {
                /* the cache backend releases the cookie lock */
+               fscache_stat(&fscache_n_cop_uncache_page);
                object->cache->ops->uncache_page(object, page);
+               fscache_stat_d(&fscache_n_cop_uncache_page);
                goto done;
        }
 
index beeab44..1d9e495 100644 (file)
@@ -37,10 +37,20 @@ int __init fscache_proc_init(void)
                goto error_histogram;
 #endif
 
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+       if (!proc_create("fs/fscache/objects", S_IFREG | 0444, NULL,
+                        &fscache_objlist_fops))
+               goto error_objects;
+#endif
+
        _leave(" = 0");
        return 0;
 
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+error_objects:
+#endif
 #ifdef CONFIG_FSCACHE_HISTOGRAM
+       remove_proc_entry("fs/fscache/histogram", NULL);
 error_histogram:
 #endif
 #ifdef CONFIG_FSCACHE_STATS
@@ -58,6 +68,9 @@ error_dir:
  */
 void fscache_proc_cleanup(void)
 {
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+       remove_proc_entry("fs/fscache/objects", NULL);
+#endif
 #ifdef CONFIG_FSCACHE_HISTOGRAM
        remove_proc_entry("fs/fscache/histogram", NULL);
 #endif
index 65deb99..46435f3 100644 (file)
@@ -25,6 +25,8 @@ atomic_t fscache_n_op_requeue;
 atomic_t fscache_n_op_deferred_release;
 atomic_t fscache_n_op_release;
 atomic_t fscache_n_op_gc;
+atomic_t fscache_n_op_cancelled;
+atomic_t fscache_n_op_rejected;
 
 atomic_t fscache_n_attr_changed;
 atomic_t fscache_n_attr_changed_ok;
@@ -36,6 +38,8 @@ atomic_t fscache_n_allocs;
 atomic_t fscache_n_allocs_ok;
 atomic_t fscache_n_allocs_wait;
 atomic_t fscache_n_allocs_nobufs;
+atomic_t fscache_n_allocs_intr;
+atomic_t fscache_n_allocs_object_dead;
 atomic_t fscache_n_alloc_ops;
 atomic_t fscache_n_alloc_op_waits;
 
@@ -46,6 +50,7 @@ atomic_t fscache_n_retrievals_nodata;
 atomic_t fscache_n_retrievals_nobufs;
 atomic_t fscache_n_retrievals_intr;
 atomic_t fscache_n_retrievals_nomem;
+atomic_t fscache_n_retrievals_object_dead;
 atomic_t fscache_n_retrieval_ops;
 atomic_t fscache_n_retrieval_op_waits;
 
@@ -56,6 +61,14 @@ atomic_t fscache_n_stores_nobufs;
 atomic_t fscache_n_stores_oom;
 atomic_t fscache_n_store_ops;
 atomic_t fscache_n_store_calls;
+atomic_t fscache_n_store_pages;
+atomic_t fscache_n_store_radix_deletes;
+atomic_t fscache_n_store_pages_over_limit;
+
+atomic_t fscache_n_store_vmscan_not_storing;
+atomic_t fscache_n_store_vmscan_gone;
+atomic_t fscache_n_store_vmscan_busy;
+atomic_t fscache_n_store_vmscan_cancelled;
 
 atomic_t fscache_n_marks;
 atomic_t fscache_n_uncaches;
@@ -74,6 +87,7 @@ atomic_t fscache_n_updates_run;
 atomic_t fscache_n_relinquishes;
 atomic_t fscache_n_relinquishes_null;
 atomic_t fscache_n_relinquishes_waitcrt;
+atomic_t fscache_n_relinquishes_retire;
 
 atomic_t fscache_n_cookie_index;
 atomic_t fscache_n_cookie_data;
@@ -84,6 +98,7 @@ atomic_t fscache_n_object_no_alloc;
 atomic_t fscache_n_object_lookups;
 atomic_t fscache_n_object_lookups_negative;
 atomic_t fscache_n_object_lookups_positive;
+atomic_t fscache_n_object_lookups_timed_out;
 atomic_t fscache_n_object_created;
 atomic_t fscache_n_object_avail;
 atomic_t fscache_n_object_dead;
@@ -93,6 +108,23 @@ atomic_t fscache_n_checkaux_okay;
 atomic_t fscache_n_checkaux_update;
 atomic_t fscache_n_checkaux_obsolete;
 
+atomic_t fscache_n_cop_alloc_object;
+atomic_t fscache_n_cop_lookup_object;
+atomic_t fscache_n_cop_lookup_complete;
+atomic_t fscache_n_cop_grab_object;
+atomic_t fscache_n_cop_update_object;
+atomic_t fscache_n_cop_drop_object;
+atomic_t fscache_n_cop_put_object;
+atomic_t fscache_n_cop_sync_cache;
+atomic_t fscache_n_cop_attr_changed;
+atomic_t fscache_n_cop_read_or_alloc_page;
+atomic_t fscache_n_cop_read_or_alloc_pages;
+atomic_t fscache_n_cop_allocate_page;
+atomic_t fscache_n_cop_allocate_pages;
+atomic_t fscache_n_cop_write_page;
+atomic_t fscache_n_cop_uncache_page;
+atomic_t fscache_n_cop_dissociate_pages;
+
 /*
  * display the general statistics
  */
@@ -129,10 +161,11 @@ static int fscache_stats_show(struct seq_file *m, void *v)
                   atomic_read(&fscache_n_acquires_nobufs),
                   atomic_read(&fscache_n_acquires_oom));
 
-       seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u\n",
+       seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u tmo=%u\n",
                   atomic_read(&fscache_n_object_lookups),
                   atomic_read(&fscache_n_object_lookups_negative),
                   atomic_read(&fscache_n_object_lookups_positive),
+                  atomic_read(&fscache_n_object_lookups_timed_out),
                   atomic_read(&fscache_n_object_created));
 
        seq_printf(m, "Updates: n=%u nul=%u run=%u\n",
@@ -140,10 +173,11 @@ static int fscache_stats_show(struct seq_file *m, void *v)
                   atomic_read(&fscache_n_updates_null),
                   atomic_read(&fscache_n_updates_run));
 
-       seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u\n",
+       seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u rtr=%u\n",
                   atomic_read(&fscache_n_relinquishes),
                   atomic_read(&fscache_n_relinquishes_null),
-                  atomic_read(&fscache_n_relinquishes_waitcrt));
+                  atomic_read(&fscache_n_relinquishes_waitcrt),
+                  atomic_read(&fscache_n_relinquishes_retire));
 
        seq_printf(m, "AttrChg: n=%u ok=%u nbf=%u oom=%u run=%u\n",
                   atomic_read(&fscache_n_attr_changed),
@@ -152,14 +186,16 @@ static int fscache_stats_show(struct seq_file *m, void *v)
                   atomic_read(&fscache_n_attr_changed_nomem),
                   atomic_read(&fscache_n_attr_changed_calls));
 
-       seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u\n",
+       seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u int=%u\n",
                   atomic_read(&fscache_n_allocs),
                   atomic_read(&fscache_n_allocs_ok),
                   atomic_read(&fscache_n_allocs_wait),
-                  atomic_read(&fscache_n_allocs_nobufs));
-       seq_printf(m, "Allocs : ops=%u owt=%u\n",
+                  atomic_read(&fscache_n_allocs_nobufs),
+                  atomic_read(&fscache_n_allocs_intr));
+       seq_printf(m, "Allocs : ops=%u owt=%u abt=%u\n",
                   atomic_read(&fscache_n_alloc_ops),
-                  atomic_read(&fscache_n_alloc_op_waits));
+                  atomic_read(&fscache_n_alloc_op_waits),
+                  atomic_read(&fscache_n_allocs_object_dead));
 
        seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u"
                   " int=%u oom=%u\n",
@@ -170,9 +206,10 @@ static int fscache_stats_show(struct seq_file *m, void *v)
                   atomic_read(&fscache_n_retrievals_nobufs),
                   atomic_read(&fscache_n_retrievals_intr),
                   atomic_read(&fscache_n_retrievals_nomem));
-       seq_printf(m, "Retrvls: ops=%u owt=%u\n",
+       seq_printf(m, "Retrvls: ops=%u owt=%u abt=%u\n",
                   atomic_read(&fscache_n_retrieval_ops),
-                  atomic_read(&fscache_n_retrieval_op_waits));
+                  atomic_read(&fscache_n_retrieval_op_waits),
+                  atomic_read(&fscache_n_retrievals_object_dead));
 
        seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n",
                   atomic_read(&fscache_n_stores),
@@ -180,18 +217,49 @@ static int fscache_stats_show(struct seq_file *m, void *v)
                   atomic_read(&fscache_n_stores_again),
                   atomic_read(&fscache_n_stores_nobufs),
                   atomic_read(&fscache_n_stores_oom));
-       seq_printf(m, "Stores : ops=%u run=%u\n",
+       seq_printf(m, "Stores : ops=%u run=%u pgs=%u rxd=%u olm=%u\n",
                   atomic_read(&fscache_n_store_ops),
-                  atomic_read(&fscache_n_store_calls));
+                  atomic_read(&fscache_n_store_calls),
+                  atomic_read(&fscache_n_store_pages),
+                  atomic_read(&fscache_n_store_radix_deletes),
+                  atomic_read(&fscache_n_store_pages_over_limit));
 
-       seq_printf(m, "Ops    : pend=%u run=%u enq=%u\n",
+       seq_printf(m, "VmScan : nos=%u gon=%u bsy=%u can=%u\n",
+                  atomic_read(&fscache_n_store_vmscan_not_storing),
+                  atomic_read(&fscache_n_store_vmscan_gone),
+                  atomic_read(&fscache_n_store_vmscan_busy),
+                  atomic_read(&fscache_n_store_vmscan_cancelled));
+
+       seq_printf(m, "Ops    : pend=%u run=%u enq=%u can=%u rej=%u\n",
                   atomic_read(&fscache_n_op_pend),
                   atomic_read(&fscache_n_op_run),
-                  atomic_read(&fscache_n_op_enqueue));
+                  atomic_read(&fscache_n_op_enqueue),
+                  atomic_read(&fscache_n_op_cancelled),
+                  atomic_read(&fscache_n_op_rejected));
        seq_printf(m, "Ops    : dfr=%u rel=%u gc=%u\n",
                   atomic_read(&fscache_n_op_deferred_release),
                   atomic_read(&fscache_n_op_release),
                   atomic_read(&fscache_n_op_gc));
+
+       seq_printf(m, "CacheOp: alo=%d luo=%d luc=%d gro=%d\n",
+                  atomic_read(&fscache_n_cop_alloc_object),
+                  atomic_read(&fscache_n_cop_lookup_object),
+                  atomic_read(&fscache_n_cop_lookup_complete),
+                  atomic_read(&fscache_n_cop_grab_object));
+       seq_printf(m, "CacheOp: upo=%d dro=%d pto=%d atc=%d syn=%d\n",
+                  atomic_read(&fscache_n_cop_update_object),
+                  atomic_read(&fscache_n_cop_drop_object),
+                  atomic_read(&fscache_n_cop_put_object),
+                  atomic_read(&fscache_n_cop_attr_changed),
+                  atomic_read(&fscache_n_cop_sync_cache));
+       seq_printf(m, "CacheOp: rap=%d ras=%d alp=%d als=%d wrp=%d ucp=%d dsp=%d\n",
+                  atomic_read(&fscache_n_cop_read_or_alloc_page),
+                  atomic_read(&fscache_n_cop_read_or_alloc_pages),
+                  atomic_read(&fscache_n_cop_allocate_page),
+                  atomic_read(&fscache_n_cop_allocate_pages),
+                  atomic_read(&fscache_n_cop_write_page),
+                  atomic_read(&fscache_n_cop_uncache_page),
+                  atomic_read(&fscache_n_cop_dissociate_pages));
        return 0;
 }
 
index 8ada78a..4787ae6 100644 (file)
@@ -385,6 +385,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
        if (fc->no_create)
                return -ENOSYS;
 
+       if (flags & O_DIRECT)
+               return -EINVAL;
+
        forget_req = fuse_get_req(fc);
        if (IS_ERR(forget_req))
                return PTR_ERR(forget_req);
index eacd78a..5b31f77 100644 (file)
@@ -114,7 +114,7 @@ static int __init init_gfs2_fs(void)
        if (error)
                goto fail_unregister;
 
-       error = slow_work_register_user();
+       error = slow_work_register_user(THIS_MODULE);
        if (error)
                goto fail_slow;
 
@@ -163,7 +163,7 @@ static void __exit exit_gfs2_fs(void)
        gfs2_unregister_debugfs();
        unregister_filesystem(&gfs2_fs_type);
        unregister_filesystem(&gfs2meta_fs_type);
-       slow_work_unregister_user();
+       slow_work_unregister_user(THIS_MODULE);
 
        kmem_cache_destroy(gfs2_quotad_cachep);
        kmem_cache_destroy(gfs2_rgrpd_cachep);
index 59d2695..09fa319 100644 (file)
@@ -7,6 +7,7 @@
  * of the GNU General Public License version 2.
  */
 
+#include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/completion.h>
@@ -593,6 +594,7 @@ fail:
 }
 
 struct slow_work_ops gfs2_recover_ops = {
+       .owner   = THIS_MODULE,
        .get_ref = gfs2_recover_get_ref,
        .put_ref = gfs2_recover_put_ref,
        .execute = gfs2_recover_work,
index cfe05c1..3f39be1 100644 (file)
@@ -164,12 +164,15 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
 
        /* XXX FIXME: Where a single physical node actually shows up in two
           frags, we read it twice. Don't do that. */
-       /* Now we're pointing at the first frag which overlaps our page */
+       /* Now we're pointing at the first frag which overlaps our page
+        * (or perhaps is before it, if we've been asked to read off the
+        * end of the file). */
        while(offset < end) {
                D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end));
-               if (unlikely(!frag || frag->ofs > offset)) {
+               if (unlikely(!frag || frag->ofs > offset ||
+                            frag->ofs + frag->size <= offset)) {
                        uint32_t holesize = end - offset;
-                       if (frag) {
+                       if (frag && frag->ofs > offset) {
                                D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset));
                                holesize = min(holesize, frag->ofs - offset);
                        }
index 70fad69..fa58800 100644 (file)
@@ -359,17 +359,13 @@ int nfs_fscache_release_page(struct page *page, gfp_t gfp)
 
        BUG_ON(!cookie);
 
-       if (fscache_check_page_write(cookie, page)) {
-               if (!(gfp & __GFP_WAIT))
-                       return 0;
-               fscache_wait_on_page_write(cookie, page);
-       }
-
        if (PageFsCache(page)) {
                dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n",
                         cookie, page, nfsi);
 
-               fscache_uncache_page(cookie, page);
+               if (!fscache_maybe_release_page(cookie, page, gfp))
+                       return 0;
+
                nfs_add_fscache_stats(page->mapping->host,
                                      NFSIOS_FSCACHE_PAGES_UNCACHED, 1);
        }
index 84d3532..7be0c6f 100644 (file)
@@ -91,6 +91,8 @@ struct fscache_operation {
 #define FSCACHE_OP_WAITING     4       /* cleared when op is woken */
 #define FSCACHE_OP_EXCLUSIVE   5       /* exclusive op, other ops must wait */
 #define FSCACHE_OP_DEAD                6       /* op is now dead */
+#define FSCACHE_OP_DEC_READ_CNT        7       /* decrement object->n_reads on destruction */
+#define FSCACHE_OP_KEEP_FLAGS  0xc0    /* flags to keep when repurposing an op */
 
        atomic_t                usage;
        unsigned                debug_id;       /* debugging ID */
@@ -102,6 +104,16 @@ struct fscache_operation {
 
        /* operation releaser */
        fscache_operation_release_t release;
+
+#ifdef CONFIG_SLOW_WORK_PROC
+       const char *name;               /* operation name */
+       const char *state;              /* operation state */
+#define fscache_set_op_name(OP, N)     do { (OP)->name  = (N); } while(0)
+#define fscache_set_op_state(OP, S)    do { (OP)->state = (S); } while(0)
+#else
+#define fscache_set_op_name(OP, N)     do { } while(0)
+#define fscache_set_op_state(OP, S)    do { } while(0)
+#endif
 };
 
 extern atomic_t fscache_op_debug_id;
@@ -125,6 +137,7 @@ static inline void fscache_operation_init(struct fscache_operation *op,
        op->debug_id = atomic_inc_return(&fscache_op_debug_id);
        op->release = release;
        INIT_LIST_HEAD(&op->pend_link);
+       fscache_set_op_state(op, "Init");
 }
 
 /**
@@ -221,8 +234,10 @@ struct fscache_cache_ops {
        struct fscache_object *(*alloc_object)(struct fscache_cache *cache,
                                               struct fscache_cookie *cookie);
 
-       /* look up the object for a cookie */
-       void (*lookup_object)(struct fscache_object *object);
+       /* look up the object for a cookie
+        * - return -ETIMEDOUT to be requeued
+        */
+       int (*lookup_object)(struct fscache_object *object);
 
        /* finished looking up */
        void (*lookup_complete)(struct fscache_object *object);
@@ -297,12 +312,14 @@ struct fscache_cookie {
        atomic_t                        usage;          /* number of users of this cookie */
        atomic_t                        n_children;     /* number of children of this cookie */
        spinlock_t                      lock;
+       spinlock_t                      stores_lock;    /* lock on page store tree */
        struct hlist_head               backing_objects; /* object(s) backing this file/index */
        const struct fscache_cookie_def *def;           /* definition */
        struct fscache_cookie           *parent;        /* parent of this entry */
        void                            *netfs_data;    /* back pointer to netfs */
        struct radix_tree_root          stores;         /* pages to be stored on this cookie */
 #define FSCACHE_COOKIE_PENDING_TAG     0               /* pages tag: pending write to cache */
+#define FSCACHE_COOKIE_STORING_TAG     1               /* pages tag: writing to cache */
 
        unsigned long                   flags;
 #define FSCACHE_COOKIE_LOOKING_UP      0       /* T if non-index cookie being looked up still */
@@ -337,6 +354,7 @@ struct fscache_object {
                FSCACHE_OBJECT_RECYCLING,       /* retiring object */
                FSCACHE_OBJECT_WITHDRAWING,     /* withdrawing object */
                FSCACHE_OBJECT_DEAD,            /* object is now dead */
+               FSCACHE_OBJECT__NSTATES
        } state;
 
        int                     debug_id;       /* debugging ID */
@@ -345,6 +363,7 @@ struct fscache_object {
        int                     n_obj_ops;      /* number of object ops outstanding on object */
        int                     n_in_progress;  /* number of ops in progress */
        int                     n_exclusive;    /* number of exclusive ops queued */
+       atomic_t                n_reads;        /* number of read ops in progress */
        spinlock_t              lock;           /* state and operations lock */
 
        unsigned long           lookup_jif;     /* time at which lookup started */
@@ -358,6 +377,7 @@ struct fscache_object {
 #define FSCACHE_OBJECT_EV_RELEASE      4       /* T if netfs requested object release */
 #define FSCACHE_OBJECT_EV_RETIRE       5       /* T if netfs requested object retirement */
 #define FSCACHE_OBJECT_EV_WITHDRAW     6       /* T if cache requested object withdrawal */
+#define FSCACHE_OBJECT_EVENTS_MASK     0x7f    /* mask of all events*/
 
        unsigned long           flags;
 #define FSCACHE_OBJECT_LOCK            0       /* T if object is busy being processed */
@@ -373,7 +393,11 @@ struct fscache_object {
        struct list_head        dependents;     /* FIFO of dependent objects */
        struct list_head        dep_link;       /* link in parent's dependents list */
        struct list_head        pending_ops;    /* unstarted operations on this object */
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+       struct rb_node          objlist_link;   /* link in global object list */
+#endif
        pgoff_t                 store_limit;    /* current storage limit */
+       loff_t                  store_limit_l;  /* current storage limit */
 };
 
 extern const char *fscache_object_states[];
@@ -383,6 +407,10 @@ extern const char *fscache_object_states[];
         (obj)->state >= FSCACHE_OBJECT_AVAILABLE &&          \
         (obj)->state < FSCACHE_OBJECT_DYING)
 
+#define fscache_object_is_dead(obj)                            \
+       (test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) &&     \
+        (obj)->state >= FSCACHE_OBJECT_DYING)
+
 extern const struct slow_work_ops fscache_object_slow_work_ops;
 
 /**
@@ -414,6 +442,7 @@ void fscache_object_init(struct fscache_object *object,
        object->events = object->event_mask = 0;
        object->flags = 0;
        object->store_limit = 0;
+       object->store_limit_l = 0;
        object->cache = cache;
        object->cookie = cookie;
        object->parent = NULL;
@@ -422,6 +451,12 @@ void fscache_object_init(struct fscache_object *object,
 extern void fscache_object_lookup_negative(struct fscache_object *object);
 extern void fscache_obtained_object(struct fscache_object *object);
 
+#ifdef CONFIG_FSCACHE_OBJECT_LIST
+extern void fscache_object_destroy(struct fscache_object *object);
+#else
+#define fscache_object_destroy(object) do {} while(0)
+#endif
+
 /**
  * fscache_object_destroyed - Note destruction of an object in a cache
  * @cache: The cache from which the object came
@@ -460,6 +495,7 @@ static inline void fscache_object_lookup_error(struct fscache_object *object)
 static inline
 void fscache_set_store_limit(struct fscache_object *object, loff_t i_size)
 {
+       object->store_limit_l = i_size;
        object->store_limit = i_size >> PAGE_SHIFT;
        if (i_size & ~PAGE_MASK)
                object->store_limit++;
index 6d8ee46..595ce49 100644 (file)
@@ -202,6 +202,8 @@ extern int __fscache_write_page(struct fscache_cookie *, struct page *, gfp_t);
 extern void __fscache_uncache_page(struct fscache_cookie *, struct page *);
 extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *);
 extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *);
+extern bool __fscache_maybe_release_page(struct fscache_cookie *, struct page *,
+                                        gfp_t);
 
 /**
  * fscache_register_netfs - Register a filesystem as desiring caching services
@@ -615,4 +617,29 @@ void fscache_wait_on_page_write(struct fscache_cookie *cookie,
                __fscache_wait_on_page_write(cookie, page);
 }
 
+/**
+ * fscache_maybe_release_page - Consider releasing a page, cancelling a store
+ * @cookie: The cookie representing the cache object
+ * @page: The netfs page that is being cached.
+ * @gfp: The gfp flags passed to releasepage()
+ *
+ * Consider releasing a page for the vmscan algorithm, on behalf of the netfs's
+ * releasepage() call.  A storage request on the page may cancelled if it is
+ * not currently being processed.
+ *
+ * The function returns true if the page no longer has a storage request on it,
+ * and false if a storage request is left in place.  If true is returned, the
+ * page will have been passed to fscache_uncache_page().  If false is returned
+ * the page cannot be freed yet.
+ */
+static inline
+bool fscache_maybe_release_page(struct fscache_cookie *cookie,
+                               struct page *page,
+                               gfp_t gfp)
+{
+       if (fscache_cookie_valid(cookie) && PageFsCache(page))
+               return __fscache_maybe_release_page(cookie, page, gfp);
+       return false;
+}
+
 #endif /* _LINUX_FSCACHE_H */
index b65c888..5035a26 100644 (file)
 #ifdef CONFIG_SLOW_WORK
 
 #include <linux/sysctl.h>
+#include <linux/timer.h>
 
 struct slow_work;
+#ifdef CONFIG_SLOW_WORK_PROC
+struct seq_file;
+#endif
 
 /*
  * The operations used to support slow work items
  */
 struct slow_work_ops {
+       /* owner */
+       struct module *owner;
+
        /* get a ref on a work item
         * - return 0 if successful, -ve if not
         */
@@ -34,6 +41,11 @@ struct slow_work_ops {
 
        /* execute a work item */
        void (*execute)(struct slow_work *work);
+
+#ifdef CONFIG_SLOW_WORK_PROC
+       /* describe a work item for /proc */
+       void (*desc)(struct slow_work *work, struct seq_file *m);
+#endif
 };
 
 /*
@@ -42,13 +54,24 @@ struct slow_work_ops {
  *   queued
  */
 struct slow_work {
+       struct module           *owner; /* the owning module */
        unsigned long           flags;
 #define SLOW_WORK_PENDING      0       /* item pending (further) execution */
 #define SLOW_WORK_EXECUTING    1       /* item currently executing */
 #define SLOW_WORK_ENQ_DEFERRED 2       /* item enqueue deferred */
 #define SLOW_WORK_VERY_SLOW    3       /* item is very slow */
+#define SLOW_WORK_CANCELLING   4       /* item is being cancelled, don't enqueue */
+#define SLOW_WORK_DELAYED      5       /* item is struct delayed_slow_work with active timer */
        const struct slow_work_ops *ops; /* operations table for this item */
        struct list_head        link;   /* link in queue */
+#ifdef CONFIG_SLOW_WORK_PROC
+       struct timespec         mark;   /* jiffies at which queued or exec begun */
+#endif
+};
+
+struct delayed_slow_work {
+       struct slow_work        work;
+       struct timer_list       timer;
 };
 
 /**
@@ -66,6 +89,20 @@ static inline void slow_work_init(struct slow_work *work,
        INIT_LIST_HEAD(&work->link);
 }
 
+/**
+ * slow_work_init - Initialise a delayed slow work item
+ * @work: The work item to initialise
+ * @ops: The operations to use to handle the slow work item
+ *
+ * Initialise a delayed slow work item.
+ */
+static inline void delayed_slow_work_init(struct delayed_slow_work *dwork,
+                                         const struct slow_work_ops *ops)
+{
+       init_timer(&dwork->timer);
+       slow_work_init(&dwork->work, ops);
+}
+
 /**
  * vslow_work_init - Initialise a very slow work item
  * @work: The work item to initialise
@@ -83,9 +120,40 @@ static inline void vslow_work_init(struct slow_work *work,
        INIT_LIST_HEAD(&work->link);
 }
 
+/**
+ * slow_work_is_queued - Determine if a slow work item is on the work queue
+ * work: The work item to test
+ *
+ * Determine if the specified slow-work item is on the work queue.  This
+ * returns true if it is actually on the queue.
+ *
+ * If the item is executing and has been marked for requeue when execution
+ * finishes, then false will be returned.
+ *
+ * Anyone wishing to wait for completion of execution can wait on the
+ * SLOW_WORK_EXECUTING bit.
+ */
+static inline bool slow_work_is_queued(struct slow_work *work)
+{
+       unsigned long flags = work->flags;
+       return flags & SLOW_WORK_PENDING && !(flags & SLOW_WORK_EXECUTING);
+}
+
 extern int slow_work_enqueue(struct slow_work *work);
-extern int slow_work_register_user(void);
-extern void slow_work_unregister_user(void);
+extern void slow_work_cancel(struct slow_work *work);
+extern int slow_work_register_user(struct module *owner);
+extern void slow_work_unregister_user(struct module *owner);
+
+extern int delayed_slow_work_enqueue(struct delayed_slow_work *dwork,
+                                    unsigned long delay);
+
+static inline void delayed_slow_work_cancel(struct delayed_slow_work *dwork)
+{
+       slow_work_cancel(&dwork->work);
+}
+
+extern bool slow_work_sleep_till_thread_needed(struct slow_work *work,
+                                              signed long *_timeout);
 
 #ifdef CONFIG_SYSCTL
 extern ctl_table slow_work_sysctls[];
index c75b960..998c30f 100644 (file)
@@ -1283,6 +1283,12 @@ enum ieee80211_filter_flags {
  *
  * These flags are used with the ampdu_action() callback in
  * &struct ieee80211_ops to indicate which action is needed.
+ *
+ * Note that drivers MUST be able to deal with a TX aggregation
+ * session being stopped even before they OK'ed starting it by
+ * calling ieee80211_start_tx_ba_cb(_irqsafe), because the peer
+ * might receive the addBA frame and send a delBA right away!
+ *
  * @IEEE80211_AMPDU_RX_START: start Rx aggregation
  * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation
  * @IEEE80211_AMPDU_TX_START: start Tx aggregation
index cd2e187..0a47456 100644 (file)
@@ -893,7 +893,6 @@ struct sctp_transport {
         */
        /* RTO         : The current retransmission timeout value.  */
        unsigned long rto;
-       unsigned long last_rto;
 
        __u32 rtt;              /* This is the most recent RTT.  */
 
index 9af48cb..f097ae3 100644 (file)
@@ -145,6 +145,7 @@ struct scsi_device {
        unsigned retry_hwerror:1;       /* Retry HARDWARE_ERROR */
        unsigned last_sector_bug:1;     /* do not use multisector accesses on
                                           SD_LAST_BUGGY_SECTORS */
+       unsigned is_visible:1;  /* is the device visible in sysfs */
 
        DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
        struct list_head event_list;    /* asserted events */
index 9e03ef8..ab5c648 100644 (file)
@@ -1098,6 +1098,16 @@ config SLOW_WORK
 
          See Documentation/slow-work.txt.
 
+config SLOW_WORK_PROC
+       bool "Slow work debugging through /proc"
+       default n
+       depends on SLOW_WORK && PROC_FS
+       help
+         Display the contents of the slow work run queue through /proc,
+         including items currently executing.
+
+         See Documentation/slow-work.txt.
+
 endmenu                # General setup
 
 config HAVE_GENERIC_DMA_COHERENT
index b8d4cd8..776ffed 100644 (file)
@@ -94,6 +94,7 @@ obj-$(CONFIG_X86_DS) += trace/
 obj-$(CONFIG_RING_BUFFER) += trace/
 obj-$(CONFIG_SMP) += sched_cpupri.o
 obj-$(CONFIG_SLOW_WORK) += slow-work.o
+obj-$(CONFIG_SLOW_WORK_PROC) += slow-work-proc.o
 obj-$(CONFIG_PERF_EVENTS) += perf_event.o
 
 ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
diff --git a/kernel/slow-work-proc.c b/kernel/slow-work-proc.c
new file mode 100644 (file)
index 0000000..3988032
--- /dev/null
@@ -0,0 +1,227 @@
+/* Slow work debugging
+ *
+ * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/slow-work.h>
+#include <linux/fs.h>
+#include <linux/time.h>
+#include <linux/seq_file.h>
+#include "slow-work.h"
+
+#define ITERATOR_SHIFT         (BITS_PER_LONG - 4)
+#define ITERATOR_SELECTOR      (0xfUL << ITERATOR_SHIFT)
+#define ITERATOR_COUNTER       (~ITERATOR_SELECTOR)
+
+void slow_work_new_thread_desc(struct slow_work *work, struct seq_file *m)
+{
+       seq_puts(m, "Slow-work: New thread");
+}
+
+/*
+ * Render the time mark field on a work item into a 5-char time with units plus
+ * a space
+ */
+static void slow_work_print_mark(struct seq_file *m, struct slow_work *work)
+{
+       struct timespec now, diff;
+
+       now = CURRENT_TIME;
+       diff = timespec_sub(now, work->mark);
+
+       if (diff.tv_sec < 0)
+               seq_puts(m, "  -ve ");
+       else if (diff.tv_sec == 0 && diff.tv_nsec < 1000)
+               seq_printf(m, "%3luns ", diff.tv_nsec);
+       else if (diff.tv_sec == 0 && diff.tv_nsec < 1000000)
+               seq_printf(m, "%3luus ", diff.tv_nsec / 1000);
+       else if (diff.tv_sec == 0 && diff.tv_nsec < 1000000000)
+               seq_printf(m, "%3lums ", diff.tv_nsec / 1000000);
+       else if (diff.tv_sec <= 1)
+               seq_puts(m, "   1s ");
+       else if (diff.tv_sec < 60)
+               seq_printf(m, "%4lus ", diff.tv_sec);
+       else if (diff.tv_sec < 60 * 60)
+               seq_printf(m, "%4lum ", diff.tv_sec / 60);
+       else if (diff.tv_sec < 60 * 60 * 24)
+               seq_printf(m, "%4luh ", diff.tv_sec / 3600);
+       else
+               seq_puts(m, "exces ");
+}
+
+/*
+ * Describe a slow work item for /proc
+ */
+static int slow_work_runqueue_show(struct seq_file *m, void *v)
+{
+       struct slow_work *work;
+       struct list_head *p = v;
+       unsigned long id;
+
+       switch ((unsigned long) v) {
+       case 1:
+               seq_puts(m, "THR PID   ITEM ADDR        FL MARK  DESC\n");
+               return 0;
+       case 2:
+               seq_puts(m, "=== ===== ================ == ===== ==========\n");
+               return 0;
+
+       case 3 ... 3 + SLOW_WORK_THREAD_LIMIT - 1:
+               id = (unsigned long) v - 3;
+
+               read_lock(&slow_work_execs_lock);
+               work = slow_work_execs[id];
+               if (work) {
+                       smp_read_barrier_depends();
+
+                       seq_printf(m, "%3lu %5d %16p %2lx ",
+                                  id, slow_work_pids[id], work, work->flags);
+                       slow_work_print_mark(m, work);
+
+                       if (work->ops->desc)
+                               work->ops->desc(work, m);
+                       seq_putc(m, '\n');
+               }
+               read_unlock(&slow_work_execs_lock);
+               return 0;
+
+       default:
+               work = list_entry(p, struct slow_work, link);
+               seq_printf(m, "%3s     - %16p %2lx ",
+                          work->flags & SLOW_WORK_VERY_SLOW ? "vsq" : "sq",
+                          work, work->flags);
+               slow_work_print_mark(m, work);
+
+               if (work->ops->desc)
+                       work->ops->desc(work, m);
+               seq_putc(m, '\n');
+               return 0;
+       }
+}
+
+/*
+ * map the iterator to a work item
+ */
+static void *slow_work_runqueue_index(struct seq_file *m, loff_t *_pos)
+{
+       struct list_head *p;
+       unsigned long count, id;
+
+       switch (*_pos >> ITERATOR_SHIFT) {
+       case 0x0:
+               if (*_pos == 0)
+                       *_pos = 1;
+               if (*_pos < 3)
+                       return (void *)(unsigned long) *_pos;
+               if (*_pos < 3 + SLOW_WORK_THREAD_LIMIT)
+                       for (id = *_pos - 3;
+                            id < SLOW_WORK_THREAD_LIMIT;
+                            id++, (*_pos)++)
+                               if (slow_work_execs[id])
+                                       return (void *)(unsigned long) *_pos;
+               *_pos = 0x1UL << ITERATOR_SHIFT;
+
+       case 0x1:
+               count = *_pos & ITERATOR_COUNTER;
+               list_for_each(p, &slow_work_queue) {
+                       if (count == 0)
+                               return p;
+                       count--;
+               }
+               *_pos = 0x2UL << ITERATOR_SHIFT;
+
+       case 0x2:
+               count = *_pos & ITERATOR_COUNTER;
+               list_for_each(p, &vslow_work_queue) {
+                       if (count == 0)
+                               return p;
+                       count--;
+               }
+               *_pos = 0x3UL << ITERATOR_SHIFT;
+
+       default:
+               return NULL;
+       }
+}
+
+/*
+ * set up the iterator to start reading from the first line
+ */
+static void *slow_work_runqueue_start(struct seq_file *m, loff_t *_pos)
+{
+       spin_lock_irq(&slow_work_queue_lock);
+       return slow_work_runqueue_index(m, _pos);
+}
+
+/*
+ * move to the next line
+ */
+static void *slow_work_runqueue_next(struct seq_file *m, void *v, loff_t *_pos)
+{
+       struct list_head *p = v;
+       unsigned long selector = *_pos >> ITERATOR_SHIFT;
+
+       (*_pos)++;
+       switch (selector) {
+       case 0x0:
+               return slow_work_runqueue_index(m, _pos);
+
+       case 0x1:
+               if (*_pos >> ITERATOR_SHIFT == 0x1) {
+                       p = p->next;
+                       if (p != &slow_work_queue)
+                               return p;
+               }
+               *_pos = 0x2UL << ITERATOR_SHIFT;
+               p = &vslow_work_queue;
+
+       case 0x2:
+               if (*_pos >> ITERATOR_SHIFT == 0x2) {
+                       p = p->next;
+                       if (p != &vslow_work_queue)
+                               return p;
+               }
+               *_pos = 0x3UL << ITERATOR_SHIFT;
+
+       default:
+               return NULL;
+       }
+}
+
+/*
+ * clean up after reading
+ */
+static void slow_work_runqueue_stop(struct seq_file *m, void *v)
+{
+       spin_unlock_irq(&slow_work_queue_lock);
+}
+
+static const struct seq_operations slow_work_runqueue_ops = {
+       .start          = slow_work_runqueue_start,
+       .stop           = slow_work_runqueue_stop,
+       .next           = slow_work_runqueue_next,
+       .show           = slow_work_runqueue_show,
+};
+
+/*
+ * open "/proc/slow_work_rq" to list queue contents
+ */
+static int slow_work_runqueue_open(struct inode *inode, struct file *file)
+{
+       return seq_open(file, &slow_work_runqueue_ops);
+}
+
+const struct file_operations slow_work_runqueue_fops = {
+       .owner          = THIS_MODULE,
+       .open           = slow_work_runqueue_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = seq_release,
+};
index 0d31135..da94f3c 100644 (file)
 #include <linux/kthread.h>
 #include <linux/freezer.h>
 #include <linux/wait.h>
-
-#define SLOW_WORK_CULL_TIMEOUT (5 * HZ)        /* cull threads 5s after running out of
-                                        * things to do */
-#define SLOW_WORK_OOM_TIMEOUT (5 * HZ) /* can't start new threads for 5s after
-                                        * OOM */
+#include <linux/proc_fs.h>
+#include "slow-work.h"
 
 static void slow_work_cull_timeout(unsigned long);
 static void slow_work_oom_timeout(unsigned long);
@@ -46,7 +43,7 @@ static unsigned vslow_work_proportion = 50; /* % of threads that may process
 
 #ifdef CONFIG_SYSCTL
 static const int slow_work_min_min_threads = 2;
-static int slow_work_max_max_threads = 255;
+static int slow_work_max_max_threads = SLOW_WORK_THREAD_LIMIT;
 static const int slow_work_min_vslow = 1;
 static const int slow_work_max_vslow = 99;
 
@@ -97,6 +94,32 @@ static DEFINE_TIMER(slow_work_cull_timer, slow_work_cull_timeout, 0, 0);
 static DEFINE_TIMER(slow_work_oom_timer, slow_work_oom_timeout, 0, 0);
 static struct slow_work slow_work_new_thread; /* new thread starter */
 
+/*
+ * slow work ID allocation (use slow_work_queue_lock)
+ */
+static DECLARE_BITMAP(slow_work_ids, SLOW_WORK_THREAD_LIMIT);
+
+/*
+ * Unregistration tracking to prevent put_ref() from disappearing during module
+ * unload
+ */
+#ifdef CONFIG_MODULES
+static struct module *slow_work_thread_processing[SLOW_WORK_THREAD_LIMIT];
+static struct module *slow_work_unreg_module;
+static struct slow_work *slow_work_unreg_work_item;
+static DECLARE_WAIT_QUEUE_HEAD(slow_work_unreg_wq);
+static DEFINE_MUTEX(slow_work_unreg_sync_lock);
+#endif
+
+/*
+ * Data for tracking currently executing items for indication through /proc
+ */
+#ifdef CONFIG_SLOW_WORK_PROC
+struct slow_work *slow_work_execs[SLOW_WORK_THREAD_LIMIT];
+pid_t slow_work_pids[SLOW_WORK_THREAD_LIMIT];
+DEFINE_RWLOCK(slow_work_execs_lock);
+#endif
+
 /*
  * The queues of work items and the lock governing access to them.  These are
  * shared between all the CPUs.  It doesn't make sense to have per-CPU queues
@@ -105,9 +128,18 @@ static struct slow_work slow_work_new_thread; /* new thread starter */
  * There are two queues of work items: one for slow work items, and one for
  * very slow work items.
  */
-static LIST_HEAD(slow_work_queue);
-static LIST_HEAD(vslow_work_queue);
-static DEFINE_SPINLOCK(slow_work_queue_lock);
+LIST_HEAD(slow_work_queue);
+LIST_HEAD(vslow_work_queue);
+DEFINE_SPINLOCK(slow_work_queue_lock);
+
+/*
+ * The following are two wait queues that get pinged when a work item is placed
+ * on an empty queue.  These allow work items that are hogging a thread by
+ * sleeping in a way that could be deferred to yield their thread and enqueue
+ * themselves.
+ */
+static DECLARE_WAIT_QUEUE_HEAD(slow_work_queue_waits_for_occupation);
+static DECLARE_WAIT_QUEUE_HEAD(vslow_work_queue_waits_for_occupation);
 
 /*
  * The thread controls.  A variable used to signal to the threads that they
@@ -126,6 +158,20 @@ static DECLARE_COMPLETION(slow_work_last_thread_exited);
 static int slow_work_user_count;
 static DEFINE_MUTEX(slow_work_user_lock);
 
+static inline int slow_work_get_ref(struct slow_work *work)
+{
+       if (work->ops->get_ref)
+               return work->ops->get_ref(work);
+
+       return 0;
+}
+
+static inline void slow_work_put_ref(struct slow_work *work)
+{
+       if (work->ops->put_ref)
+               work->ops->put_ref(work);
+}
+
 /*
  * Calculate the maximum number of active threads in the pool that are
  * permitted to process very slow work items.
@@ -149,8 +195,11 @@ static unsigned slow_work_calc_vsmax(void)
  * Attempt to execute stuff queued on a slow thread.  Return true if we managed
  * it, false if there was nothing to do.
  */
-static bool slow_work_execute(void)
+static noinline bool slow_work_execute(int id)
 {
+#ifdef CONFIG_MODULES
+       struct module *module;
+#endif
        struct slow_work *work = NULL;
        unsigned vsmax;
        bool very_slow;
@@ -186,6 +235,16 @@ static bool slow_work_execute(void)
        } else {
                very_slow = false; /* avoid the compiler warning */
        }
+
+#ifdef CONFIG_MODULES
+       if (work)
+               slow_work_thread_processing[id] = work->owner;
+#endif
+       if (work) {
+               slow_work_mark_time(work);
+               slow_work_begin_exec(id, work);
+       }
+
        spin_unlock_irq(&slow_work_queue_lock);
 
        if (!work)
@@ -194,12 +253,19 @@ static bool slow_work_execute(void)
        if (!test_and_clear_bit(SLOW_WORK_PENDING, &work->flags))
                BUG();
 
-       work->ops->execute(work);
+       /* don't execute if the work is in the process of being cancelled */
+       if (!test_bit(SLOW_WORK_CANCELLING, &work->flags))
+               work->ops->execute(work);
 
        if (very_slow)
                atomic_dec(&vslow_work_executing_count);
        clear_bit_unlock(SLOW_WORK_EXECUTING, &work->flags);
 
+       /* wake up anyone waiting for this work to be complete */
+       wake_up_bit(&work->flags, SLOW_WORK_EXECUTING);
+
+       slow_work_end_exec(id, work);
+
        /* if someone tried to enqueue the item whilst we were executing it,
         * then it'll be left unenqueued to avoid multiple threads trying to
         * execute it simultaneously
@@ -219,7 +285,18 @@ static bool slow_work_execute(void)
                spin_unlock_irq(&slow_work_queue_lock);
        }
 
-       work->ops->put_ref(work);
+       /* sort out the race between module unloading and put_ref() */
+       slow_work_put_ref(work);
+
+#ifdef CONFIG_MODULES
+       module = slow_work_thread_processing[id];
+       slow_work_thread_processing[id] = NULL;
+       smp_mb();
+       if (slow_work_unreg_work_item == work ||
+           slow_work_unreg_module == module)
+               wake_up_all(&slow_work_unreg_wq);
+#endif
+
        return true;
 
 auto_requeue:
@@ -227,14 +304,60 @@ auto_requeue:
         * - we transfer our ref on the item back to the appropriate queue
         * - don't wake another thread up as we're awake already
         */
+       slow_work_mark_time(work);
        if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags))
                list_add_tail(&work->link, &vslow_work_queue);
        else
                list_add_tail(&work->link, &slow_work_queue);
        spin_unlock_irq(&slow_work_queue_lock);
+       slow_work_thread_processing[id] = NULL;
        return true;
 }
 
+/**
+ * slow_work_sleep_till_thread_needed - Sleep till thread needed by other work
+ * work: The work item under execution that wants to sleep
+ * _timeout: Scheduler sleep timeout
+ *
+ * Allow a requeueable work item to sleep on a slow-work processor thread until
+ * that thread is needed to do some other work or the sleep is interrupted by
+ * some other event.
+ *
+ * The caller must set up a wake up event before calling this and must have set
+ * the appropriate sleep mode (such as TASK_UNINTERRUPTIBLE) and tested its own
+ * condition before calling this function as no test is made here.
+ *
+ * False is returned if there is nothing on the queue; true is returned if the
+ * work item should be requeued
+ */
+bool slow_work_sleep_till_thread_needed(struct slow_work *work,
+                                       signed long *_timeout)
+{
+       wait_queue_head_t *wfo_wq;
+       struct list_head *queue;
+
+       DEFINE_WAIT(wait);
+
+       if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
+               wfo_wq = &vslow_work_queue_waits_for_occupation;
+               queue = &vslow_work_queue;
+       } else {
+               wfo_wq = &slow_work_queue_waits_for_occupation;
+               queue = &slow_work_queue;
+       }
+
+       if (!list_empty(queue))
+               return true;
+
+       add_wait_queue_exclusive(wfo_wq, &wait);
+       if (list_empty(queue))
+               *_timeout = schedule_timeout(*_timeout);
+       finish_wait(wfo_wq, &wait);
+
+       return !list_empty(queue);
+}
+EXPORT_SYMBOL(slow_work_sleep_till_thread_needed);
+
 /**
  * slow_work_enqueue - Schedule a slow work item for processing
  * @work: The work item to queue
@@ -260,16 +383,22 @@ auto_requeue:
  * allowed to pick items to execute.  This ensures that very slow items won't
  * overly block ones that are just ordinarily slow.
  *
- * Returns 0 if successful, -EAGAIN if not.
+ * Returns 0 if successful, -EAGAIN if not (or -ECANCELED if cancelled work is
+ * attempted queued)
  */
 int slow_work_enqueue(struct slow_work *work)
 {
+       wait_queue_head_t *wfo_wq;
+       struct list_head *queue;
        unsigned long flags;
+       int ret;
+
+       if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
+               return -ECANCELED;
 
        BUG_ON(slow_work_user_count <= 0);
        BUG_ON(!work);
        BUG_ON(!work->ops);
-       BUG_ON(!work->ops->get_ref);
 
        /* when honouring an enqueue request, we only promise that we will run
         * the work function in the future; we do not promise to run it once
@@ -280,8 +409,19 @@ int slow_work_enqueue(struct slow_work *work)
         * maintaining our promise
         */
        if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) {
+               if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
+                       wfo_wq = &vslow_work_queue_waits_for_occupation;
+                       queue = &vslow_work_queue;
+               } else {
+                       wfo_wq = &slow_work_queue_waits_for_occupation;
+                       queue = &slow_work_queue;
+               }
+
                spin_lock_irqsave(&slow_work_queue_lock, flags);
 
+               if (unlikely(test_bit(SLOW_WORK_CANCELLING, &work->flags)))
+                       goto cancelled;
+
                /* we promise that we will not attempt to execute the work
                 * function in more than one thread simultaneously
                 *
@@ -299,25 +439,221 @@ int slow_work_enqueue(struct slow_work *work)
                if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) {
                        set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags);
                } else {
-                       if (work->ops->get_ref(work) < 0)
-                               goto cant_get_ref;
-                       if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags))
-                               list_add_tail(&work->link, &vslow_work_queue);
-                       else
-                               list_add_tail(&work->link, &slow_work_queue);
+                       ret = slow_work_get_ref(work);
+                       if (ret < 0)
+                               goto failed;
+                       slow_work_mark_time(work);
+                       list_add_tail(&work->link, queue);
                        wake_up(&slow_work_thread_wq);
+
+                       /* if someone who could be requeued is sleeping on a
+                        * thread, then ask them to yield their thread */
+                       if (work->link.prev == queue)
+                               wake_up(wfo_wq);
                }
 
                spin_unlock_irqrestore(&slow_work_queue_lock, flags);
        }
        return 0;
 
-cant_get_ref:
+cancelled:
+       ret = -ECANCELED;
+failed:
        spin_unlock_irqrestore(&slow_work_queue_lock, flags);
-       return -EAGAIN;
+       return ret;
 }
 EXPORT_SYMBOL(slow_work_enqueue);
 
+static int slow_work_wait(void *word)
+{
+       schedule();
+       return 0;
+}
+
+/**
+ * slow_work_cancel - Cancel a slow work item
+ * @work: The work item to cancel
+ *
+ * This function will cancel a previously enqueued work item. If we cannot
+ * cancel the work item, it is guarenteed to have run when this function
+ * returns.
+ */
+void slow_work_cancel(struct slow_work *work)
+{
+       bool wait = true, put = false;
+
+       set_bit(SLOW_WORK_CANCELLING, &work->flags);
+       smp_mb();
+
+       /* if the work item is a delayed work item with an active timer, we
+        * need to wait for the timer to finish _before_ getting the spinlock,
+        * lest we deadlock against the timer routine
+        *
+        * the timer routine will leave DELAYED set if it notices the
+        * CANCELLING flag in time
+        */
+       if (test_bit(SLOW_WORK_DELAYED, &work->flags)) {
+               struct delayed_slow_work *dwork =
+                       container_of(work, struct delayed_slow_work, work);
+               del_timer_sync(&dwork->timer);
+       }
+
+       spin_lock_irq(&slow_work_queue_lock);
+
+       if (test_bit(SLOW_WORK_DELAYED, &work->flags)) {
+               /* the timer routine aborted or never happened, so we are left
+                * holding the timer's reference on the item and should just
+                * drop the pending flag and wait for any ongoing execution to
+                * finish */
+               struct delayed_slow_work *dwork =
+                       container_of(work, struct delayed_slow_work, work);
+
+               BUG_ON(timer_pending(&dwork->timer));
+               BUG_ON(!list_empty(&work->link));
+
+               clear_bit(SLOW_WORK_DELAYED, &work->flags);
+               put = true;
+               clear_bit(SLOW_WORK_PENDING, &work->flags);
+
+       } else if (test_bit(SLOW_WORK_PENDING, &work->flags) &&
+                  !list_empty(&work->link)) {
+               /* the link in the pending queue holds a reference on the item
+                * that we will need to release */
+               list_del_init(&work->link);
+               wait = false;
+               put = true;
+               clear_bit(SLOW_WORK_PENDING, &work->flags);
+
+       } else if (test_and_clear_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags)) {
+               /* the executor is holding our only reference on the item, so
+                * we merely need to wait for it to finish executing */
+               clear_bit(SLOW_WORK_PENDING, &work->flags);
+       }
+
+       spin_unlock_irq(&slow_work_queue_lock);
+
+       /* the EXECUTING flag is set by the executor whilst the spinlock is set
+        * and before the item is dequeued - so assuming the above doesn't
+        * actually dequeue it, simply waiting for the EXECUTING flag to be
+        * released here should be sufficient */
+       if (wait)
+               wait_on_bit(&work->flags, SLOW_WORK_EXECUTING, slow_work_wait,
+                           TASK_UNINTERRUPTIBLE);
+
+       clear_bit(SLOW_WORK_CANCELLING, &work->flags);
+       if (put)
+               slow_work_put_ref(work);
+}
+EXPORT_SYMBOL(slow_work_cancel);
+
+/*
+ * Handle expiry of the delay timer, indicating that a delayed slow work item
+ * should now be queued if not cancelled
+ */
+static void delayed_slow_work_timer(unsigned long data)
+{
+       wait_queue_head_t *wfo_wq;
+       struct list_head *queue;
+       struct slow_work *work = (struct slow_work *) data;
+       unsigned long flags;
+       bool queued = false, put = false, first = false;
+
+       if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) {
+               wfo_wq = &vslow_work_queue_waits_for_occupation;
+               queue = &vslow_work_queue;
+       } else {
+               wfo_wq = &slow_work_queue_waits_for_occupation;
+               queue = &slow_work_queue;
+       }
+
+       spin_lock_irqsave(&slow_work_queue_lock, flags);
+       if (likely(!test_bit(SLOW_WORK_CANCELLING, &work->flags))) {
+               clear_bit(SLOW_WORK_DELAYED, &work->flags);
+
+               if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) {
+                       /* we discard the reference the timer was holding in
+                        * favour of the one the executor holds */
+                       set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags);
+                       put = true;
+               } else {
+                       slow_work_mark_time(work);
+                       list_add_tail(&work->link, queue);
+                       queued = true;
+                       if (work->link.prev == queue)
+                               first = true;
+               }
+       }
+
+       spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+       if (put)
+               slow_work_put_ref(work);
+       if (first)
+               wake_up(wfo_wq);
+       if (queued)
+               wake_up(&slow_work_thread_wq);
+}
+
+/**
+ * delayed_slow_work_enqueue - Schedule a delayed slow work item for processing
+ * @dwork: The delayed work item to queue
+ * @delay: When to start executing the work, in jiffies from now
+ *
+ * This is similar to slow_work_enqueue(), but it adds a delay before the work
+ * is actually queued for processing.
+ *
+ * The item can have delayed processing requested on it whilst it is being
+ * executed.  The delay will begin immediately, and if it expires before the
+ * item finishes executing, the item will be placed back on the queue when it
+ * has done executing.
+ */
+int delayed_slow_work_enqueue(struct delayed_slow_work *dwork,
+                             unsigned long delay)
+{
+       struct slow_work *work = &dwork->work;
+       unsigned long flags;
+       int ret;
+
+       if (delay == 0)
+               return slow_work_enqueue(&dwork->work);
+
+       BUG_ON(slow_work_user_count <= 0);
+       BUG_ON(!work);
+       BUG_ON(!work->ops);
+
+       if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
+               return -ECANCELED;
+
+       if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) {
+               spin_lock_irqsave(&slow_work_queue_lock, flags);
+
+               if (test_bit(SLOW_WORK_CANCELLING, &work->flags))
+                       goto cancelled;
+
+               /* the timer holds a reference whilst it is pending */
+               ret = work->ops->get_ref(work);
+               if (ret < 0)
+                       goto cant_get_ref;
+
+               if (test_and_set_bit(SLOW_WORK_DELAYED, &work->flags))
+                       BUG();
+               dwork->timer.expires = jiffies + delay;
+               dwork->timer.data = (unsigned long) work;
+               dwork->timer.function = delayed_slow_work_timer;
+               add_timer(&dwork->timer);
+
+               spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+       }
+
+       return 0;
+
+cancelled:
+       ret = -ECANCELED;
+cant_get_ref:
+       spin_unlock_irqrestore(&slow_work_queue_lock, flags);
+       return ret;
+}
+EXPORT_SYMBOL(delayed_slow_work_enqueue);
+
 /*
  * Schedule a cull of the thread pool at some time in the near future
  */
@@ -368,13 +704,23 @@ static inline bool slow_work_available(int vsmax)
  */
 static int slow_work_thread(void *_data)
 {
-       int vsmax;
+       int vsmax, id;
 
        DEFINE_WAIT(wait);
 
        set_freezable();
        set_user_nice(current, -5);
 
+       /* allocate ourselves an ID */
+       spin_lock_irq(&slow_work_queue_lock);
+       id = find_first_zero_bit(slow_work_ids, SLOW_WORK_THREAD_LIMIT);
+       BUG_ON(id < 0 || id >= SLOW_WORK_THREAD_LIMIT);
+       __set_bit(id, slow_work_ids);
+       slow_work_set_thread_pid(id, current->pid);
+       spin_unlock_irq(&slow_work_queue_lock);
+
+       sprintf(current->comm, "kslowd%03u", id);
+
        for (;;) {
                vsmax = vslow_work_proportion;
                vsmax *= atomic_read(&slow_work_thread_count);
@@ -395,7 +741,7 @@ static int slow_work_thread(void *_data)
                vsmax *= atomic_read(&slow_work_thread_count);
                vsmax /= 100;
 
-               if (slow_work_available(vsmax) && slow_work_execute()) {
+               if (slow_work_available(vsmax) && slow_work_execute(id)) {
                        cond_resched();
                        if (list_empty(&slow_work_queue) &&
                            list_empty(&vslow_work_queue) &&
@@ -412,6 +758,11 @@ static int slow_work_thread(void *_data)
                        break;
        }
 
+       spin_lock_irq(&slow_work_queue_lock);
+       slow_work_set_thread_pid(id, 0);
+       __clear_bit(id, slow_work_ids);
+       spin_unlock_irq(&slow_work_queue_lock);
+
        if (atomic_dec_and_test(&slow_work_thread_count))
                complete_and_exit(&slow_work_last_thread_exited, 0);
        return 0;
@@ -426,21 +777,6 @@ static void slow_work_cull_timeout(unsigned long data)
        wake_up(&slow_work_thread_wq);
 }
 
-/*
- * Get a reference on slow work thread starter
- */
-static int slow_work_new_thread_get_ref(struct slow_work *work)
-{
-       return 0;
-}
-
-/*
- * Drop a reference on slow work thread starter
- */
-static void slow_work_new_thread_put_ref(struct slow_work *work)
-{
-}
-
 /*
  * Start a new slow work thread
  */
@@ -475,9 +811,11 @@ static void slow_work_new_thread_execute(struct slow_work *work)
 }
 
 static const struct slow_work_ops slow_work_new_thread_ops = {
-       .get_ref        = slow_work_new_thread_get_ref,
-       .put_ref        = slow_work_new_thread_put_ref,
+       .owner          = THIS_MODULE,
        .execute        = slow_work_new_thread_execute,
+#ifdef CONFIG_SLOW_WORK_PROC
+       .desc           = slow_work_new_thread_desc,
+#endif
 };
 
 /*
@@ -546,12 +884,13 @@ static int slow_work_max_threads_sysctl(struct ctl_table *table, int write,
 
 /**
  * slow_work_register_user - Register a user of the facility
+ * @module: The module about to make use of the facility
  *
  * Register a user of the facility, starting up the initial threads if there
  * aren't any other users at this point.  This will return 0 if successful, or
  * an error if not.
  */
-int slow_work_register_user(void)
+int slow_work_register_user(struct module *module)
 {
        struct task_struct *p;
        int loop;
@@ -598,14 +937,79 @@ error:
 }
 EXPORT_SYMBOL(slow_work_register_user);
 
+/*
+ * wait for all outstanding items from the calling module to complete
+ * - note that more items may be queued whilst we're waiting
+ */
+static void slow_work_wait_for_items(struct module *module)
+{
+       DECLARE_WAITQUEUE(myself, current);
+       struct slow_work *work;
+       int loop;
+
+       mutex_lock(&slow_work_unreg_sync_lock);
+       add_wait_queue(&slow_work_unreg_wq, &myself);
+
+       for (;;) {
+               spin_lock_irq(&slow_work_queue_lock);
+
+               /* first of all, we wait for the last queued item in each list
+                * to be processed */
+               list_for_each_entry_reverse(work, &vslow_work_queue, link) {
+                       if (work->owner == module) {
+                               set_current_state(TASK_UNINTERRUPTIBLE);
+                               slow_work_unreg_work_item = work;
+                               goto do_wait;
+                       }
+               }
+               list_for_each_entry_reverse(work, &slow_work_queue, link) {
+                       if (work->owner == module) {
+                               set_current_state(TASK_UNINTERRUPTIBLE);
+                               slow_work_unreg_work_item = work;
+                               goto do_wait;
+                       }
+               }
+
+               /* then we wait for the items being processed to finish */
+               slow_work_unreg_module = module;
+               smp_mb();
+               for (loop = 0; loop < SLOW_WORK_THREAD_LIMIT; loop++) {
+                       if (slow_work_thread_processing[loop] == module)
+                               goto do_wait;
+               }
+               spin_unlock_irq(&slow_work_queue_lock);
+               break; /* okay, we're done */
+
+       do_wait:
+               spin_unlock_irq(&slow_work_queue_lock);
+               schedule();
+               slow_work_unreg_work_item = NULL;
+               slow_work_unreg_module = NULL;
+       }
+
+       remove_wait_queue(&slow_work_unreg_wq, &myself);
+       mutex_unlock(&slow_work_unreg_sync_lock);
+}
+
 /**
  * slow_work_unregister_user - Unregister a user of the facility
+ * @module: The module whose items should be cleared
  *
  * Unregister a user of the facility, killing all the threads if this was the
  * last one.
+ *
+ * This waits for all the work items belonging to the nominated module to go
+ * away before proceeding.
  */
-void slow_work_unregister_user(void)
+void slow_work_unregister_user(struct module *module)
 {
+       /* first of all, wait for all outstanding items from the calling module
+        * to complete */
+       if (module)
+               slow_work_wait_for_items(module);
+
+       /* then we can actually go about shutting down the facility if need
+        * be */
        mutex_lock(&slow_work_user_lock);
 
        BUG_ON(slow_work_user_count <= 0);
@@ -638,6 +1042,10 @@ static int __init init_slow_work(void)
 #ifdef CONFIG_SYSCTL
        if (slow_work_max_max_threads < nr_cpus * 2)
                slow_work_max_max_threads = nr_cpus * 2;
+#endif
+#ifdef CONFIG_SLOW_WORK_PROC
+       proc_create("slow_work_rq", S_IFREG | 0400, NULL,
+                   &slow_work_runqueue_fops);
 #endif
        return 0;
 }
diff --git a/kernel/slow-work.h b/kernel/slow-work.h
new file mode 100644 (file)
index 0000000..3c2f007
--- /dev/null
@@ -0,0 +1,72 @@
+/* Slow work private definitions
+ *
+ * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define SLOW_WORK_CULL_TIMEOUT (5 * HZ)        /* cull threads 5s after running out of
+                                        * things to do */
+#define SLOW_WORK_OOM_TIMEOUT (5 * HZ) /* can't start new threads for 5s after
+                                        * OOM */
+
+#define SLOW_WORK_THREAD_LIMIT 255     /* abs maximum number of slow-work threads */
+
+/*
+ * slow-work.c
+ */
+#ifdef CONFIG_SLOW_WORK_PROC
+extern struct slow_work *slow_work_execs[];
+extern pid_t slow_work_pids[];
+extern rwlock_t slow_work_execs_lock;
+#endif
+
+extern struct list_head slow_work_queue;
+extern struct list_head vslow_work_queue;
+extern spinlock_t slow_work_queue_lock;
+
+/*
+ * slow-work-proc.c
+ */
+#ifdef CONFIG_SLOW_WORK_PROC
+extern const struct file_operations slow_work_runqueue_fops;
+
+extern void slow_work_new_thread_desc(struct slow_work *, struct seq_file *);
+#endif
+
+/*
+ * Helper functions
+ */
+static inline void slow_work_set_thread_pid(int id, pid_t pid)
+{
+#ifdef CONFIG_SLOW_WORK_PROC
+       slow_work_pids[id] = pid;
+#endif
+}
+
+static inline void slow_work_mark_time(struct slow_work *work)
+{
+#ifdef CONFIG_SLOW_WORK_PROC
+       work->mark = CURRENT_TIME;
+#endif
+}
+
+static inline void slow_work_begin_exec(int id, struct slow_work *work)
+{
+#ifdef CONFIG_SLOW_WORK_PROC
+       slow_work_execs[id] = work;
+#endif
+}
+
+static inline void slow_work_end_exec(int id, struct slow_work *work)
+{
+#ifdef CONFIG_SLOW_WORK_PROC
+       write_lock(&slow_work_execs_lock);
+       slow_work_execs[id] = NULL;
+       write_unlock(&slow_work_execs_lock);
+#endif
+}
index 23abbd9..92cdd99 100644 (file)
@@ -200,6 +200,9 @@ radix_tree_node_free(struct radix_tree_node *node)
  * ensure that the addition of a single element in the tree cannot fail.  On
  * success, return zero, with preemption disabled.  On error, return -ENOMEM
  * with preemption not disabled.
+ *
+ * To make use of this facility, the radix tree must be initialised without
+ * __GFP_WAIT being passed to INIT_RADIX_TREE().
  */
 int radix_tree_preload(gfp_t gfp_mask)
 {
@@ -543,7 +546,6 @@ out:
 }
 EXPORT_SYMBOL(radix_tree_tag_clear);
 
-#ifndef __KERNEL__     /* Only the test harness uses this at present */
 /**
  * radix_tree_tag_get - get a tag on a radix tree node
  * @root:              radix tree root
@@ -606,7 +608,6 @@ int radix_tree_tag_get(struct radix_tree_root *root,
        }
 }
 EXPORT_SYMBOL(radix_tree_tag_get);
-#endif
 
 /**
  *     radix_tree_next_hole    -    find the next hole (not-present entry)
index 11aee09..67a33a5 100644 (file)
@@ -604,10 +604,14 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
 
        /*
         * Finally, kill the kernel threads. We don't need to be RCU
-        * safe anymore, since the bdi is gone from visibility.
+        * safe anymore, since the bdi is gone from visibility. Force
+        * unfreeze of the thread before calling kthread_stop(), otherwise
+        * it would never exet if it is currently stuck in the refrigerator.
         */
-       list_for_each_entry(wb, &bdi->wb_list, list)
+       list_for_each_entry(wb, &bdi->wb_list, list) {
+               wb->task->flags &= ~PF_FROZEN;
                kthread_stop(wb->task);
+       }
 }
 
 /*
index 6eb8d47..6e79e96 100644 (file)
@@ -363,6 +363,7 @@ struct pktgen_dev {
                                  * device name (not when the inject is
                                  * started as it used to do.)
                                  */
+       char odevname[32];
        struct flow_state *flows;
        unsigned cflows;        /* Concurrent flows (config) */
        unsigned lflow;         /* Flow length  (config) */
@@ -426,7 +427,7 @@ static const char version[] =
 static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i);
 static int pktgen_add_device(struct pktgen_thread *t, const char *ifname);
 static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
-                                         const char *ifname);
+                                         const char *ifname, bool exact);
 static int pktgen_device_event(struct notifier_block *, unsigned long, void *);
 static void pktgen_run_all_threads(void);
 static void pktgen_reset_all_threads(void);
@@ -528,7 +529,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
        seq_printf(seq,
                   "     frags: %d  delay: %llu  clone_skb: %d  ifname: %s\n",
                   pkt_dev->nfrags, (unsigned long long) pkt_dev->delay,
-                  pkt_dev->clone_skb, pkt_dev->odev->name);
+                  pkt_dev->clone_skb, pkt_dev->odevname);
 
        seq_printf(seq, "     flows: %u flowlen: %u\n", pkt_dev->cflows,
                   pkt_dev->lflow);
@@ -1688,13 +1689,13 @@ static int pktgen_thread_show(struct seq_file *seq, void *v)
        if_lock(t);
        list_for_each_entry(pkt_dev, &t->if_list, list)
                if (pkt_dev->running)
-                       seq_printf(seq, "%s ", pkt_dev->odev->name);
+                       seq_printf(seq, "%s ", pkt_dev->odevname);
 
        seq_printf(seq, "\nStopped: ");
 
        list_for_each_entry(pkt_dev, &t->if_list, list)
                if (!pkt_dev->running)
-                       seq_printf(seq, "%s ", pkt_dev->odev->name);
+                       seq_printf(seq, "%s ", pkt_dev->odevname);
 
        if (t->result[0])
                seq_printf(seq, "\nResult: %s\n", t->result);
@@ -1817,9 +1818,10 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove)
 {
        struct pktgen_thread *t;
        struct pktgen_dev *pkt_dev = NULL;
+       bool exact = (remove == FIND);
 
        list_for_each_entry(t, &pktgen_threads, th_list) {
-               pkt_dev = pktgen_find_dev(t, ifname);
+               pkt_dev = pktgen_find_dev(t, ifname, exact);
                if (pkt_dev) {
                        if (remove) {
                                if_lock(t);
@@ -1994,7 +1996,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
                       "queue_map_min (zero-based) (%d) exceeds valid range "
                       "[0 - %d] for (%d) queues on %s, resetting\n",
                       pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq,
-                      pkt_dev->odev->name);
+                      pkt_dev->odevname);
                pkt_dev->queue_map_min = ntxq - 1;
        }
        if (pkt_dev->queue_map_max >= ntxq) {
@@ -2002,7 +2004,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
                       "queue_map_max (zero-based) (%d) exceeds valid range "
                       "[0 - %d] for (%d) queues on %s, resetting\n",
                       pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq,
-                      pkt_dev->odev->name);
+                      pkt_dev->odevname);
                pkt_dev->queue_map_max = ntxq - 1;
        }
 
@@ -3262,7 +3264,7 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev)
 
        if (!pkt_dev->running) {
                printk(KERN_WARNING "pktgen: interface: %s is already "
-                      "stopped\n", pkt_dev->odev->name);
+                      "stopped\n", pkt_dev->odevname);
                return -EINVAL;
        }
 
@@ -3464,7 +3466,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
        default: /* Drivers are not supposed to return other values! */
                if (net_ratelimit())
                        pr_info("pktgen: %s xmit error: %d\n",
-                               odev->name, ret);
+                               pkt_dev->odevname, ret);
                pkt_dev->errors++;
                /* fallthru */
        case NETDEV_TX_LOCKED:
@@ -3566,13 +3568,18 @@ static int pktgen_thread_worker(void *arg)
 }
 
 static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
-                                         const char *ifname)
+                                         const char *ifname, bool exact)
 {
        struct pktgen_dev *p, *pkt_dev = NULL;
-       if_lock(t);
+       size_t len = strlen(ifname);
 
+       if_lock(t);
        list_for_each_entry(p, &t->if_list, list)
-               if (strncmp(p->odev->name, ifname, IFNAMSIZ) == 0) {
+               if (strncmp(p->odevname, ifname, len) == 0) {
+                       if (p->odevname[len]) {
+                               if (exact || p->odevname[len] != '@')
+                                       continue;
+                       }
                        pkt_dev = p;
                        break;
                }
@@ -3628,6 +3635,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
        if (!pkt_dev)
                return -ENOMEM;
 
+       strcpy(pkt_dev->odevname, ifname);
        pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state));
        if (pkt_dev->flows == NULL) {
                kfree(pkt_dev);
index 575f9bd..d3fe10b 100644 (file)
@@ -563,7 +563,7 @@ out_oversize:
                printk(KERN_INFO "Oversized IP packet from %pI4.\n",
                        &qp->saddr);
 out_fail:
-       IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMFAILS);
+       IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
        return err;
 }
 
index bc064d7..ce8e0e7 100644 (file)
@@ -85,10 +85,6 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
 
-       /* stop HW Rx aggregation. ampdu_action existence
-        * already verified in session init so we add the BUG_ON */
-       BUG_ON(!local->ops->ampdu_action);
-
        rcu_read_lock();
 
        sta = sta_info_get(local, ra);
index b09948c..89e238b 100644 (file)
@@ -123,13 +123,18 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
        ieee80211_tx_skb(sdata, skb, 0);
 }
 
-static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
-                                          enum ieee80211_back_parties initiator)
+int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
+                                   enum ieee80211_back_parties initiator)
 {
        struct ieee80211_local *local = sta->local;
        int ret;
        u8 *state;
 
+#ifdef CONFIG_MAC80211_HT_DEBUG
+       printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
+              sta->sta.addr, tid);
+#endif /* CONFIG_MAC80211_HT_DEBUG */
+
        state = &sta->ampdu_mlme.tid_state_tx[tid];
 
        if (*state == HT_AGG_STATE_OPERATIONAL)
@@ -143,7 +148,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
 
        /* HW shall not deny going back to legacy */
        if (WARN_ON(ret)) {
-               *state = HT_AGG_STATE_OPERATIONAL;
                /*
                 * We may have pending packets get stuck in this case...
                 * Not bothering with a workaround for now.
@@ -173,12 +177,14 @@ static void sta_addba_resp_timer_expired(unsigned long data)
 
        /* check if the TID waits for addBA response */
        spin_lock_bh(&sta->lock);
-       if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
+       if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) !=
+                                               HT_ADDBA_REQUESTED_MSK) {
                spin_unlock_bh(&sta->lock);
                *state = HT_AGG_STATE_IDLE;
 #ifdef CONFIG_MAC80211_HT_DEBUG
                printk(KERN_DEBUG "timer expired on tid %d but we are not "
-                               "expecting addBA response there", tid);
+                               "(or no longer) expecting addBA response there",
+                       tid);
 #endif
                return;
        }
@@ -523,11 +529,6 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
                goto unlock;
        }
 
-#ifdef CONFIG_MAC80211_HT_DEBUG
-       printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
-              sta->sta.addr, tid);
-#endif /* CONFIG_MAC80211_HT_DEBUG */
-
        ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator);
 
  unlock:
@@ -543,7 +544,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
        struct sta_info *sta;
        int ret = 0;
 
-       if (WARN_ON(!local->ops->ampdu_action))
+       if (!local->ops->ampdu_action)
                return -EINVAL;
 
        if (tid >= STA_TID_NUM)
@@ -666,21 +667,21 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
 
        state = &sta->ampdu_mlme.tid_state_tx[tid];
 
-       del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
-
        spin_lock_bh(&sta->lock);
 
        if (!(*state & HT_ADDBA_REQUESTED_MSK))
-               goto timer_still_needed;
+               goto out;
 
        if (mgmt->u.action.u.addba_resp.dialog_token !=
                sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
                printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
-               goto timer_still_needed;
+               goto out;
        }
 
+       del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
+
 #ifdef CONFIG_MAC80211_HT_DEBUG
        printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
@@ -699,10 +700,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
                ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
        }
 
-       goto out;
-
- timer_still_needed:
-       add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
  out:
        spin_unlock_bh(&sta->lock);
 }
index 48ef1a2..cdc58e6 100644 (file)
@@ -141,7 +141,6 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
                             struct sta_info *sta,
                             struct ieee80211_mgmt *mgmt, size_t len)
 {
-       struct ieee80211_local *local = sdata->local;
        u16 tid, params;
        u16 initiator;
 
@@ -161,10 +160,9 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
                                                 WLAN_BACK_INITIATOR, 0);
        else { /* WLAN_BACK_RECIPIENT */
                spin_lock_bh(&sta->lock);
-               sta->ampdu_mlme.tid_state_tx[tid] =
-                               HT_AGG_STATE_OPERATIONAL;
+               if (sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK)
+                       ___ieee80211_stop_tx_ba_session(sta, tid,
+                                                       WLAN_BACK_RECIPIENT);
                spin_unlock_bh(&sta->lock);
-               ieee80211_stop_tx_ba_session(&local->hw, sta->sta.addr, tid,
-                                            WLAN_BACK_RECIPIENT);
        }
 }
index 588005c..10d316e 100644 (file)
@@ -661,6 +661,14 @@ struct ieee80211_local {
         */
        bool suspended;
 
+       /*
+        * Resuming is true while suspended, but when we're reprogramming the
+        * hardware -- at that time it's allowed to use ieee80211_queue_work()
+        * again even though some other parts of the stack are still suspended
+        * and we still drop received frames to avoid waking the stack.
+        */
+       bool resuming;
+
        /*
         * quiescing is true during the suspend process _only_ to
         * ease timer cancelling etc.
@@ -1083,6 +1091,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
 
 int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
                                   enum ieee80211_back_parties initiator);
+int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
+                                   enum ieee80211_back_parties initiator);
 
 /* Spectrum management */
 void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
index aeb65b3..e6c08da 100644 (file)
@@ -520,9 +520,9 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
  */
 static bool ieee80211_can_queue_work(struct ieee80211_local *local)
 {
-        if (WARN(local->suspended, "queueing ieee80211 work while "
-                "going to suspend\n"))
-                return false;
+       if (WARN(local->suspended && !local->resuming,
+                "queueing ieee80211 work while going to suspend\n"))
+               return false;
 
        return true;
 }
@@ -1025,13 +1025,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        struct sta_info *sta;
        unsigned long flags;
        int res;
-       bool from_suspend = local->suspended;
 
-       /*
-        * We're going to start the hardware, at that point
-        * we are no longer suspended and can RX frames.
-        */
-       local->suspended = false;
+       if (local->suspended)
+               local->resuming = true;
 
        /* restart hardware */
        if (local->open_count) {
@@ -1129,11 +1125,14 @@ int ieee80211_reconfig(struct ieee80211_local *local)
         * If this is for hw restart things are still running.
         * We may want to change that later, however.
         */
-       if (!from_suspend)
+       if (!local->suspended)
                return 0;
 
 #ifdef CONFIG_PM
+       /* first set suspended false, then resuming */
        local->suspended = false;
+       mb();
+       local->resuming = false;
 
        list_for_each_entry(sdata, &local->interfaces, list) {
                switch(sdata->vif.type) {
index c93494f..d65d348 100644 (file)
@@ -128,9 +128,8 @@ EXPORT_SYMBOL(nf_log_packet);
 
 #ifdef CONFIG_PROC_FS
 static void *seq_start(struct seq_file *seq, loff_t *pos)
-       __acquires(RCU)
 {
-       rcu_read_lock();
+       mutex_lock(&nf_log_mutex);
 
        if (*pos >= ARRAY_SIZE(nf_loggers))
                return NULL;
@@ -149,9 +148,8 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
 }
 
 static void seq_stop(struct seq_file *s, void *v)
-       __releases(RCU)
 {
-       rcu_read_unlock();
+       mutex_unlock(&nf_log_mutex);
 }
 
 static int seq_show(struct seq_file *s, void *v)
@@ -161,7 +159,7 @@ static int seq_show(struct seq_file *s, void *v)
        struct nf_logger *t;
        int ret;
 
-       logger = rcu_dereference(nf_loggers[*pos]);
+       logger = nf_loggers[*pos];
 
        if (!logger)
                ret = seq_printf(s, "%2lld NONE (", *pos);
@@ -171,22 +169,16 @@ static int seq_show(struct seq_file *s, void *v)
        if (ret < 0)
                return ret;
 
-       mutex_lock(&nf_log_mutex);
        list_for_each_entry(t, &nf_loggers_l[*pos], list[*pos]) {
                ret = seq_printf(s, "%s", t->name);
-               if (ret < 0) {
-                       mutex_unlock(&nf_log_mutex);
+               if (ret < 0)
                        return ret;
-               }
                if (&t->list[*pos] != nf_loggers_l[*pos].prev) {
                        ret = seq_printf(s, ",");
-                       if (ret < 0) {
-                               mutex_unlock(&nf_log_mutex);
+                       if (ret < 0)
                                return ret;
-                       }
                }
        }
-       mutex_unlock(&nf_log_mutex);
 
        return seq_printf(s, ")\n");
 }
index 2e8089e..2773be6 100644 (file)
@@ -112,7 +112,7 @@ static bool limit_mt_check(const struct xt_mtchk_param *par)
 
        priv = kmalloc(sizeof(*priv), GFP_KERNEL);
        if (priv == NULL)
-               return -ENOMEM;
+               return false;
 
        /* For SMP, we only want to use one set of state. */
        r->master = priv;
index 63e1905..4d1a41b 100644 (file)
@@ -118,7 +118,7 @@ static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb,
 {
        struct xt_osf_user_finger *f;
        struct xt_osf_finger *sf;
-       int err = ENOENT;
+       int err = -ENOENT;
 
        if (!osf_attrs[OSF_ATTR_FINGER])
                return -EINVAL;
index ba2efb9..a001f7c 100644 (file)
@@ -1189,6 +1189,7 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd,
 #endif
 
 static const struct file_operations rfkill_fops = {
+       .owner          = THIS_MODULE,
        .open           = rfkill_fop_open,
        .read           = rfkill_fop_read,
        .write          = rfkill_fop_write,
index c9f20e2..23e5e97 100644 (file)
@@ -423,16 +423,6 @@ void sctp_retransmit_mark(struct sctp_outq *q,
                if ((reason == SCTP_RTXR_FAST_RTX  &&
                            (chunk->fast_retransmit == SCTP_NEED_FRTX)) ||
                    (reason != SCTP_RTXR_FAST_RTX  && !chunk->tsn_gap_acked)) {
-                       /* If this chunk was sent less then 1 rto ago, do not
-                        * retransmit this chunk, but give the peer time
-                        * to acknowlege it.  Do this only when
-                        * retransmitting due to T3 timeout.
-                        */
-                       if (reason == SCTP_RTXR_T3_RTX &&
-                           time_before(jiffies, chunk->sent_at +
-                                                transport->last_rto))
-                               continue;
-
                        /* RFC 2960 6.2.1 Processing a Received SACK
                         *
                         * C) Any time a DATA chunk is marked for
index 8674d49..efa516b 100644 (file)
@@ -480,7 +480,6 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
         * that indicates that we have an outstanding HB.
         */
        if (!is_hb || transport->hb_sent) {
-               transport->last_rto = transport->rto;
                transport->rto = min((transport->rto * 2), transport->asoc->rto_max);
        }
 }
index 3b141bb..37a1184 100644 (file)
@@ -74,7 +74,7 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
         * given destination transport address, set RTO to the protocol
         * parameter 'RTO.Initial'.
         */
-       peer->last_rto = peer->rto = msecs_to_jiffies(sctp_rto_initial);
+       peer->rto = msecs_to_jiffies(sctp_rto_initial);
        peer->rtt = 0;
        peer->rttvar = 0;
        peer->srtt = 0;
@@ -386,7 +386,6 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
                tp->rto = tp->asoc->rto_max;
 
        tp->rtt = rtt;
-       tp->last_rto = tp->rto;
 
        /* Reset rto_pending so that a new RTT measurement is started when a
         * new data chunk is sent.
@@ -602,7 +601,7 @@ void sctp_transport_reset(struct sctp_transport *t)
         */
        t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380));
        t->ssthresh = asoc->peer.i.a_rwnd;
-       t->last_rto = t->rto = asoc->rto_initial;
+       t->rto = asoc->rto_initial;
        t->rtt = 0;
        t->srtt = 0;
        t->rttvar = 0;
index 6d69c7c..80599e3 100644 (file)
@@ -30,7 +30,7 @@ silentoldconfig: $(obj)/conf
        $< -s $(Kconfig)
 
 localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
-       $(Q)perl $< $(Kconfig) > .tmp.config
+       $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config
        $(Q)if [ -f .config ]; then                             \
                        cmp -s .tmp.config .config ||           \
                        (mv -f .config .config.old.1;           \
@@ -44,7 +44,7 @@ localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
        $(Q)rm -f .tmp.config
 
 localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
-       $(Q)perl $< $(Kconfig) > .tmp.config
+       $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config
        $(Q)sed -i s/=m/=y/ .tmp.config
        $(Q)if [ -f .config ]; then                             \
                        cmp -s .tmp.config .config ||           \
index 95984db..0d80082 100644 (file)
@@ -43,7 +43,6 @@
 #    make oldconfig
 #
 my $config = ".config";
-my $linuxpath = ".";
 
 my $uname = `uname -r`;
 chomp $uname;
@@ -111,7 +110,11 @@ sub find_config {
 
 find_config;
 
-my @makefiles = `find $linuxpath -name Makefile`;
+# Get the build source and top level Kconfig file (passed in)
+my $ksource = $ARGV[0];
+my $kconfig = $ARGV[1];
+
+my @makefiles = `find $ksource -name Makefile`;
 my %depends;
 my %selects;
 my %prompts;
@@ -119,9 +122,6 @@ my %objects;
 my $var;
 my $cont = 0;
 
-# Get the top level Kconfig file (passed in)
-my $kconfig = $ARGV[0];
-
 # prevent recursion
 my %read_kconfigs;
 
@@ -132,7 +132,7 @@ sub read_kconfig {
     my $config;
     my @kconfigs;
 
-    open(KIN, $kconfig) || die "Can't open $kconfig";
+    open(KIN, "$ksource/$kconfig") || die "Can't open $kconfig";
     while (<KIN>) {
        chomp;
 
index 1f0f821..6c160a0 100644 (file)
@@ -504,6 +504,10 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
        int err;
 
        aaci_pcm_hw_free(substream);
+       if (aacirun->pcm_open) {
+               snd_ac97_pcm_close(aacirun->pcm);
+               aacirun->pcm_open = 0;
+       }
 
        err = devdma_hw_alloc(NULL, substream,
                              params_buffer_bytes(params));
@@ -517,7 +521,7 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
        else
                err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
                                        params_channels(params),
-                                       aacirun->pcm->r[1].slots);
+                                       aacirun->pcm->r[0].slots);
 
        if (err)
                goto out;
index 6b24d8b..90a0264 100644 (file)
@@ -625,11 +625,10 @@ static int tlv320aic23_resume(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
        struct snd_soc_codec *codec = socdev->card->codec;
-       int i;
        u16 reg;
 
        /* Sync reg_cache with the hardware */
-       for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) {
+       for (reg = 0; reg < TLV320AIC23_RESET; reg++) {
                u16 val = tlv320aic23_read_reg_cache(codec, reg);
                tlv320aic23_write(codec, reg, val);
        }
index d89f6dc..66d4c16 100644 (file)
@@ -973,9 +973,19 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
                        if (!w->power_check)
                                continue;
 
-                       power = w->power_check(w);
-                       if (power)
-                               sys_power = 1;
+                       /* If we're suspending then pull down all the 
+                        * power. */
+                       switch (event) {
+                       case SND_SOC_DAPM_STREAM_SUSPEND:
+                               power = 0;
+                               break;
+
+                       default:
+                               power = w->power_check(w);
+                               if (power)
+                                       sys_power = 1;
+                               break;
+                       }
 
                        if (w->power == power)
                                continue;
@@ -999,8 +1009,12 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
                case SND_SOC_DAPM_STREAM_RESUME:
                        sys_power = 1;
                        break;
+               case SND_SOC_DAPM_STREAM_SUSPEND:
+                       sys_power = 0;
+                       break;
                case SND_SOC_DAPM_STREAM_NOP:
                        sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY;
+                       break;
                default:
                        break;
                }