]> git.karo-electronics.de Git - linux-beck.git/commitdiff
Merge branch 'irq-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 18 Aug 2009 20:57:38 +0000 (13:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 18 Aug 2009 20:57:38 +0000 (13:57 -0700)
* 'irq-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  genirq: Wake up irq thread after action has been installed

215 files changed:
Documentation/video4linux/CARDLIST.em28xx
Documentation/video4linux/CARDLIST.saa7134
MAINTAINERS
Makefile
arch/arm/configs/rx51_defconfig
arch/arm/include/asm/setup.h
arch/arm/mach-ixp4xx/include/mach/io.h
arch/arm/mach-mx3/mx31moboard-devboard.c
arch/arm/mach-mx3/mx31moboard-marxbot.c
arch/arm/mach-mx3/mx31moboard.c
arch/arm/mach-mx3/pcm037_eet.c
arch/arm/mach-omap2/board-2430sdp.c
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-4430sdp.c
arch/arm/mach-omap2/board-apollon.c
arch/arm/mach-omap2/board-generic.c
arch/arm/mach-omap2/board-h4.c
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3evm.c
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-overo.c
arch/arm/mach-omap2/board-rx51-peripherals.c
arch/arm/mach-omap2/board-rx51.c
arch/arm/mach-omap2/board-zoom2.c
arch/arm/mach-omap2/clock.c
arch/arm/mach-omap2/clock.h
arch/arm/mach-omap2/clock24xx.c
arch/arm/mach-omap2/clock24xx.h
arch/arm/mach-omap2/clock34xx.c
arch/arm/mach-omap2/clock34xx.h
arch/arm/mach-omap2/cm.h
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/mmc-twl4030.c
arch/arm/mach-omap2/mux.c
arch/arm/mach-omap2/pm.h
arch/arm/mach-omap2/pm24xx.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/prcm.c
arch/arm/mach-omap2/sdrc.c
arch/arm/mach-omap2/serial.c
arch/arm/mach-omap2/sram34xx.S
arch/arm/mach-u300/core.c
arch/arm/mm/init.c
arch/arm/mm/mmu.c
arch/arm/plat-omap/cpu-omap.c
arch/arm/plat-omap/dma.c
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/include/mach/clock.h
arch/arm/plat-omap/include/mach/cpu.h
arch/arm/plat-omap/include/mach/io.h
arch/arm/plat-omap/include/mach/mux.h
arch/arm/plat-omap/include/mach/prcm.h
arch/arm/plat-omap/include/mach/sdrc.h
arch/arm/plat-omap/include/mach/serial.h
arch/arm/plat-omap/include/mach/sram.h
arch/arm/plat-omap/sram.c
arch/arm/plat-s3c24xx/clock-dclk.c
arch/mips/include/asm/page.h
arch/sh/boards/mach-se/7724/setup.c
arch/sh/kernel/cpu/shmobile/sleep.S
drivers/clocksource/sh_cmt.c
drivers/md/dm-log-userspace-transfer.c
drivers/md/md.c
drivers/media/common/tuners/qt1010.c
drivers/media/common/tuners/tuner-xc2028.c
drivers/media/common/tuners/tuner-xc2028.h
drivers/media/dvb/dvb-usb/af9015.c
drivers/media/dvb/frontends/cx22700.c
drivers/media/dvb/frontends/cx22702.c
drivers/media/dvb/frontends/cx24110.c
drivers/media/dvb/frontends/dvb_dummy_fe.c
drivers/media/dvb/frontends/l64781.c
drivers/media/dvb/frontends/lgs8gl5.c
drivers/media/dvb/frontends/mt312.c
drivers/media/dvb/frontends/nxt6000.c
drivers/media/dvb/frontends/or51132.c
drivers/media/dvb/frontends/or51211.c
drivers/media/dvb/frontends/s5h1409.c
drivers/media/dvb/frontends/s5h1411.c
drivers/media/dvb/frontends/si21xx.c
drivers/media/dvb/frontends/sp8870.c
drivers/media/dvb/frontends/sp887x.c
drivers/media/dvb/frontends/stv0288.c
drivers/media/dvb/frontends/stv0297.c
drivers/media/dvb/frontends/stv0299.c
drivers/media/dvb/frontends/tda10021.c
drivers/media/dvb/frontends/tda10048.c
drivers/media/dvb/frontends/tda1004x.c
drivers/media/dvb/frontends/tda10086.c
drivers/media/dvb/frontends/tda8083.c
drivers/media/dvb/frontends/ves1820.c
drivers/media/dvb/frontends/ves1x93.c
drivers/media/dvb/frontends/zl10353.c
drivers/media/dvb/siano/Kconfig
drivers/media/dvb/siano/sms-cards.c
drivers/media/dvb/siano/smscoreapi.c
drivers/media/video/Kconfig
drivers/media/video/bw-qcam.c
drivers/media/video/cx18/cx18-controls.c
drivers/media/video/cx23885/cx23885-417.c
drivers/media/video/cx88/cx88-cards.c
drivers/media/video/cx88/cx88-dvb.c
drivers/media/video/cx88/cx88-mpeg.c
drivers/media/video/em28xx/em28xx-cards.c
drivers/media/video/em28xx/em28xx-core.c
drivers/media/video/em28xx/em28xx-dvb.c
drivers/media/video/em28xx/em28xx-reg.h
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/em28xx/em28xx.h
drivers/media/video/hdpvr/hdpvr-video.c
drivers/media/video/ivtv/ivtv-controls.c
drivers/media/video/mt9v011.c
drivers/media/video/mt9v011.h
drivers/media/video/mx1_camera.c
drivers/media/video/mx3_camera.c
drivers/media/video/pxa_camera.c
drivers/media/video/saa7134/saa7134-cards.c
drivers/media/video/saa7134/saa7134-dvb.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/stk-webcam.c
drivers/media/video/uvc/uvc_driver.c
drivers/media/video/uvc/uvc_status.c
drivers/media/video/v4l2-ioctl.c
drivers/net/3c59x.c
drivers/net/8139cp.c
drivers/net/atl1c/atl1c_ethtool.c
drivers/net/atlx/atl1.c
drivers/net/b44.c
drivers/net/bnx2.c
drivers/net/bnx2.h
drivers/net/can/dev.c
drivers/net/cnic.c
drivers/net/cnic.h
drivers/net/cnic_if.h
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/netdev.c
drivers/net/fec.c
drivers/net/gianfar.c
drivers/net/irda/w83977af_ir.c
drivers/net/ixgbe/ixgbe.h
drivers/net/ixgbe/ixgbe_ethtool.c
drivers/net/ixgbe/ixgbe_fcoe.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/mlx4/en_rx.c
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/pcnet32.c
drivers/net/tulip/tulip_core.c
drivers/net/tun.c
drivers/net/ucc_geth.c
drivers/net/usb/pegasus.h
drivers/net/via-rhine.c
drivers/net/via-velocity.c
drivers/net/wireless/ath/ar9170/main.c
drivers/net/wireless/ath/ar9170/usb.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/libertas/assoc.c
drivers/net/wireless/libertas/hostcmd.h
drivers/net/wireless/mwl8k.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/zorro8390.c
drivers/serial/Kconfig
drivers/video/sh_mobile_lcdcfb.c
fs/gfs2/sys.c
fs/notify/inotify/inotify_fsnotify.c
fs/notify/inotify/inotify_user.c
fs/notify/notification.c
fs/select.c
fs/xfs/linux-2.6/xfs_sync.c
fs/xfs/linux-2.6/xfs_sync.h
fs/xfs/xfs_iget.c
include/linux/gen_stats.h
include/linux/mm.h
include/linux/security.h
include/net/act_api.h
include/net/gen_stats.h
include/net/netfilter/xt_rateest.h
include/net/sch_generic.h
kernel/sysctl.c
mm/Kconfig
mm/mmap.c
mm/nommu.c
net/appletalk/ddp.c
net/can/raw.c
net/core/gen_estimator.c
net/core/gen_stats.c
net/dccp/proto.c
net/econet/af_econet.c
net/ieee802154/af_ieee802154.c
net/ieee802154/dgram.c
net/ieee802154/raw.c
net/ipv4/ip_gre.c
net/irda/af_irda.c
net/mac80211/agg-tx.c
net/netfilter/xt_RATEEST.c
net/netrom/af_netrom.c
net/netrom/nr_route.c
net/phonet/pn_dev.c
net/rose/af_rose.c
net/sched/sch_atm.c
net/sched/sch_cbq.c
net/sched/sch_drr.c
net/sched/sch_hfsc.c
net/sched/sch_htb.c
net/sctp/protocol.c
net/xfrm/xfrm_hash.h
security/Kconfig
security/Makefile
security/capability.c
security/commoncap.c
security/min_addr.c [new file with mode: 0644]
security/selinux/hooks.c

index 68c236c018462e2e3d687e4a078c44815786db0d..e352d754875cae415b0c27d766336c00942cd241 100644 (file)
@@ -1,5 +1,5 @@
   0 -> Unknown EM2800 video grabber             (em2800)        [eb1a:2800]
-  1 -> Unknown EM2750/28xx video grabber        (em2820/em2840) [eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
+  1 -> Unknown EM2750/28xx video grabber        (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883]
   2 -> Terratec Cinergy 250 USB                 (em2820/em2840) [0ccd:0036]
   3 -> Pinnacle PCTV USB 2                      (em2820/em2840) [2304:0208]
   4 -> Hauppauge WinTV USB 2                    (em2820/em2840) [2040:4200,2040:4201]
index 15562427e8a9cb51b7f7611bb38a0bc7975bfa65..c913e5614195a9a359411ee163f8c2e081d24a2a 100644 (file)
 152 -> Asus Tiger Rev:1.00                      [1043:4857]
 153 -> Kworld Plus TV Analog Lite PCI           [17de:7128]
 154 -> Avermedia AVerTV GO 007 FM Plus          [1461:f31d]
-155 -> Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid  [0070:6706,0070:6708]
-156 -> Hauppauge WinTV-HVR1110r3 DVB-T/Hybrid   [0070:6707,0070:6709,0070:670a]
+155 -> Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid  [0070:6706,0070:6708]
+156 -> Hauppauge WinTV-HVR1120 DVB-T/Hybrid     [0070:6707,0070:6709,0070:670a]
 157 -> Avermedia AVerTV Studio 507UA            [1461:a11b]
 158 -> AVerMedia Cardbus TV/Radio (E501R)       [1461:b7e9]
 159 -> Beholder BeholdTV 505 RDS                [0000:505B]
index b1114cfac6bf22b9d7fc015af9cad2e628b0bbcb..557d4dcc2c2c336fc8deaf559efacc6210180521 100644 (file)
@@ -904,7 +904,7 @@ F:  drivers/input/misc/ati_remote2.c
 
 ATLX ETHERNET DRIVERS
 M:     Jay Cliburn <jcliburn@gmail.com>
-M:     Chris Snook <csnook@redhat.com>
+M:     Chris Snook <chris.snook@gmail.com>
 M:     Jie Yang <jie.yang@atheros.com>
 L:     atl1-devel@lists.sourceforge.net
 W:     http://sourceforge.net/projects/atl1
@@ -2238,6 +2238,14 @@ T:       git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
 S:     Maintained
 F:     drivers/media/video/gspca/pac207.c
 
+GSPCA SN9C20X SUBDRIVER
+P:     Brian Johnson
+M:     brijohn@gmail.com
+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/sn9c20x.c
+
 GSPCA T613 SUBDRIVER
 M:     Leandro Costantino <lcostantino@gmail.com>
 L:     linux-media@vger.kernel.org
@@ -3555,6 +3563,9 @@ T:        git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
 S:     Maintained
 F:     net/
 F:     include/net/
+F:     include/linux/in.h
+F:     include/linux/net.h
+F:     include/linux/netdevice.h
 
 NETWORKING [IPv4/IPv6]
 M:     "David S. Miller" <davem@davemloft.net>
@@ -3590,6 +3601,8 @@ W:        http://www.linuxfoundation.org/en/Net
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.git
 S:     Odd Fixes
 F:     drivers/net/
+F:     include/linux/if_*
+F:     include/linux/*device.h
 
 NETXEN (1/10) GbE SUPPORT
 M:     Dhananjay Phadke <dhananjay@netxen.com>
index 0d46615bffe5c95704a83cfb7cdf82d2fa792c48..abcfa85f8f825392890bc26da007e5af3fd94d6c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 31
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc6
 NAME = Man-Eating Seals of Antiquity
 
 # *DOCUMENTATION*
index eb2cb31825c0b4a797258f652ef75d54f96233cb..f238df66efd4d3d2e80f1188b91171845e7ee502 100644 (file)
@@ -282,7 +282,7 @@ CONFIG_ALIGNMENT_TRAP=y
 #
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="init=/sbin/preinit ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs rootflags=bulk_read,no_chk_data_crc rw console=ttyMTD,log console=tty0"
+CONFIG_CMDLINE="init=/sbin/preinit ubi.mtd=rootfs root=ubi0:rootfs rootfstype=ubifs rootflags=bulk_read,no_chk_data_crc rw console=ttyMTD,log console=tty0 console=ttyS2,115200n8"
 # CONFIG_XIP_KERNEL is not set
 # CONFIG_KEXEC is not set
 
@@ -1354,7 +1354,7 @@ CONFIG_USB_OTG_UTILS=y
 # CONFIG_USB_GPIO_VBUS is not set
 # CONFIG_ISP1301_OMAP is not set
 CONFIG_TWL4030_USB=y
-CONFIG_MMC=m
+CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
 
@@ -1449,7 +1449,8 @@ CONFIG_RTC_DRV_TWL4030=m
 # on-CPU RTC drivers
 #
 # CONFIG_DMADEVICES is not set
-# CONFIG_REGULATOR is not set
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_TWL4030=y
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
index ee1304f22f944c3104d28d44c1b0eeb05957eb22..5ccce0a9b03cdfd6a054b4c43b429d3bbce922d9 100644 (file)
@@ -201,7 +201,8 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn }
 struct membank {
        unsigned long start;
        unsigned long size;
-       int           node;
+       unsigned short node;
+       unsigned short highmem;
 };
 
 struct meminfo {
index ce63048d45eb0ab7ad52556917ce5b28fe1c610c..8a947d42a6f1b83bf7ed4b4b74e96d3f13b9e8be 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <mach/hardware.h>
 
-#define IO_SPACE_LIMIT 0xffff0000
+#define IO_SPACE_LIMIT 0x0000ffff
 
 extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data);
 extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data);
index 4704405165a16e75b90f40846453566a8a8a959a..b48581e7dedd83b83f968167610b633ca97781df 100644 (file)
@@ -63,7 +63,7 @@ static struct imxuart_platform_data uart_pdata = {
 
 static int devboard_sdhc2_get_ro(struct device *dev)
 {
-       return gpio_get_value(SDHC2_WP);
+       return !gpio_get_value(SDHC2_WP);
 }
 
 static int devboard_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
index 641c3d6153aee66566e552e1400375d6390d3dfb..901fb0166c0e893e5f3f37732de7ae56c5fc4a40 100644 (file)
@@ -67,7 +67,7 @@ static unsigned int marxbot_pins[] = {
 
 static int marxbot_sdhc2_get_ro(struct device *dev)
 {
-       return gpio_get_value(SDHC2_WP);
+       return !gpio_get_value(SDHC2_WP);
 }
 
 static int marxbot_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
index a17f2e4116097c2a792f8f38454fb901a96efbd7..2a2da4739ecfa7039f3e8f78396c99d9f806b68f 100644 (file)
@@ -94,7 +94,7 @@ static struct imxi2c_platform_data moboard_i2c1_pdata = {
 
 static int moboard_sdhc1_get_ro(struct device *dev)
 {
-       return gpio_get_value(SDHC1_WP);
+       return !gpio_get_value(SDHC1_WP);
 }
 
 static int moboard_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
index fe52fb1bb8b73636c0930535395e36e40c3df15b..8d386000fc40d1f9c161ae1e121ec5a6466cba1e 100644 (file)
 #include "devices.h"
 
 static unsigned int pcm037_eet_pins[] = {
-       /* SPI #1 */
-       MX31_PIN_CSPI1_MISO__MISO,
-       MX31_PIN_CSPI1_MOSI__MOSI,
-       MX31_PIN_CSPI1_SCLK__SCLK,
-       MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
-       MX31_PIN_CSPI1_SS0__SS0,
-       MX31_PIN_CSPI1_SS1__SS1,
-       MX31_PIN_CSPI1_SS2__SS2,
-
        /* Reserve and hardwire GPIO 57 high - S6E63D6 chipselect */
        IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_GPIO),
        /* GPIO keys */
index 9c3fdcdf76c324306702d07974e912fb59246d09..8ec2a132904d3dd3f426d58ae991b691b92cb6a8 100644 (file)
@@ -141,7 +141,7 @@ static inline void board_smc91x_init(void)
 
 static void __init omap_2430sdp_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(NULL, NULL);
        omap_init_irq();
        omap_gpio_init();
 }
index 496a90e4ea7ac16d2983759a1b62dd007160c010..ac262cd74503d756f004503f1e92f570ea87ba5d 100644 (file)
@@ -169,7 +169,7 @@ static struct platform_device *sdp3430_devices[] __initdata = {
 
 static void __init omap_3430sdp_init_irq(void)
 {
-       omap2_init_common_hw(hyb18m512160af6_sdrc_params);
+       omap2_init_common_hw(hyb18m512160af6_sdrc_params, NULL);
        omap_init_irq();
        omap_gpio_init();
 }
index 57e477bd89c6d28cc095f06ce0bc3974c9b2da28..b0c7402248f7d37958f9e940988e868a5e9ee013 100644 (file)
@@ -59,7 +59,7 @@ static void __init gic_init_irq(void)
 
 static void __init omap_4430sdp_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(NULL, NULL);
 #ifdef CONFIG_OMAP_32K_TIMER
        omap2_gp_clockevent_set_gptimer(1);
 #endif
index 06dfba888b0ca408b9691e1623774f366e1569d3..dcfc20d03894c65cba921266c753f29228add833 100644 (file)
@@ -250,7 +250,7 @@ out:
 
 static void __init omap_apollon_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(NULL, NULL);
        omap_init_irq();
        omap_gpio_init();
        apollon_init_smc91x();
index 3492162a65c383907bb093702b0c9921ff1b8ac2..fd00aa03690cc8b690de63bd74e6dff6621bdb6d 100644 (file)
@@ -33,7 +33,7 @@
 
 static void __init omap_generic_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(NULL, NULL);
        omap_init_irq();
 }
 
index e7d017cdc43851b63c1c8a7c88feb0fe05039236..7b1d61d5bb2c43ec3fda06cfa50519242a8d7802 100644 (file)
@@ -270,7 +270,7 @@ static void __init h4_init_flash(void)
 
 static void __init omap_h4_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(NULL, NULL);
        omap_init_irq();
        omap_gpio_init();
        h4_init_flash();
index d8bc0a7dcb8df64463b3653de1f9a1626bc37619..ea383f88cb1b5b93a9b1f32801cb5fb8275caedb 100644 (file)
@@ -270,7 +270,7 @@ static inline void __init ldp_init_smsc911x(void)
 
 static void __init omap_ldp_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(NULL, NULL);
        omap_init_irq();
        omap_gpio_init();
        ldp_init_smsc911x();
index 991ac9c38032832dbed51e533f10b2ef7099ce81..e00ba128cece07f17c5958bd63cc3cfad4eab81e 100644 (file)
@@ -282,7 +282,8 @@ static int __init omap3_beagle_i2c_init(void)
 
 static void __init omap3_beagle_init_irq(void)
 {
-       omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
+       omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
+                            mt46h32m32lf6_sdrc_params);
        omap_init_irq();
 #ifdef CONFIG_OMAP_32K_TIMER
        omap2_gp_clockevent_set_gptimer(12);
@@ -408,6 +409,10 @@ static void __init omap3_beagle_init(void)
 
        usb_musb_init();
        omap3beagle_flash_init();
+
+       /* Ensure SDRC pins are mux'd for self-refresh */
+       omap_cfg_reg(H16_34XX_SDRC_CKE0);
+       omap_cfg_reg(H17_34XX_SDRC_CKE1);
 }
 
 static void __init omap3_beagle_map_io(void)
index cf3dd771a6784fe751542fa993e03971a93f946d..c4b144647dc574c4e31cb9adfc389106cbbe9cca 100644 (file)
@@ -280,7 +280,7 @@ struct spi_board_info omap3evm_spi_board_info[] = {
 
 static void __init omap3_evm_init_irq(void)
 {
-       omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
+       omap2_init_common_hw(mt46h32m32lf6_sdrc_params, NULL);
        omap_init_irq();
        omap_gpio_init();
        omap3evm_init_smc911x();
index e32aa23ce9629942d9d03befd1e3ee37a9b5c78f..864ee3d021f7b416c50e979b1204e2585cf1db47 100644 (file)
@@ -40,6 +40,7 @@
 #include <mach/mcspi.h>
 #include <mach/usb.h>
 #include <mach/keypad.h>
+#include <mach/mux.h>
 
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "mmc-twl4030.h"
@@ -310,7 +311,8 @@ static int __init omap3pandora_i2c_init(void)
 
 static void __init omap3pandora_init_irq(void)
 {
-       omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
+       omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
+                            mt46h32m32lf6_sdrc_params);
        omap_init_irq();
        omap_gpio_init();
 }
@@ -397,6 +399,10 @@ static void __init omap3pandora_init(void)
        omap3pandora_ads7846_init();
        pandora_keys_gpio_init();
        usb_musb_init();
+
+       /* Ensure SDRC pins are mux'd for self-refresh */
+       omap_cfg_reg(H16_34XX_SDRC_CKE0);
+       omap_cfg_reg(H17_34XX_SDRC_CKE1);
 }
 
 static void __init omap3pandora_map_io(void)
index dff5528fbfb567fbdd661d1546c5a8cc83e09cd7..6bce23004aa4ba0f1051126663f27ccd43447b18 100644 (file)
@@ -44,6 +44,7 @@
 #include <mach/gpmc.h>
 #include <mach/hardware.h>
 #include <mach/nand.h>
+#include <mach/mux.h>
 #include <mach/usb.h>
 
 #include "sdram-micron-mt46h32m32lf-6.h"
@@ -51,6 +52,7 @@
 
 #define OVERO_GPIO_BT_XGATE    15
 #define OVERO_GPIO_W2W_NRESET  16
+#define OVERO_GPIO_PENDOWN     114
 #define OVERO_GPIO_BT_NRESET   164
 #define OVERO_GPIO_USBH_CPEN   168
 #define OVERO_GPIO_USBH_NRESET 183
@@ -146,7 +148,7 @@ static struct platform_device overo_smsc911x_device = {
        .name           = "smsc911x",
        .id             = -1,
        .num_resources  = ARRAY_SIZE(overo_smsc911x_resources),
-       .resource       = &overo_smsc911x_resources,
+       .resource       = overo_smsc911x_resources,
        .dev            = {
                .platform_data = &overo_smsc911x_config,
        },
@@ -360,7 +362,8 @@ static int __init overo_i2c_init(void)
 
 static void __init overo_init_irq(void)
 {
-       omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
+       omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
+                            mt46h32m32lf6_sdrc_params);
        omap_init_irq();
        omap_gpio_init();
 }
@@ -395,6 +398,10 @@ static void __init overo_init(void)
        overo_ads7846_init();
        overo_init_smsc911x();
 
+       /* Ensure SDRC pins are mux'd for self-refresh */
+       omap_cfg_reg(H16_34XX_SDRC_CKE0);
+       omap_cfg_reg(H17_34XX_SDRC_CKE1);
+
        if ((gpio_request(OVERO_GPIO_W2W_NRESET,
                          "OVERO_GPIO_W2W_NRESET") == 0) &&
            (gpio_direction_output(OVERO_GPIO_W2W_NRESET, 1) == 0)) {
index 9a0bf6744a057518971f22d6d808c0f4c7af152b..56d931a425f7f74f93abd03465a214f2e7bf690d 100644 (file)
@@ -278,6 +278,10 @@ static struct twl4030_gpio_platform_data rx51_gpio_data = {
        .setup                  = rx51_twlgpio_setup,
 };
 
+static struct twl4030_usb_data rx51_usb_data = {
+       .usb_mode               = T2_USB_MODE_ULPI,
+};
+
 static struct twl4030_platform_data rx51_twldata = {
        .irq_base               = TWL4030_IRQ_BASE,
        .irq_end                = TWL4030_IRQ_END,
@@ -286,6 +290,7 @@ static struct twl4030_platform_data rx51_twldata = {
        .gpio                   = &rx51_gpio_data,
        .keypad                 = &rx51_kp_data,
        .madc                   = &rx51_madc_data,
+       .usb                    = &rx51_usb_data,
 
        .vaux1                  = &rx51_vaux1,
        .vaux2                  = &rx51_vaux2,
index 374ff63c3eb2d0cc4d55d8b49f85c9413b8df6d1..1c9e07fe82668ed5139d244f82bd9ceed088eacf 100644 (file)
@@ -61,7 +61,7 @@ static struct omap_board_config_kernel rx51_config[] = {
 
 static void __init rx51_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(NULL, NULL);
        omap_init_irq();
        omap_gpio_init();
 }
@@ -75,6 +75,10 @@ static void __init rx51_init(void)
        omap_serial_init();
        usb_musb_init();
        rx51_peripherals_init();
+
+       /* Ensure SDRC pins are mux'd for self-refresh */
+       omap_cfg_reg(H16_34XX_SDRC_CKE0);
+       omap_cfg_reg(H17_34XX_SDRC_CKE1);
 }
 
 static void __init rx51_map_io(void)
index bcc0f7632deaac0590bdc4313128826d19cb465a..427b7b8b1237e5bb035eea225eb7e7755790c08f 100644 (file)
@@ -25,7 +25,7 @@
 
 static void __init omap_zoom2_init_irq(void)
 {
-       omap2_init_common_hw(NULL);
+       omap2_init_common_hw(NULL, NULL);
        omap_init_irq();
        omap_gpio_init();
 }
index b0665f161c03845725a019f1f62ea64be8cf154d..456e2ad5f62136bb33187980f92b1323e1868462 100644 (file)
@@ -27,6 +27,7 @@
 #include <mach/clock.h>
 #include <mach/clockdomain.h>
 #include <mach/cpu.h>
+#include <mach/prcm.h>
 #include <asm/div64.h>
 
 #include <mach/sdrc.h>
@@ -38,8 +39,6 @@
 #include "cm-regbits-24xx.h"
 #include "cm-regbits-34xx.h"
 
-#define MAX_CLOCK_ENABLE_WAIT          100000
-
 /* DPLL rate rounding: minimum DPLL multiplier, divider values */
 #define DPLL_MIN_MULTIPLIER            1
 #define DPLL_MIN_DIVIDER               1
@@ -274,83 +273,97 @@ unsigned long omap2_fixed_divisor_recalc(struct clk *clk)
 }
 
 /**
- * omap2_wait_clock_ready - wait for clock to enable
- * @reg: physical address of clock IDLEST register
- * @mask: value to mask against to determine if the clock is active
- * @name: name of the clock (for printk)
+ * omap2_clk_dflt_find_companion - find companion clock to @clk
+ * @clk: struct clk * to find the companion clock of
+ * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
+ * @other_bit: u8 ** to return the companion clock bit shift in
+ *
+ * Note: We don't need special code here for INVERT_ENABLE for the
+ * time being since INVERT_ENABLE only applies to clocks enabled by
+ * CM_CLKEN_PLL
  *
- * Returns 1 if the clock enabled in time, or 0 if it failed to enable
- * in roughly MAX_CLOCK_ENABLE_WAIT microseconds.
+ * Convert CM_ICLKEN* <-> CM_FCLKEN*.  This conversion assumes it's
+ * just a matter of XORing the bits.
+ *
+ * Some clocks don't have companion clocks.  For example, modules with
+ * only an interface clock (such as MAILBOXES) don't have a companion
+ * clock.  Right now, this code relies on the hardware exporting a bit
+ * in the correct companion register that indicates that the
+ * nonexistent 'companion clock' is active.  Future patches will
+ * associate this type of code with per-module data structures to
+ * avoid this issue, and remove the casts.  No return value.
  */
-int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name)
+void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
+                                  u8 *other_bit)
 {
-       int i = 0;
-       int ena = 0;
+       u32 r;
 
        /*
-        * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
-        * 34xx reverses this, just to keep us on our toes
+        * Convert CM_ICLKEN* <-> CM_FCLKEN*.  This conversion assumes
+        * it's just a matter of XORing the bits.
         */
-       if (cpu_mask & (RATE_IN_242X | RATE_IN_243X))
-               ena = mask;
-       else if (cpu_mask & RATE_IN_343X)
-               ena = 0;
-
-       /* Wait for lock */
-       while (((__raw_readl(reg) & mask) != ena) &&
-              (i++ < MAX_CLOCK_ENABLE_WAIT)) {
-               udelay(1);
-       }
-
-       if (i <= MAX_CLOCK_ENABLE_WAIT)
-               pr_debug("Clock %s stable after %d loops\n", name, i);
-       else
-               printk(KERN_ERR "Clock %s didn't enable in %d tries\n",
-                      name, MAX_CLOCK_ENABLE_WAIT);
-
-
-       return (i < MAX_CLOCK_ENABLE_WAIT) ? 1 : 0;
-};
+       r = ((__force u32)clk->enable_reg ^ (CM_FCLKEN ^ CM_ICLKEN));
 
+       *other_reg = (__force void __iomem *)r;
+       *other_bit = clk->enable_bit;
+}
 
-/*
- * Note: We don't need special code here for INVERT_ENABLE
- * for the time being since INVERT_ENABLE only applies to clocks enabled by
- * CM_CLKEN_PLL
+/**
+ * omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk
+ * @clk: struct clk * to find IDLEST info for
+ * @idlest_reg: void __iomem ** to return the CM_IDLEST va in
+ * @idlest_bit: u8 ** to return the CM_IDLEST bit shift in
+ *
+ * Return the CM_IDLEST register address and bit shift corresponding
+ * to the module that "owns" this clock.  This default code assumes
+ * that the CM_IDLEST bit shift is the CM_*CLKEN bit shift, and that
+ * the IDLEST register address ID corresponds to the CM_*CLKEN
+ * register address ID (e.g., that CM_FCLKEN2 corresponds to
+ * CM_IDLEST2).  This is not true for all modules.  No return value.
  */
-static void omap2_clk_wait_ready(struct clk *clk)
+void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
+                               u8 *idlest_bit)
 {
-       void __iomem *reg, *other_reg, *st_reg;
-       u32 bit;
+       u32 r;
 
-       /*
-        * REVISIT: This code is pretty ugly.  It would be nice to generalize
-        * it and pull it into struct clk itself somehow.
-        */
-       reg = clk->enable_reg;
+       r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
+       *idlest_reg = (__force void __iomem *)r;
+       *idlest_bit = clk->enable_bit;
+}
 
-       /*
-        * Convert CM_ICLKEN* <-> CM_FCLKEN*.  This conversion assumes
-        * it's just a matter of XORing the bits.
-        */
-       other_reg = (void __iomem *)((u32)reg ^ (CM_FCLKEN ^ CM_ICLKEN));
+/**
+ * omap2_module_wait_ready - wait for an OMAP module to leave IDLE
+ * @clk: struct clk * belonging to the module
+ *
+ * If the necessary clocks for the OMAP hardware IP block that
+ * corresponds to clock @clk are enabled, then wait for the module to
+ * indicate readiness (i.e., to leave IDLE).  This code does not
+ * belong in the clock code and will be moved in the medium term to
+ * module-dependent code.  No return value.
+ */
+static void omap2_module_wait_ready(struct clk *clk)
+{
+       void __iomem *companion_reg, *idlest_reg;
+       u8 other_bit, idlest_bit;
+
+       /* Not all modules have multiple clocks that their IDLEST depends on */
+       if (clk->ops->find_companion) {
+               clk->ops->find_companion(clk, &companion_reg, &other_bit);
+               if (!(__raw_readl(companion_reg) & (1 << other_bit)))
+                       return;
+       }
 
-       /* Check if both functional and interface clocks
-        * are running. */
-       bit = 1 << clk->enable_bit;
-       if (!(__raw_readl(other_reg) & bit))
-               return;
-       st_reg = (void __iomem *)(((u32)other_reg & ~0xf0) | 0x20); /* CM_IDLEST* */
+       clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit);
 
-       omap2_wait_clock_ready(st_reg, bit, clk->name);
+       omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), clk->name);
 }
 
-static int omap2_dflt_clk_enable(struct clk *clk)
+int omap2_dflt_clk_enable(struct clk *clk)
 {
        u32 v;
 
        if (unlikely(clk->enable_reg == NULL)) {
-               printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
+               pr_err("clock.c: Enable for %s without enable code\n",
                       clk->name);
                return 0; /* REVISIT: -EINVAL */
        }
@@ -363,26 +376,13 @@ static int omap2_dflt_clk_enable(struct clk *clk)
        __raw_writel(v, clk->enable_reg);
        v = __raw_readl(clk->enable_reg); /* OCP barrier */
 
-       return 0;
-}
+       if (clk->ops->find_idlest)
+               omap2_module_wait_ready(clk);
 
-static int omap2_dflt_clk_enable_wait(struct clk *clk)
-{
-       int ret;
-
-       if (!clk->enable_reg) {
-               printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
-                      clk->name);
-               return 0; /* REVISIT: -EINVAL */
-       }
-
-       ret = omap2_dflt_clk_enable(clk);
-       if (ret == 0)
-               omap2_clk_wait_ready(clk);
-       return ret;
+       return 0;
 }
 
-static void omap2_dflt_clk_disable(struct clk *clk)
+void omap2_dflt_clk_disable(struct clk *clk)
 {
        u32 v;
 
@@ -406,8 +406,10 @@ static void omap2_dflt_clk_disable(struct clk *clk)
 }
 
 const struct clkops clkops_omap2_dflt_wait = {
-       .enable         = omap2_dflt_clk_enable_wait,
+       .enable         = omap2_dflt_clk_enable,
        .disable        = omap2_dflt_clk_disable,
+       .find_companion = omap2_clk_dflt_find_companion,
+       .find_idlest    = omap2_clk_dflt_find_idlest,
 };
 
 const struct clkops clkops_omap2_dflt = {
index 2679ddfa64248307abad3f45c256423a6936a0a5..9ae7540f8af2c078e35ea661d759683414ad2664 100644 (file)
@@ -65,6 +65,12 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
 u32 omap2_get_dpll_rate(struct clk *clk);
 int omap2_wait_clock_ready(void __iomem *reg, u32 cval, const char *name);
 void omap2_clk_prepare_for_reboot(void);
+int omap2_dflt_clk_enable(struct clk *clk);
+void omap2_dflt_clk_disable(struct clk *clk);
+void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,
+                                  u8 *other_bit);
+void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,
+                               u8 *idlest_bit);
 
 extern const struct clkops clkops_omap2_dflt_wait;
 extern const struct clkops clkops_omap2_dflt;
index 44de0271fc2f23a434e888176e9f34e6f0eba3dc..bc5d3ac6661191e3eeb68ef2c2d0723688d337fd 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <mach/clock.h>
 #include <mach/sram.h>
+#include <mach/prcm.h>
 #include <asm/div64.h>
 #include <asm/clkdev.h>
 
 static const struct clkops clkops_oscck;
 static const struct clkops clkops_fixed;
 
+static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
+                                          void __iomem **idlest_reg,
+                                          u8 *idlest_bit);
+
+/* 2430 I2CHS has non-standard IDLEST register */
+static const struct clkops clkops_omap2430_i2chs_wait = {
+       .enable         = omap2_dflt_clk_enable,
+       .disable        = omap2_dflt_clk_disable,
+       .find_idlest    = omap2430_clk_i2chs_find_idlest,
+       .find_companion = omap2_clk_dflt_find_companion,
+};
+
 #include "clock24xx.h"
 
 struct omap_clk {
@@ -239,6 +252,26 @@ static void __iomem *prcm_clksrc_ctrl;
  * Omap24xx specific clock functions
  *-------------------------------------------------------------------------*/
 
+/**
+ * omap2430_clk_i2chs_find_idlest - return CM_IDLEST info for 2430 I2CHS
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ *
+ * OMAP2430 I2CHS CM_IDLEST bits are in CM_IDLEST1_CORE, but the
+ * CM_*CLKEN bits are in CM_{I,F}CLKEN2_CORE.  This custom function
+ * passes back the correct CM_IDLEST register address for I2CHS
+ * modules.  No return value.
+ */
+static void omap2430_clk_i2chs_find_idlest(struct clk *clk,
+                                          void __iomem **idlest_reg,
+                                          u8 *idlest_bit)
+{
+       *idlest_reg = OMAP_CM_REGADDR(CORE_MOD, CM_IDLEST);
+       *idlest_bit = clk->enable_bit;
+}
+
+
 /**
  * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
  * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
@@ -325,8 +358,8 @@ static int omap2_clk_fixed_enable(struct clk *clk)
        else if (clk == &apll54_ck)
                cval = OMAP24XX_ST_54M_APLL;
 
-       omap2_wait_clock_ready(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), cval,
-                           clk->name);
+       omap2_cm_wait_idlest(OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), cval,
+                            clk->name);
 
        /*
         * REVISIT: Should we return an error code if omap2_wait_clock_ready()
index 458f00cdcbea3a354658f2b2fe7b23c25cf3ec55..d19cf7a7d8db36ef7045edb601b65361709c4ddd 100644 (file)
@@ -2337,7 +2337,7 @@ static struct clk i2c2_fck = {
 
 static struct clk i2chs2_fck = {
        .name           = "i2c_fck",
-       .ops            = &clkops_omap2_dflt_wait,
+       .ops            = &clkops_omap2430_i2chs_wait,
        .id             = 2,
        .parent         = &func_96m_ck,
        .clkdm_name     = "core_l4_clkdm",
@@ -2370,7 +2370,7 @@ static struct clk i2c1_fck = {
 
 static struct clk i2chs1_fck = {
        .name           = "i2c_fck",
-       .ops            = &clkops_omap2_dflt_wait,
+       .ops            = &clkops_omap2430_i2chs_wait,
        .id             = 1,
        .parent         = &func_96m_ck,
        .clkdm_name     = "core_l4_clkdm",
index 045da923e75bd0cde5bd275e0daed86a4592ac9e..cd7819cc0c9eb091226adf584c3608a86cb31508 100644 (file)
@@ -2,7 +2,7 @@
  * OMAP3-specific clock framework functions
  *
  * Copyright (C) 2007-2008 Texas Instruments, Inc.
- * Copyright (C) 2007-2008 Nokia Corporation
+ * Copyright (C) 2007-2009 Nokia Corporation
  *
  * Written by Paul Walmsley
  * Testing and integration fixes by Jouni Högander
 
 static const struct clkops clkops_noncore_dpll_ops;
 
+static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
+                                           void __iomem **idlest_reg,
+                                           u8 *idlest_bit);
+static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
+                                           void __iomem **idlest_reg,
+                                           u8 *idlest_bit);
+static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
+                                                   void __iomem **idlest_reg,
+                                                   u8 *idlest_bit);
+
+static const struct clkops clkops_omap3430es2_ssi_wait = {
+       .enable         = omap2_dflt_clk_enable,
+       .disable        = omap2_dflt_clk_disable,
+       .find_idlest    = omap3430es2_clk_ssi_find_idlest,
+       .find_companion = omap2_clk_dflt_find_companion,
+};
+
+static const struct clkops clkops_omap3430es2_hsotgusb_wait = {
+       .enable         = omap2_dflt_clk_enable,
+       .disable        = omap2_dflt_clk_disable,
+       .find_idlest    = omap3430es2_clk_hsotgusb_find_idlest,
+       .find_companion = omap2_clk_dflt_find_companion,
+};
+
+static const struct clkops clkops_omap3430es2_dss_usbhost_wait = {
+       .enable         = omap2_dflt_clk_enable,
+       .disable        = omap2_dflt_clk_disable,
+       .find_idlest    = omap3430es2_clk_dss_usbhost_find_idlest,
+       .find_companion = omap2_clk_dflt_find_companion,
+};
+
 #include "clock34xx.h"
 
 struct omap_clk {
@@ -157,10 +188,13 @@ static struct omap_clk omap34xx_clks[] = {
        CLK(NULL,       "fshostusb_fck", &fshostusb_fck, CK_3430ES1),
        CLK(NULL,       "core_12m_fck", &core_12m_fck,  CK_343X),
        CLK("omap_hdq.0", "fck",        &hdq_fck,       CK_343X),
-       CLK(NULL,       "ssi_ssr_fck",  &ssi_ssr_fck,   CK_343X),
-       CLK(NULL,       "ssi_sst_fck",  &ssi_sst_fck,   CK_343X),
+       CLK(NULL,       "ssi_ssr_fck",  &ssi_ssr_fck_3430es1,   CK_3430ES1),
+       CLK(NULL,       "ssi_ssr_fck",  &ssi_ssr_fck_3430es2,   CK_3430ES2),
+       CLK(NULL,       "ssi_sst_fck",  &ssi_sst_fck_3430es1,   CK_3430ES1),
+       CLK(NULL,       "ssi_sst_fck",  &ssi_sst_fck_3430es2,   CK_3430ES2),
        CLK(NULL,       "core_l3_ick",  &core_l3_ick,   CK_343X),
-       CLK("musb_hdrc",        "ick",  &hsotgusb_ick,  CK_343X),
+       CLK("musb_hdrc",        "ick",  &hsotgusb_ick_3430es1,  CK_3430ES1),
+       CLK("musb_hdrc",        "ick",  &hsotgusb_ick_3430es2,  CK_3430ES2),
        CLK(NULL,       "sdrc_ick",     &sdrc_ick,      CK_343X),
        CLK(NULL,       "gpmc_fck",     &gpmc_fck,      CK_343X),
        CLK(NULL,       "security_l3_ick", &security_l3_ick, CK_343X),
@@ -193,18 +227,21 @@ static struct omap_clk omap34xx_clks[] = {
        CLK(NULL,       "mailboxes_ick", &mailboxes_ick, CK_343X),
        CLK(NULL,       "omapctrl_ick", &omapctrl_ick,  CK_343X),
        CLK(NULL,       "ssi_l4_ick",   &ssi_l4_ick,    CK_343X),
-       CLK(NULL,       "ssi_ick",      &ssi_ick,       CK_343X),
+       CLK(NULL,       "ssi_ick",      &ssi_ick_3430es1,       CK_3430ES1),
+       CLK(NULL,       "ssi_ick",      &ssi_ick_3430es2,       CK_3430ES2),
        CLK(NULL,       "usb_l4_ick",   &usb_l4_ick,    CK_3430ES1),
        CLK(NULL,       "security_l4_ick2", &security_l4_ick2, CK_343X),
        CLK(NULL,       "aes1_ick",     &aes1_ick,      CK_343X),
        CLK("omap_rng", "ick",          &rng_ick,       CK_343X),
        CLK(NULL,       "sha11_ick",    &sha11_ick,     CK_343X),
        CLK(NULL,       "des1_ick",     &des1_ick,      CK_343X),
-       CLK("omapfb",   "dss1_fck",     &dss1_alwon_fck, CK_343X),
+       CLK("omapfb",   "dss1_fck",     &dss1_alwon_fck_3430es1, CK_3430ES1),
+       CLK("omapfb",   "dss1_fck",     &dss1_alwon_fck_3430es2, CK_3430ES2),
        CLK("omapfb",   "tv_fck",       &dss_tv_fck,    CK_343X),
        CLK("omapfb",   "video_fck",    &dss_96m_fck,   CK_343X),
        CLK("omapfb",   "dss2_fck",     &dss2_alwon_fck, CK_343X),
-       CLK("omapfb",   "ick",          &dss_ick,       CK_343X),
+       CLK("omapfb",   "ick",          &dss_ick_3430es1,       CK_3430ES1),
+       CLK("omapfb",   "ick",          &dss_ick_3430es2,       CK_3430ES2),
        CLK(NULL,       "cam_mclk",     &cam_mclk,      CK_343X),
        CLK(NULL,       "cam_ick",      &cam_ick,       CK_343X),
        CLK(NULL,       "csi2_96m_fck", &csi2_96m_fck,  CK_343X),
@@ -300,6 +337,73 @@ static struct omap_clk omap34xx_clks[] = {
  */
 #define SDRC_MPURATE_LOOPS             96
 
+/**
+ * omap3430es2_clk_ssi_find_idlest - return CM_IDLEST info for SSI
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ *
+ * The OMAP3430ES2 SSI target CM_IDLEST bit is at a different shift
+ * from the CM_{I,F}CLKEN bit.  Pass back the correct info via
+ * @idlest_reg and @idlest_bit.  No return value.
+ */
+static void omap3430es2_clk_ssi_find_idlest(struct clk *clk,
+                                           void __iomem **idlest_reg,
+                                           u8 *idlest_bit)
+{
+       u32 r;
+
+       r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
+       *idlest_reg = (__force void __iomem *)r;
+       *idlest_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT;
+}
+
+/**
+ * omap3430es2_clk_dss_usbhost_find_idlest - CM_IDLEST info for DSS, USBHOST
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ *
+ * Some OMAP modules on OMAP3 ES2+ chips have both initiator and
+ * target IDLEST bits.  For our purposes, we are concerned with the
+ * target IDLEST bits, which exist at a different bit position than
+ * the *CLKEN bit position for these modules (DSS and USBHOST) (The
+ * default find_idlest code assumes that they are at the same
+ * position.)  No return value.
+ */
+static void omap3430es2_clk_dss_usbhost_find_idlest(struct clk *clk,
+                                                   void __iomem **idlest_reg,
+                                                   u8 *idlest_bit)
+{
+       u32 r;
+
+       r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
+       *idlest_reg = (__force void __iomem *)r;
+       /* USBHOST_IDLE has same shift */
+       *idlest_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT;
+}
+
+/**
+ * omap3430es2_clk_hsotgusb_find_idlest - return CM_IDLEST info for HSOTGUSB
+ * @clk: struct clk * being enabled
+ * @idlest_reg: void __iomem ** to store CM_IDLEST reg address into
+ * @idlest_bit: pointer to a u8 to store the CM_IDLEST bit shift into
+ *
+ * The OMAP3430ES2 HSOTGUSB target CM_IDLEST bit is at a different
+ * shift from the CM_{I,F}CLKEN bit.  Pass back the correct info via
+ * @idlest_reg and @idlest_bit.  No return value.
+ */
+static void omap3430es2_clk_hsotgusb_find_idlest(struct clk *clk,
+                                                void __iomem **idlest_reg,
+                                                u8 *idlest_bit)
+{
+       u32 r;
+
+       r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);
+       *idlest_reg = (__force void __iomem *)r;
+       *idlest_bit = OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT;
+}
+
 /**
  * omap3_dpll_recalc - recalculate DPLL rate
  * @clk: DPLL struct clk
@@ -725,7 +829,9 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
        u32 unlock_dll = 0;
        u32 c;
        unsigned long validrate, sdrcrate, mpurate;
-       struct omap_sdrc_params *sp;
+       struct omap_sdrc_params *sdrc_cs0;
+       struct omap_sdrc_params *sdrc_cs1;
+       int ret;
 
        if (!clk || !rate)
                return -EINVAL;
@@ -743,8 +849,8 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
        else
                sdrcrate >>= ((clk->rate / rate) >> 1);
 
-       sp = omap2_sdrc_get_params(sdrcrate);
-       if (!sp)
+       ret = omap2_sdrc_get_params(sdrcrate, &sdrc_cs0, &sdrc_cs1);
+       if (ret)
                return -EINVAL;
 
        if (sdrcrate < MIN_SDRC_DLL_LOCK_FREQ) {
@@ -765,12 +871,29 @@ static int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate)
 
        pr_debug("clock: changing CORE DPLL rate from %lu to %lu\n", clk->rate,
                 validrate);
-       pr_debug("clock: SDRC timing params used: %08x %08x %08x\n",
-                sp->rfr_ctrl, sp->actim_ctrla, sp->actim_ctrlb);
-
-       omap3_configure_core_dpll(sp->rfr_ctrl, sp->actim_ctrla,
-                                 sp->actim_ctrlb, new_div, unlock_dll, c,
-                                 sp->mr, rate > clk->rate);
+       pr_debug("clock: SDRC CS0 timing params used:"
+                " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
+                sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+                sdrc_cs0->actim_ctrlb, sdrc_cs0->mr);
+       if (sdrc_cs1)
+               pr_debug("clock: SDRC CS1 timing params used: "
+                " RFR %08x CTRLA %08x CTRLB %08x MR %08x\n",
+                sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
+                sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
+
+       if (sdrc_cs1)
+               omap3_configure_core_dpll(
+                                 new_div, unlock_dll, c, rate > clk->rate,
+                                 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+                                 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
+                                 sdrc_cs1->rfr_ctrl, sdrc_cs1->actim_ctrla,
+                                 sdrc_cs1->actim_ctrlb, sdrc_cs1->mr);
+       else
+               omap3_configure_core_dpll(
+                                 new_div, unlock_dll, c, rate > clk->rate,
+                                 sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla,
+                                 sdrc_cs0->actim_ctrlb, sdrc_cs0->mr,
+                                 0, 0, 0, 0);
 
        return 0;
 }
index e433aec4efdd2c65587556702df13001c9aaffe6..57cc2725b923bd31fc97eb9a5a2c85780ba83bc6 100644 (file)
@@ -1568,7 +1568,7 @@ static const struct clksel ssi_ssr_clksel[] = {
        { .parent = NULL }
 };
 
-static struct clk ssi_ssr_fck = {
+static struct clk ssi_ssr_fck_3430es1 = {
        .name           = "ssi_ssr_fck",
        .ops            = &clkops_omap2_dflt,
        .init           = &omap2_init_clksel_parent,
@@ -1581,10 +1581,31 @@ static struct clk ssi_ssr_fck = {
        .recalc         = &omap2_clksel_recalc,
 };
 
-static struct clk ssi_sst_fck = {
+static struct clk ssi_ssr_fck_3430es2 = {
+       .name           = "ssi_ssr_fck",
+       .ops            = &clkops_omap3430es2_ssi_wait,
+       .init           = &omap2_init_clksel_parent,
+       .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1),
+       .enable_bit     = OMAP3430_EN_SSI_SHIFT,
+       .clksel_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_CLKSEL),
+       .clksel_mask    = OMAP3430_CLKSEL_SSI_MASK,
+       .clksel         = ssi_ssr_clksel,
+       .clkdm_name     = "core_l4_clkdm",
+       .recalc         = &omap2_clksel_recalc,
+};
+
+static struct clk ssi_sst_fck_3430es1 = {
        .name           = "ssi_sst_fck",
        .ops            = &clkops_null,
-       .parent         = &ssi_ssr_fck,
+       .parent         = &ssi_ssr_fck_3430es1,
+       .fixed_div      = 2,
+       .recalc         = &omap2_fixed_divisor_recalc,
+};
+
+static struct clk ssi_sst_fck_3430es2 = {
+       .name           = "ssi_sst_fck",
+       .ops            = &clkops_null,
+       .parent         = &ssi_ssr_fck_3430es2,
        .fixed_div      = 2,
        .recalc         = &omap2_fixed_divisor_recalc,
 };
@@ -1606,9 +1627,19 @@ static struct clk core_l3_ick = {
        .recalc         = &followparent_recalc,
 };
 
-static struct clk hsotgusb_ick = {
+static struct clk hsotgusb_ick_3430es1 = {
        .name           = "hsotgusb_ick",
-       .ops            = &clkops_omap2_dflt_wait,
+       .ops            = &clkops_omap2_dflt,
+       .parent         = &core_l3_ick,
+       .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+       .enable_bit     = OMAP3430_EN_HSOTGUSB_SHIFT,
+       .clkdm_name     = "core_l3_clkdm",
+       .recalc         = &followparent_recalc,
+};
+
+static struct clk hsotgusb_ick_3430es2 = {
+       .name           = "hsotgusb_ick",
+       .ops            = &clkops_omap3430es2_hsotgusb_wait,
        .parent         = &core_l3_ick,
        .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
        .enable_bit     = OMAP3430_EN_HSOTGUSB_SHIFT,
@@ -1947,7 +1978,7 @@ static struct clk ssi_l4_ick = {
        .recalc         = &followparent_recalc,
 };
 
-static struct clk ssi_ick = {
+static struct clk ssi_ick_3430es1 = {
        .name           = "ssi_ick",
        .ops            = &clkops_omap2_dflt,
        .parent         = &ssi_l4_ick,
@@ -1957,6 +1988,16 @@ static struct clk ssi_ick = {
        .recalc         = &followparent_recalc,
 };
 
+static struct clk ssi_ick_3430es2 = {
+       .name           = "ssi_ick",
+       .ops            = &clkops_omap3430es2_ssi_wait,
+       .parent         = &ssi_l4_ick,
+       .enable_reg     = OMAP_CM_REGADDR(CORE_MOD, CM_ICLKEN1),
+       .enable_bit     = OMAP3430_EN_SSI_SHIFT,
+       .clkdm_name     = "core_l4_clkdm",
+       .recalc         = &followparent_recalc,
+};
+
 /* REVISIT: Technically the TRM claims that this is CORE_CLK based,
  * but l4_ick makes more sense to me */
 
@@ -2024,7 +2065,7 @@ static struct clk des1_ick = {
 };
 
 /* DSS */
-static struct clk dss1_alwon_fck = {
+static struct clk dss1_alwon_fck_3430es1 = {
        .name           = "dss1_alwon_fck",
        .ops            = &clkops_omap2_dflt,
        .parent         = &dpll4_m4x2_ck,
@@ -2034,6 +2075,16 @@ static struct clk dss1_alwon_fck = {
        .recalc         = &followparent_recalc,
 };
 
+static struct clk dss1_alwon_fck_3430es2 = {
+       .name           = "dss1_alwon_fck",
+       .ops            = &clkops_omap3430es2_dss_usbhost_wait,
+       .parent         = &dpll4_m4x2_ck,
+       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_FCLKEN),
+       .enable_bit     = OMAP3430_EN_DSS1_SHIFT,
+       .clkdm_name     = "dss_clkdm",
+       .recalc         = &followparent_recalc,
+};
+
 static struct clk dss_tv_fck = {
        .name           = "dss_tv_fck",
        .ops            = &clkops_omap2_dflt,
@@ -2067,7 +2118,7 @@ static struct clk dss2_alwon_fck = {
        .recalc         = &followparent_recalc,
 };
 
-static struct clk dss_ick = {
+static struct clk dss_ick_3430es1 = {
        /* Handles both L3 and L4 clocks */
        .name           = "dss_ick",
        .ops            = &clkops_omap2_dflt,
@@ -2079,6 +2130,18 @@ static struct clk dss_ick = {
        .recalc         = &followparent_recalc,
 };
 
+static struct clk dss_ick_3430es2 = {
+       /* Handles both L3 and L4 clocks */
+       .name           = "dss_ick",
+       .ops            = &clkops_omap3430es2_dss_usbhost_wait,
+       .parent         = &l4_ick,
+       .init           = &omap2_init_clk_clkdm,
+       .enable_reg     = OMAP_CM_REGADDR(OMAP3430_DSS_MOD, CM_ICLKEN),
+       .enable_bit     = OMAP3430_CM_ICLKEN_DSS_EN_DSS_SHIFT,
+       .clkdm_name     = "dss_clkdm",
+       .recalc         = &followparent_recalc,
+};
+
 /* CAM */
 
 static struct clk cam_mclk = {
@@ -2118,7 +2181,7 @@ static struct clk csi2_96m_fck = {
 
 static struct clk usbhost_120m_fck = {
        .name           = "usbhost_120m_fck",
-       .ops            = &clkops_omap2_dflt_wait,
+       .ops            = &clkops_omap2_dflt,
        .parent         = &dpll5_m2_ck,
        .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
@@ -2129,7 +2192,7 @@ static struct clk usbhost_120m_fck = {
 
 static struct clk usbhost_48m_fck = {
        .name           = "usbhost_48m_fck",
-       .ops            = &clkops_omap2_dflt_wait,
+       .ops            = &clkops_omap3430es2_dss_usbhost_wait,
        .parent         = &omap_48m_fck,
        .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_FCLKEN),
@@ -2141,7 +2204,7 @@ static struct clk usbhost_48m_fck = {
 static struct clk usbhost_ick = {
        /* Handles both L3 and L4 clocks */
        .name           = "usbhost_ick",
-       .ops            = &clkops_omap2_dflt_wait,
+       .ops            = &clkops_omap3430es2_dss_usbhost_wait,
        .parent         = &l4_ick,
        .init           = &omap2_init_clk_clkdm,
        .enable_reg     = OMAP_CM_REGADDR(OMAP3430ES2_USBHOST_MOD, CM_ICLKEN),
index 1d3c93bf86d32a69c9d9d5a258bce6a51078c6fb..f3c91a1ca391f8acf011c54e827f41ec2324c30b 100644 (file)
@@ -29,9 +29,9 @@
  * These registers appear once per CM module.
  */
 
-#define OMAP3430_CM_REVISION           OMAP_CM_REGADDR(OCP_MOD, 0x0000)
-#define OMAP3430_CM_SYSCONFIG          OMAP_CM_REGADDR(OCP_MOD, 0x0010)
-#define OMAP3430_CM_POLCTRL            OMAP_CM_REGADDR(OCP_MOD, 0x009c)
+#define OMAP3430_CM_REVISION           OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000)
+#define OMAP3430_CM_SYSCONFIG          OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010)
+#define OMAP3430_CM_POLCTRL            OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c)
 
 #define OMAP3_CM_CLKOUT_CTRL_OFFSET    0x0070
 #define OMAP3430_CM_CLKOUT_CTRL                OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070)
index 3a86b0f660314c28234c31fe7bd1e731d1a6b95e..e9b9bcb19b4e3b12680926435e9b0deee261e42c 100644 (file)
@@ -276,14 +276,15 @@ static int __init _omap2_init_reprogram_sdrc(void)
        return v;
 }
 
-void __init omap2_init_common_hw(struct omap_sdrc_params *sp)
+void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
+                                struct omap_sdrc_params *sdrc_cs1)
 {
        omap2_mux_init();
 #ifndef CONFIG_ARCH_OMAP4 /* FIXME: Remove this once the clkdev is ready */
        pwrdm_init(powerdomains_omap);
        clkdm_init(clockdomains_omap, clkdm_pwrdm_autodeps);
        omap2_clk_init();
-       omap2_sdrc_init(sp);
+       omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
        _omap2_init_reprogram_sdrc();
 #endif
        gpmc_init();
index 1541fd4c8d0fd0b28bacf30eca96853f7da04a3d..3c04c2f1b23ff2faae92630600f7c20a4ed2b57b 100644 (file)
@@ -119,6 +119,7 @@ static int twl_mmc_late_init(struct device *dev)
                                if (i != 0)
                                        break;
                                ret = PTR_ERR(reg);
+                               hsmmc[i].vcc = NULL;
                                goto err;
                        }
                        hsmmc[i].vcc = reg;
@@ -165,8 +166,13 @@ done:
 static void twl_mmc_cleanup(struct device *dev)
 {
        struct omap_mmc_platform_data *mmc = dev->platform_data;
+       int i;
 
        gpio_free(mmc->slots[0].switch_pin);
+       for(i = 0; i < ARRAY_SIZE(hsmmc); i++) {
+               regulator_put(hsmmc[i].vcc);
+               regulator_put(hsmmc[i].vcc_aux);
+       }
 }
 
 #ifdef CONFIG_PM
index 026c4fc883a7f21816a7b7433cd96e62092a8bc4..43d6b92b65f293ab2a329a49e2aafab58e3a9015 100644 (file)
@@ -486,6 +486,12 @@ MUX_CFG_34XX("H19_34XX_GPIO164_OUT", 0x19c,
                OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_OUTPUT)
 MUX_CFG_34XX("J25_34XX_GPIO170", 0x1c6,
                OMAP34XX_MUX_MODE4 | OMAP34XX_PIN_INPUT)
+
+/* OMAP3 SDRC CKE signals to SDR/DDR ram chips */
+MUX_CFG_34XX("H16_34XX_SDRC_CKE0", 0x262,
+               OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT)
+MUX_CFG_34XX("H17_34XX_SDRC_CKE1", 0x264,
+               OMAP34XX_MUX_MODE0 | OMAP34XX_PIN_OUTPUT)
 };
 
 #define OMAP34XX_PINS_SZ       ARRAY_SIZE(omap34xx_pins)
index f7b3baf766789a157dafb06b7d7d99621cf98357..21201cd4117b5d55a4380422d253687372657bad 100644 (file)
@@ -11,9 +11,6 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_PM_H
 #define __ARCH_ARM_MACH_OMAP2_PM_H
 
-extern int omap2_pm_init(void);
-extern int omap3_pm_init(void);
-
 #ifdef CONFIG_PM_DEBUG
 extern void omap2_pm_dump(int mode, int resume, unsigned int us);
 extern int omap2_pm_debug;
index db1025562fb066b8714fa4594a14162875530c05..528dbdc26e2363536335c88446b8c17ebbef234b 100644 (file)
@@ -470,7 +470,7 @@ static void __init prcm_setup_regs(void)
                          WKUP_MOD, PM_WKEN);
 }
 
-int __init omap2_pm_init(void)
+static int __init omap2_pm_init(void)
 {
        u32 l;
 
index 841d4c5ed8be10efa543d4ddb37e5d24acaaab32..488d595d8e4b337a29a589a950a5d3f73aca15a4 100644 (file)
@@ -39,7 +39,9 @@
 struct power_state {
        struct powerdomain *pwrdm;
        u32 next_state;
+#ifdef CONFIG_SUSPEND
        u32 saved_state;
+#endif
        struct list_head node;
 };
 
@@ -293,6 +295,9 @@ out:
        local_irq_enable();
 }
 
+#ifdef CONFIG_SUSPEND
+static suspend_state_t suspend_state;
+
 static int omap3_pm_prepare(void)
 {
        disable_hlt();
@@ -321,7 +326,6 @@ static int omap3_pm_suspend(void)
 restore:
        /* Restore next_pwrsts */
        list_for_each_entry(pwrst, &pwrst_list, node) {
-               set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
                state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
                if (state > pwrst->next_state) {
                        printk(KERN_INFO "Powerdomain (%s) didn't enter "
@@ -329,6 +333,7 @@ restore:
                               pwrst->pwrdm->name, pwrst->next_state);
                        ret = -1;
                }
+               set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
        }
        if (ret)
                printk(KERN_ERR "Could not enter target state in pm_suspend\n");
@@ -339,11 +344,11 @@ restore:
        return ret;
 }
 
-static int omap3_pm_enter(suspend_state_t state)
+static int omap3_pm_enter(suspend_state_t unused)
 {
        int ret = 0;
 
-       switch (state) {
+       switch (suspend_state) {
        case PM_SUSPEND_STANDBY:
        case PM_SUSPEND_MEM:
                ret = omap3_pm_suspend();
@@ -360,12 +365,30 @@ static void omap3_pm_finish(void)
        enable_hlt();
 }
 
+/* Hooks to enable / disable UART interrupts during suspend */
+static int omap3_pm_begin(suspend_state_t state)
+{
+       suspend_state = state;
+       omap_uart_enable_irqs(0);
+       return 0;
+}
+
+static void omap3_pm_end(void)
+{
+       suspend_state = PM_SUSPEND_ON;
+       omap_uart_enable_irqs(1);
+       return;
+}
+
 static struct platform_suspend_ops omap_pm_ops = {
+       .begin          = omap3_pm_begin,
+       .end            = omap3_pm_end,
        .prepare        = omap3_pm_prepare,
        .enter          = omap3_pm_enter,
        .finish         = omap3_pm_finish,
        .valid          = suspend_valid_only_mem,
 };
+#endif /* CONFIG_SUSPEND */
 
 
 /**
@@ -613,6 +636,24 @@ static void __init prcm_setup_regs(void)
        /* Clear any pending PRCM interrupts */
        prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
 
+       /* Don't attach IVA interrupts */
+       prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
+       prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
+       prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
+       prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
+
+       /* Clear any pending 'reset' flags */
+       prm_write_mod_reg(0xffffffff, MPU_MOD, RM_RSTST);
+       prm_write_mod_reg(0xffffffff, CORE_MOD, RM_RSTST);
+       prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, RM_RSTST);
+       prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, RM_RSTST);
+       prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, RM_RSTST);
+       prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, RM_RSTST);
+       prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, RM_RSTST);
+
+       /* Clear any pending PRCM interrupts */
+       prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+
        omap3_iva_idle();
        omap3_d2d_idle();
 }
@@ -652,7 +693,7 @@ static int __init clkdms_setup(struct clockdomain *clkdm)
        return 0;
 }
 
-int __init omap3_pm_init(void)
+static int __init omap3_pm_init(void)
 {
        struct power_state *pwrst, *tmp;
        int ret;
@@ -692,7 +733,9 @@ int __init omap3_pm_init(void)
        _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
                                         omap34xx_cpu_suspend_sz);
 
+#ifdef CONFIG_SUSPEND
        suspend_set_ops(&omap_pm_ops);
+#endif /* CONFIG_SUSPEND */
 
        pm_idle = omap3_pm_idle;
 
index f945156d55859cbf97e0f70f9f917c7d2630107f..ced555a4cd1a1d50fb3094c892bfdfd07112caae 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/delay.h>
 
 #include <mach/common.h>
 #include <mach/prcm.h>
@@ -28,6 +29,8 @@
 static void __iomem *prm_base;
 static void __iomem *cm_base;
 
+#define MAX_MODULE_ENABLE_WAIT         100000
+
 u32 omap_prcm_get_reset_sources(void)
 {
        /* XXX This presumably needs modification for 34XX */
@@ -120,6 +123,46 @@ u32 cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx)
 }
 EXPORT_SYMBOL(cm_rmw_mod_reg_bits);
 
+/**
+ * omap2_cm_wait_idlest - wait for IDLEST bit to indicate module readiness
+ * @reg: physical address of module IDLEST register
+ * @mask: value to mask against to determine if the module is active
+ * @name: name of the clock (for printk)
+ *
+ * Returns 1 if the module indicated readiness in time, or 0 if it
+ * failed to enable in roughly MAX_MODULE_ENABLE_WAIT microseconds.
+ */
+int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name)
+{
+       int i = 0;
+       int ena = 0;
+
+       /*
+        * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
+        * 34xx reverses this, just to keep us on our toes
+        */
+       if (cpu_is_omap24xx())
+               ena = mask;
+       else if (cpu_is_omap34xx())
+               ena = 0;
+       else
+               BUG();
+
+       /* Wait for lock */
+       while (((__raw_readl(reg) & mask) != ena) &&
+              (i++ < MAX_MODULE_ENABLE_WAIT))
+               udelay(1);
+
+       if (i < MAX_MODULE_ENABLE_WAIT)
+               pr_debug("cm: Module associated with clock %s ready after %d "
+                        "loops\n", name, i);
+       else
+               pr_err("cm: Module associated with clock %s didn't enable in "
+                      "%d tries\n", name, MAX_MODULE_ENABLE_WAIT);
+
+       return (i < MAX_MODULE_ENABLE_WAIT) ? 1 : 0;
+};
+
 void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals)
 {
        prm_base = omap2_globals->prm;
index 2045441e8385987967eb02b7f6045c503dc94b1d..9e3bd4fa781082fb4832ad26d96518edabb548fe 100644 (file)
@@ -32,7 +32,7 @@
 #include <mach/sdrc.h>
 #include "sdrc.h"
 
-static struct omap_sdrc_params *sdrc_init_params;
+static struct omap_sdrc_params *sdrc_init_params_cs0, *sdrc_init_params_cs1;
 
 void __iomem *omap2_sdrc_base;
 void __iomem *omap2_sms_base;
@@ -45,33 +45,49 @@ void __iomem *omap2_sms_base;
 /**
  * omap2_sdrc_get_params - return SDRC register values for a given clock rate
  * @r: SDRC clock rate (in Hz)
+ * @sdrc_cs0: chip select 0 ram timings **
+ * @sdrc_cs1: chip select 1 ram timings **
  *
  * Return pre-calculated values for the SDRC_ACTIM_CTRLA,
- * SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL, and SDRC_MR registers, for a given
- * SDRC clock rate 'r'.  These parameters control various timing
- * delays in the SDRAM controller that are expressed in terms of the
- * number of SDRC clock cycles to wait; hence the clock rate
- * dependency. Note that sdrc_init_params must be sorted rate
- * descending.  Also assumes that both chip-selects use the same
- * timing parameters.  Returns a struct omap_sdrc_params * upon
- * success, or NULL upon failure.
+ *  SDRC_ACTIM_CTRLB, SDRC_RFR_CTRL and SDRC_MR registers in sdrc_cs[01]
+ *  structs,for a given SDRC clock rate 'r'.
+ * These parameters control various timing delays in the SDRAM controller
+ *  that are expressed in terms of the number of SDRC clock cycles to
+ *  wait; hence the clock rate dependency.
+ *
+ * Supports 2 different timing parameters for both chip selects.
+ *
+ * Note 1: the sdrc_init_params_cs[01] must be sorted rate descending.
+ * Note 2: If sdrc_init_params_cs_1 is not NULL it must be of same size
+ *  as sdrc_init_params_cs_0.
+ *
+ * Fills in the struct omap_sdrc_params * for each chip select.
+ * Returns 0 upon success or -1 upon failure.
  */
-struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r)
+int omap2_sdrc_get_params(unsigned long r,
+                         struct omap_sdrc_params **sdrc_cs0,
+                         struct omap_sdrc_params **sdrc_cs1)
 {
-       struct omap_sdrc_params *sp;
+       struct omap_sdrc_params *sp0, *sp1;
 
-       if (!sdrc_init_params)
-               return NULL;
+       if (!sdrc_init_params_cs0)
+               return -1;
 
-       sp = sdrc_init_params;
+       sp0 = sdrc_init_params_cs0;
+       sp1 = sdrc_init_params_cs1;
 
-       while (sp->rate && sp->rate != r)
-               sp++;
+       while (sp0->rate && sp0->rate != r) {
+               sp0++;
+               if (sdrc_init_params_cs1)
+                       sp1++;
+       }
 
-       if (!sp->rate)
-               return NULL;
+       if (!sp0->rate)
+               return -1;
 
-       return sp;
+       *sdrc_cs0 = sp0;
+       *sdrc_cs1 = sp1;
+       return 0;
 }
 
 
@@ -83,13 +99,15 @@ void __init omap2_set_globals_sdrc(struct omap_globals *omap2_globals)
 
 /**
  * omap2_sdrc_init - initialize SMS, SDRC devices on boot
- * @sp: pointer to a null-terminated list of struct omap_sdrc_params
+ * @sdrc_cs[01]: pointers to a null-terminated list of struct omap_sdrc_params
+ *  Support for 2 chip selects timings
  *
  * Turn on smart idle modes for SDRAM scheduler and controller.
  * Program a known-good configuration for the SDRC to deal with buggy
  * bootloaders.
  */
-void __init omap2_sdrc_init(struct omap_sdrc_params *sp)
+void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
+                           struct omap_sdrc_params *sdrc_cs1)
 {
        u32 l;
 
@@ -103,11 +121,15 @@ void __init omap2_sdrc_init(struct omap_sdrc_params *sp)
        l |= (0x2 << 3);
        sdrc_write_reg(l, SDRC_SYSCONFIG);
 
-       sdrc_init_params = sp;
+       sdrc_init_params_cs0 = sdrc_cs0;
+       sdrc_init_params_cs1 = sdrc_cs1;
 
        /* XXX Enable SRFRONIDLEREQ here also? */
+       /*
+        * PWDENA should not be set due to 34xx erratum 1.150 - PWDENA
+        * can cause random memory corruption
+        */
        l = (1 << SDRC_POWER_EXTCLKDIS_SHIFT) |
-               (1 << SDRC_POWER_PWDENA_SHIFT) |
                (1 << SDRC_POWER_PAGEPOLICY_SHIFT);
        sdrc_write_reg(l, SDRC_POWER);
 }
index b094c15bfe471d6ccc47073d891bd4459b432c1a..a7421a50410bc16a23126439071c73f51b35474e 100644 (file)
@@ -54,6 +54,7 @@ struct omap_uart_state {
 
        struct plat_serial8250_port *p;
        struct list_head node;
+       struct platform_device pdev;
 
 #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
        int context_valid;
@@ -68,10 +69,9 @@ struct omap_uart_state {
 #endif
 };
 
-static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS];
 static LIST_HEAD(uart_list);
 
-static struct plat_serial8250_port serial_platform_data[] = {
+static struct plat_serial8250_port serial_platform_data0[] = {
        {
                .membase        = IO_ADDRESS(OMAP_UART1_BASE),
                .mapbase        = OMAP_UART1_BASE,
@@ -81,6 +81,12 @@ static struct plat_serial8250_port serial_platform_data[] = {
                .regshift       = 2,
                .uartclk        = OMAP24XX_BASE_BAUD * 16,
        }, {
+               .flags          = 0
+       }
+};
+
+static struct plat_serial8250_port serial_platform_data1[] = {
+       {
                .membase        = IO_ADDRESS(OMAP_UART2_BASE),
                .mapbase        = OMAP_UART2_BASE,
                .irq            = 73,
@@ -89,6 +95,12 @@ static struct plat_serial8250_port serial_platform_data[] = {
                .regshift       = 2,
                .uartclk        = OMAP24XX_BASE_BAUD * 16,
        }, {
+               .flags          = 0
+       }
+};
+
+static struct plat_serial8250_port serial_platform_data2[] = {
+       {
                .membase        = IO_ADDRESS(OMAP_UART3_BASE),
                .mapbase        = OMAP_UART3_BASE,
                .irq            = 74,
@@ -217,6 +229,40 @@ static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
        clk_disable(uart->fck);
 }
 
+static void omap_uart_enable_wakeup(struct omap_uart_state *uart)
+{
+       /* Set wake-enable bit */
+       if (uart->wk_en && uart->wk_mask) {
+               u32 v = __raw_readl(uart->wk_en);
+               v |= uart->wk_mask;
+               __raw_writel(v, uart->wk_en);
+       }
+
+       /* Ensure IOPAD wake-enables are set */
+       if (cpu_is_omap34xx() && uart->padconf) {
+               u16 v = omap_ctrl_readw(uart->padconf);
+               v |= OMAP3_PADCONF_WAKEUPENABLE0;
+               omap_ctrl_writew(v, uart->padconf);
+       }
+}
+
+static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
+{
+       /* Clear wake-enable bit */
+       if (uart->wk_en && uart->wk_mask) {
+               u32 v = __raw_readl(uart->wk_en);
+               v &= ~uart->wk_mask;
+               __raw_writel(v, uart->wk_en);
+       }
+
+       /* Ensure IOPAD wake-enables are cleared */
+       if (cpu_is_omap34xx() && uart->padconf) {
+               u16 v = omap_ctrl_readw(uart->padconf);
+               v &= ~OMAP3_PADCONF_WAKEUPENABLE0;
+               omap_ctrl_writew(v, uart->padconf);
+       }
+}
+
 static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
                                          int enable)
 {
@@ -246,6 +292,11 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart)
 
 static void omap_uart_allow_sleep(struct omap_uart_state *uart)
 {
+       if (device_may_wakeup(&uart->pdev.dev))
+               omap_uart_enable_wakeup(uart);
+       else
+               omap_uart_disable_wakeup(uart);
+
        if (!uart->clocked)
                return;
 
@@ -292,7 +343,6 @@ void omap_uart_resume_idle(int num)
                        /* Check for normal UART wakeup */
                        if (__raw_readl(uart->wk_st) & uart->wk_mask)
                                omap_uart_block_sleep(uart);
-
                        return;
                }
        }
@@ -346,16 +396,13 @@ static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
        return IRQ_NONE;
 }
 
-static u32 sleep_timeout = DEFAULT_TIMEOUT;
-
 static void omap_uart_idle_init(struct omap_uart_state *uart)
 {
-       u32 v;
        struct plat_serial8250_port *p = uart->p;
        int ret;
 
        uart->can_sleep = 0;
-       uart->timeout = sleep_timeout;
+       uart->timeout = DEFAULT_TIMEOUT;
        setup_timer(&uart->timer, omap_uart_idle_timer,
                    (unsigned long) uart);
        mod_timer(&uart->timer, jiffies + uart->timeout);
@@ -413,76 +460,101 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
                uart->padconf = 0;
        }
 
-       /* Set wake-enable bit */
-       if (uart->wk_en && uart->wk_mask) {
-               v = __raw_readl(uart->wk_en);
-               v |= uart->wk_mask;
-               __raw_writel(v, uart->wk_en);
-       }
-
-       /* Ensure IOPAD wake-enables are set */
-       if (cpu_is_omap34xx() && uart->padconf) {
-               u16 v;
-
-               v = omap_ctrl_readw(uart->padconf);
-               v |= OMAP3_PADCONF_WAKEUPENABLE0;
-               omap_ctrl_writew(v, uart->padconf);
-       }
-
        p->flags |= UPF_SHARE_IRQ;
        ret = request_irq(p->irq, omap_uart_interrupt, IRQF_SHARED,
                          "serial idle", (void *)uart);
        WARN_ON(ret);
 }
 
-static ssize_t sleep_timeout_show(struct kobject *kobj,
-                                 struct kobj_attribute *attr,
+void omap_uart_enable_irqs(int enable)
+{
+       int ret;
+       struct omap_uart_state *uart;
+
+       list_for_each_entry(uart, &uart_list, node) {
+               if (enable)
+                       ret = request_irq(uart->p->irq, omap_uart_interrupt,
+                               IRQF_SHARED, "serial idle", (void *)uart);
+               else
+                       free_irq(uart->p->irq, (void *)uart);
+       }
+}
+
+static ssize_t sleep_timeout_show(struct device *dev,
+                                 struct device_attribute *attr,
                                  char *buf)
 {
-       return sprintf(buf, "%u\n", sleep_timeout / HZ);
+       struct platform_device *pdev = container_of(dev,
+                                       struct platform_device, dev);
+       struct omap_uart_state *uart = container_of(pdev,
+                                       struct omap_uart_state, pdev);
+
+       return sprintf(buf, "%u\n", uart->timeout / HZ);
 }
 
-static ssize_t sleep_timeout_store(struct kobject *kobj,
-                                  struct kobj_attribute *attr,
+static ssize_t sleep_timeout_store(struct device *dev,
+                                  struct device_attribute *attr,
                                   const char *buf, size_t n)
 {
-       struct omap_uart_state *uart;
+       struct platform_device *pdev = container_of(dev,
+                                       struct platform_device, dev);
+       struct omap_uart_state *uart = container_of(pdev,
+                                       struct omap_uart_state, pdev);
        unsigned int value;
 
        if (sscanf(buf, "%u", &value) != 1) {
                printk(KERN_ERR "sleep_timeout_store: Invalid value\n");
                return -EINVAL;
        }
-       sleep_timeout = value * HZ;
-       list_for_each_entry(uart, &uart_list, node) {
-               uart->timeout = sleep_timeout;
-               if (uart->timeout)
-                       mod_timer(&uart->timer, jiffies + uart->timeout);
-               else
-                       /* A zero value means disable timeout feature */
-                       omap_uart_block_sleep(uart);
-       }
+
+       uart->timeout = value * HZ;
+       if (uart->timeout)
+               mod_timer(&uart->timer, jiffies + uart->timeout);
+       else
+               /* A zero value means disable timeout feature */
+               omap_uart_block_sleep(uart);
+
        return n;
 }
 
-static struct kobj_attribute sleep_timeout_attr =
-       __ATTR(sleep_timeout, 0644, sleep_timeout_show, sleep_timeout_store);
-
+DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show, sleep_timeout_store);
+#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr))
 #else
 static inline void omap_uart_idle_init(struct omap_uart_state *uart) {}
+#define DEV_CREATE_FILE(dev, attr)
 #endif /* CONFIG_PM */
 
-static struct platform_device serial_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_PLATFORM,
-       .dev                    = {
-               .platform_data  = serial_platform_data,
+static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS] = {
+       {
+               .pdev = {
+                       .name                   = "serial8250",
+                       .id                     = PLAT8250_DEV_PLATFORM,
+                       .dev                    = {
+                               .platform_data  = serial_platform_data0,
+                       },
+               },
+       }, {
+               .pdev = {
+                       .name                   = "serial8250",
+                       .id                     = PLAT8250_DEV_PLATFORM1,
+                       .dev                    = {
+                               .platform_data  = serial_platform_data1,
+                       },
+               },
+       }, {
+               .pdev = {
+                       .name                   = "serial8250",
+                       .id                     = PLAT8250_DEV_PLATFORM2,
+                       .dev                    = {
+                               .platform_data  = serial_platform_data2,
+                       },
+               },
        },
 };
 
 void __init omap_serial_init(void)
 {
-       int i, err;
+       int i;
        const struct omap_uart_config *info;
        char name[16];
 
@@ -496,14 +568,12 @@ void __init omap_serial_init(void)
 
        if (info == NULL)
                return;
-       if (cpu_is_omap44xx()) {
-               for (i = 0; i < OMAP_MAX_NR_PORTS; i++)
-                       serial_platform_data[i].irq += 32;
-       }
 
        for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
-               struct plat_serial8250_port *p = serial_platform_data + i;
                struct omap_uart_state *uart = &omap_uart[i];
+               struct platform_device *pdev = &uart->pdev;
+               struct device *dev = &pdev->dev;
+               struct plat_serial8250_port *p = dev->platform_data;
 
                if (!(info->enabled_uarts & (1 << i))) {
                        p->membase = NULL;
@@ -531,20 +601,21 @@ void __init omap_serial_init(void)
                uart->num = i;
                p->private_data = uart;
                uart->p = p;
-               list_add(&uart->node, &uart_list);
+               list_add_tail(&uart->node, &uart_list);
+
+               if (cpu_is_omap44xx())
+                       p->irq += 32;
 
                omap_uart_enable_clocks(uart);
                omap_uart_reset(uart);
                omap_uart_idle_init(uart);
-       }
-
-       err = platform_device_register(&serial_device);
-
-#ifdef CONFIG_PM
-       if (!err)
-               err = sysfs_create_file(&serial_device.dev.kobj,
-                                       &sleep_timeout_attr.attr);
-#endif
 
+               if (WARN_ON(platform_device_register(pdev)))
+                       continue;
+               if ((cpu_is_omap34xx() && uart->padconf) ||
+                   (uart->wk_en && uart->wk_mask)) {
+                       device_init_wakeup(dev, true);
+                       DEV_CREATE_FILE(dev, &dev_attr_sleep_timeout);
+               }
+       }
 }
-
index f41f8d96ddba55df420943a6ed8b6561db842342..82aa4a3d160ce917b8b85ce0959b3a5d093968ed 100644 (file)
@@ -36,7 +36,7 @@
 
        .text
 
-/* r4 parameters */
+/* r1 parameters */
 #define SDRC_NO_UNLOCK_DLL             0x0
 #define SDRC_UNLOCK_DLL                        0x1
 
@@ -58,7 +58,6 @@
 
 /* SDRC_POWER bit settings */
 #define SRFRONIDLEREQ_MASK             0x40
-#define PWDENA_MASK                    0x4
 
 /* CM_IDLEST1_CORE bit settings */
 #define ST_SDRC_MASK                   0x2
 
 /*
  * omap3_sram_configure_core_dpll - change DPLL3 M2 divider
- * r0 = new SDRC_RFR_CTRL register contents
- * r1 = new SDRC_ACTIM_CTRLA register contents
- * r2 = new SDRC_ACTIM_CTRLB register contents
- * r3 = new M2 divider setting (only 1 and 2 supported right now)
- * r4 = unlock SDRC DLL? (1 = yes, 0 = no).  Only unlock DLL for
+ *
+ * Params passed in registers:
+ *  r0 = new M2 divider setting (only 1 and 2 supported right now)
+ *  r1 = unlock SDRC DLL? (1 = yes, 0 = no).  Only unlock DLL for
  *      SDRC rates < 83MHz
- * r5 = number of MPU cycles to wait for SDRC to stabilize after
+ *  r2 = number of MPU cycles to wait for SDRC to stabilize after
  *      reprogramming the SDRC when switching to a slower MPU speed
- * r6 = new SDRC_MR_0 register value
- * r7 = increasing SDRC rate? (1 = yes, 0 = no)
+ *  r3 = increasing SDRC rate? (1 = yes, 0 = no)
+ *
+ * Params passed via the stack. The needed params will be copied in SRAM
+ *  before use by the code in SRAM (SDRAM is not accessible during SDRC
+ *  reconfiguration):
+ *  new SDRC_RFR_CTRL_0 register contents
+ *  new SDRC_ACTIM_CTRL_A_0 register contents
+ *  new SDRC_ACTIM_CTRL_B_0 register contents
+ *  new SDRC_MR_0 register value
+ *  new SDRC_RFR_CTRL_1 register contents
+ *  new SDRC_ACTIM_CTRL_A_1 register contents
+ *  new SDRC_ACTIM_CTRL_B_1 register contents
+ *  new SDRC_MR_1 register value
  *
+ * If the param SDRC_RFR_CTRL_1 is 0, the parameters
+ *  are not programmed into the SDRC CS1 registers
  */
 ENTRY(omap3_sram_configure_core_dpll)
        stmfd   sp!, {r1-r12, lr}       @ store regs to stack
-       ldr     r4, [sp, #52]           @ pull extra args off the stack
-       ldr     r5, [sp, #56]           @ load extra args from the stack
-       ldr     r6, [sp, #60]           @ load extra args from the stack
-       ldr     r7, [sp, #64]           @ load extra args from the stack
+
+                                       @ pull the extra args off the stack
+                                       @  and store them in SRAM
+       ldr     r4, [sp, #52]
+       str     r4, omap_sdrc_rfr_ctrl_0_val
+       ldr     r4, [sp, #56]
+       str     r4, omap_sdrc_actim_ctrl_a_0_val
+       ldr     r4, [sp, #60]
+       str     r4, omap_sdrc_actim_ctrl_b_0_val
+       ldr     r4, [sp, #64]
+       str     r4, omap_sdrc_mr_0_val
+       ldr     r4, [sp, #68]
+       str     r4, omap_sdrc_rfr_ctrl_1_val
+       cmp     r4, #0                  @ if SDRC_RFR_CTRL_1 is 0,
+       beq     skip_cs1_params         @  do not use cs1 params
+       ldr     r4, [sp, #72]
+       str     r4, omap_sdrc_actim_ctrl_a_1_val
+       ldr     r4, [sp, #76]
+       str     r4, omap_sdrc_actim_ctrl_b_1_val
+       ldr     r4, [sp, #80]
+       str     r4, omap_sdrc_mr_1_val
+skip_cs1_params:
        dsb                             @ flush buffered writes to interconnect
-       cmp     r7, #1                  @ if increasing SDRC clk rate,
+
+       cmp     r3, #1                  @ if increasing SDRC clk rate,
        bleq    configure_sdrc          @ program the SDRC regs early (for RFR)
-       cmp     r4, #SDRC_UNLOCK_DLL    @ set the intended DLL state
+       cmp     r1, #SDRC_UNLOCK_DLL    @ set the intended DLL state
        bleq    unlock_dll
        blne    lock_dll
        bl      sdram_in_selfrefresh    @ put SDRAM in self refresh, idle SDRC
        bl      configure_core_dpll     @ change the DPLL3 M2 divider
+       mov     r12, r2
+       bl      wait_clk_stable         @ wait for SDRC to stabilize
        bl      enable_sdrc             @ take SDRC out of idle
-       cmp     r4, #SDRC_UNLOCK_DLL    @ wait for DLL status to change
+       cmp     r1, #SDRC_UNLOCK_DLL    @ wait for DLL status to change
        bleq    wait_dll_unlock
        blne    wait_dll_lock
-       cmp     r7, #1                  @ if increasing SDRC clk rate,
+       cmp     r3, #1                  @ if increasing SDRC clk rate,
        beq     return_to_sdram         @ return to SDRAM code, otherwise,
        bl      configure_sdrc          @ reprogram SDRC regs now
-       mov     r12, r5
-       bl      wait_clk_stable         @ wait for SDRC to stabilize
 return_to_sdram:
        isb                             @ prevent speculative exec past here
        mov     r0, #0                  @ return value
@@ -113,7 +143,7 @@ return_to_sdram:
 unlock_dll:
        ldr     r11, omap3_sdrc_dlla_ctrl
        ldr     r12, [r11]
-       and     r12, r12, #FIXEDDELAY_MASK
+       bic     r12, r12, #FIXEDDELAY_MASK
        orr     r12, r12, #FIXEDDELAY_DEFAULT
        orr     r12, r12, #DLLIDLE_MASK
        str     r12, [r11]              @ (no OCP barrier needed)
@@ -129,7 +159,6 @@ sdram_in_selfrefresh:
        ldr     r12, [r11]              @ read the contents of SDRC_POWER
        mov     r9, r12                 @ keep a copy of SDRC_POWER bits
        orr     r12, r12, #SRFRONIDLEREQ_MASK   @ enable self refresh on idle
-       bic     r12, r12, #PWDENA_MASK  @ clear PWDENA
        str     r12, [r11]              @ write back to SDRC_POWER register
        ldr     r12, [r11]              @ posted-write barrier for SDRC
 idle_sdrc:
@@ -149,7 +178,7 @@ configure_core_dpll:
        ldr     r12, [r11]
        ldr     r10, core_m2_mask_val   @ modify m2 for core dpll
        and     r12, r12, r10
-       orr     r12, r12, r3, lsl #CORE_DPLL_CLKOUT_DIV_SHIFT
+       orr     r12, r12, r0, lsl #CORE_DPLL_CLKOUT_DIV_SHIFT
        str     r12, [r11]
        ldr     r12, [r11]              @ posted-write barrier for CM
        bx      lr
@@ -187,15 +216,34 @@ wait_dll_unlock:
        bne     wait_dll_unlock
        bx      lr
 configure_sdrc:
-       ldr     r11, omap3_sdrc_rfr_ctrl
-       str     r0, [r11]
-       ldr     r11, omap3_sdrc_actim_ctrla
-       str     r1, [r11]
-       ldr     r11, omap3_sdrc_actim_ctrlb
-       str     r2, [r11]
+       ldr     r12, omap_sdrc_rfr_ctrl_0_val   @ fetch value from SRAM
+       ldr     r11, omap3_sdrc_rfr_ctrl_0      @ fetch addr from SRAM
+       str     r12, [r11]                      @ store
+       ldr     r12, omap_sdrc_actim_ctrl_a_0_val
+       ldr     r11, omap3_sdrc_actim_ctrl_a_0
+       str     r12, [r11]
+       ldr     r12, omap_sdrc_actim_ctrl_b_0_val
+       ldr     r11, omap3_sdrc_actim_ctrl_b_0
+       str     r12, [r11]
+       ldr     r12, omap_sdrc_mr_0_val
        ldr     r11, omap3_sdrc_mr_0
-       str     r6, [r11]
-       ldr     r6, [r11]               @ posted-write barrier for SDRC
+       str     r12, [r11]
+       ldr     r12, omap_sdrc_rfr_ctrl_1_val
+       cmp     r12, #0                 @ if SDRC_RFR_CTRL_1 is 0,
+       beq     skip_cs1_prog           @  do not program cs1 params
+       ldr     r11, omap3_sdrc_rfr_ctrl_1
+       str     r12, [r11]
+       ldr     r12, omap_sdrc_actim_ctrl_a_1_val
+       ldr     r11, omap3_sdrc_actim_ctrl_a_1
+       str     r12, [r11]
+       ldr     r12, omap_sdrc_actim_ctrl_b_1_val
+       ldr     r11, omap3_sdrc_actim_ctrl_b_1
+       str     r12, [r11]
+       ldr     r12, omap_sdrc_mr_1_val
+       ldr     r11, omap3_sdrc_mr_1
+       str     r12, [r11]
+skip_cs1_prog:
+       ldr     r12, [r11]              @ posted-write barrier for SDRC
        bx      lr
 
 omap3_sdrc_power:
@@ -206,14 +254,40 @@ omap3_cm_idlest1_core:
        .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_IDLEST)
 omap3_cm_iclken1_core:
        .word OMAP34XX_CM_REGADDR(CORE_MOD, CM_ICLKEN1)
-omap3_sdrc_rfr_ctrl:
+
+omap3_sdrc_rfr_ctrl_0:
        .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_0)
-omap3_sdrc_actim_ctrla:
+omap3_sdrc_rfr_ctrl_1:
+       .word OMAP34XX_SDRC_REGADDR(SDRC_RFR_CTRL_1)
+omap3_sdrc_actim_ctrl_a_0:
        .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_0)
-omap3_sdrc_actim_ctrlb:
+omap3_sdrc_actim_ctrl_a_1:
+       .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_A_1)
+omap3_sdrc_actim_ctrl_b_0:
        .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_0)
+omap3_sdrc_actim_ctrl_b_1:
+       .word OMAP34XX_SDRC_REGADDR(SDRC_ACTIM_CTRL_B_1)
 omap3_sdrc_mr_0:
        .word OMAP34XX_SDRC_REGADDR(SDRC_MR_0)
+omap3_sdrc_mr_1:
+       .word OMAP34XX_SDRC_REGADDR(SDRC_MR_1)
+omap_sdrc_rfr_ctrl_0_val:
+       .word 0xDEADBEEF
+omap_sdrc_rfr_ctrl_1_val:
+       .word 0xDEADBEEF
+omap_sdrc_actim_ctrl_a_0_val:
+       .word 0xDEADBEEF
+omap_sdrc_actim_ctrl_a_1_val:
+       .word 0xDEADBEEF
+omap_sdrc_actim_ctrl_b_0_val:
+       .word 0xDEADBEEF
+omap_sdrc_actim_ctrl_b_1_val:
+       .word 0xDEADBEEF
+omap_sdrc_mr_0_val:
+       .word 0xDEADBEEF
+omap_sdrc_mr_1_val:
+       .word 0xDEADBEEF
+
 omap3_sdrc_dlla_status:
        .word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
 omap3_sdrc_dlla_ctrl:
@@ -223,3 +297,4 @@ core_m2_mask_val:
 
 ENTRY(omap3_sram_configure_core_dpll_sz)
        .word   . - omap3_sram_configure_core_dpll
+
index 7936085dd75881c3faca30adcbede5a8ba60db56..2e9b8ccd8ec2e6d8cccc347231cc00293de22619 100644 (file)
@@ -510,7 +510,7 @@ static struct db_chip db_chips[] __initdata = {
        }
 };
 
-static void u300_init_check_chip(void)
+static void __init u300_init_check_chip(void)
 {
 
        u16 val;
index 8277802ec85926abe0e3bd7ad6dd10fb83e987d4..3a7279c1ce5e7eb5ed857f6d7bf442920c12860c 100644 (file)
@@ -120,6 +120,32 @@ void show_mem(void)
        printk("%d pages swap cached\n", cached);
 }
 
+static void __init find_node_limits(int node, struct meminfo *mi,
+       unsigned long *min, unsigned long *max_low, unsigned long *max_high)
+{
+       int i;
+
+       *min = -1UL;
+       *max_low = *max_high = 0;
+
+       for_each_nodebank(i, mi, node) {
+               struct membank *bank = &mi->bank[i];
+               unsigned long start, end;
+
+               start = bank_pfn_start(bank);
+               end = bank_pfn_end(bank);
+
+               if (*min > start)
+                       *min = start;
+               if (*max_high < end)
+                       *max_high = end;
+               if (bank->highmem)
+                       continue;
+               if (*max_low < end)
+                       *max_low = end;
+       }
+}
+
 /*
  * FIXME: We really want to avoid allocating the bootmap bitmap
  * over the top of the initrd.  Hopefully, this is located towards
@@ -210,40 +236,24 @@ static inline void map_memory_bank(struct membank *bank)
 #endif
 }
 
-static unsigned long __init bootmem_init_node(int node, struct meminfo *mi)
+static void __init bootmem_init_node(int node, struct meminfo *mi,
+       unsigned long start_pfn, unsigned long end_pfn)
 {
-       unsigned long start_pfn, end_pfn, boot_pfn;
+       unsigned long boot_pfn;
        unsigned int boot_pages;
        pg_data_t *pgdat;
        int i;
 
-       start_pfn = -1UL;
-       end_pfn = 0;
-
        /*
-        * Calculate the pfn range, and map the memory banks for this node.
+        * Map the memory banks for this node.
         */
        for_each_nodebank(i, mi, node) {
                struct membank *bank = &mi->bank[i];
-               unsigned long start, end;
 
-               start = bank_pfn_start(bank);
-               end = bank_pfn_end(bank);
-
-               if (start_pfn > start)
-                       start_pfn = start;
-               if (end_pfn < end)
-                       end_pfn = end;
-
-               map_memory_bank(bank);
+               if (!bank->highmem)
+                       map_memory_bank(bank);
        }
 
-       /*
-        * If there is no memory in this node, ignore it.
-        */
-       if (end_pfn == 0)
-               return end_pfn;
-
        /*
         * Allocate the bootmem bitmap page.
         */
@@ -260,7 +270,8 @@ static unsigned long __init bootmem_init_node(int node, struct meminfo *mi)
 
        for_each_nodebank(i, mi, node) {
                struct membank *bank = &mi->bank[i];
-               free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank));
+               if (!bank->highmem)
+                       free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank));
                memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
        }
 
@@ -269,8 +280,6 @@ static unsigned long __init bootmem_init_node(int node, struct meminfo *mi)
         */
        reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
                             boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
-
-       return end_pfn;
 }
 
 static void __init bootmem_reserve_initrd(int node)
@@ -297,33 +306,39 @@ static void __init bootmem_reserve_initrd(int node)
 static void __init bootmem_free_node(int node, struct meminfo *mi)
 {
        unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
-       unsigned long start_pfn, end_pfn;
-       pg_data_t *pgdat = NODE_DATA(node);
+       unsigned long min, max_low, max_high;
        int i;
 
-       start_pfn = pgdat->bdata->node_min_pfn;
-       end_pfn = pgdat->bdata->node_low_pfn;
+       find_node_limits(node, mi, &min, &max_low, &max_high);
 
        /*
         * initialise the zones within this node.
         */
        memset(zone_size, 0, sizeof(zone_size));
-       memset(zhole_size, 0, sizeof(zhole_size));
 
        /*
         * The size of this node has already been determined.  If we need
         * to do anything fancy with the allocation of this memory to the
         * zones, now is the time to do it.
         */
-       zone_size[0] = end_pfn - start_pfn;
+       zone_size[0] = max_low - min;
+#ifdef CONFIG_HIGHMEM
+       zone_size[ZONE_HIGHMEM] = max_high - max_low;
+#endif
 
        /*
         * For each bank in this node, calculate the size of the holes.
         *  holes = node_size - sum(bank_sizes_in_node)
         */
-       zhole_size[0] = zone_size[0];
-       for_each_nodebank(i, mi, node)
-               zhole_size[0] -= bank_pfn_size(&mi->bank[i]);
+       memcpy(zhole_size, zone_size, sizeof(zhole_size));
+       for_each_nodebank(i, mi, node) {
+               int idx = 0;
+#ifdef CONFIG_HIGHMEM
+               if (mi->bank[i].highmem)
+                       idx = ZONE_HIGHMEM;
+#endif
+               zhole_size[idx] -= bank_pfn_size(&mi->bank[i]);
+       }
 
        /*
         * Adjust the sizes according to any special requirements for
@@ -331,13 +346,13 @@ static void __init bootmem_free_node(int node, struct meminfo *mi)
         */
        arch_adjust_zones(node, zone_size, zhole_size);
 
-       free_area_init_node(node, zone_size, start_pfn, zhole_size);
+       free_area_init_node(node, zone_size, min, zhole_size);
 }
 
 void __init bootmem_init(void)
 {
        struct meminfo *mi = &meminfo;
-       unsigned long memend_pfn = 0;
+       unsigned long min, max_low, max_high;
        int node, initrd_node;
 
        /*
@@ -345,11 +360,29 @@ void __init bootmem_init(void)
         */
        initrd_node = check_initrd(mi);
 
+       max_low = max_high = 0;
+
        /*
         * Run through each node initialising the bootmem allocator.
         */
        for_each_node(node) {
-               unsigned long end_pfn = bootmem_init_node(node, mi);
+               unsigned long node_low, node_high;
+
+               find_node_limits(node, mi, &min, &node_low, &node_high);
+
+               if (node_low > max_low)
+                       max_low = node_low;
+               if (node_high > max_high)
+                       max_high = node_high;
+
+               /*
+                * If there is no memory in this node, ignore it.
+                * (We can't have nodes which have no lowmem)
+                */
+               if (node_low == 0)
+                       continue;
+
+               bootmem_init_node(node, mi, min, node_low);
 
                /*
                 * Reserve any special node zero regions.
@@ -362,12 +395,6 @@ void __init bootmem_init(void)
                 */
                if (node == initrd_node)
                        bootmem_reserve_initrd(node);
-
-               /*
-                * Remember the highest memory PFN.
-                */
-               if (end_pfn > memend_pfn)
-                       memend_pfn = end_pfn;
        }
 
        /*
@@ -383,7 +410,7 @@ void __init bootmem_init(void)
        for_each_node(node)
                bootmem_free_node(node, mi);
 
-       high_memory = __va((memend_pfn << PAGE_SHIFT) - 1) + 1;
+       high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1;
 
        /*
         * This doesn't seem to be used by the Linux memory manager any
@@ -393,7 +420,8 @@ void __init bootmem_init(void)
         * Note: max_low_pfn and max_pfn reflect the number of _pages_ in
         * the system, not the maximum PFN.
         */
-       max_pfn = max_low_pfn = memend_pfn - PHYS_PFN_OFFSET;
+       max_low_pfn = max_low - PHYS_PFN_OFFSET;
+       max_pfn = max_high - PHYS_PFN_OFFSET;
 }
 
 static inline int free_area(unsigned long pfn, unsigned long end, char *s)
index 4722582b17b82f526feef2d2f439bef26a98e946..4426ee67ceca5d3d74c9b0dbe0f39c5b7e2b8538 100644 (file)
@@ -687,13 +687,19 @@ __early_param("vmalloc=", early_vmalloc);
 
 static void __init sanity_check_meminfo(void)
 {
-       int i, j;
+       int i, j, highmem = 0;
 
        for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
                struct membank *bank = &meminfo.bank[j];
                *bank = meminfo.bank[i];
 
 #ifdef CONFIG_HIGHMEM
+               if (__va(bank->start) > VMALLOC_MIN ||
+                   __va(bank->start) < (void *)PAGE_OFFSET)
+                       highmem = 1;
+
+               bank->highmem = highmem;
+
                /*
                 * Split those memory banks which are partially overlapping
                 * the vmalloc area greatly simplifying things later.
@@ -714,6 +720,7 @@ static void __init sanity_check_meminfo(void)
                                i++;
                                bank[1].size -= VMALLOC_MIN - __va(bank->start);
                                bank[1].start = __pa(VMALLOC_MIN - 1) + 1;
+                               bank[1].highmem = highmem = 1;
                                j++;
                        }
                        bank->size = VMALLOC_MIN - __va(bank->start);
index 843e8af640660bcd24b62aaef2de2c121ca3633b..1868c0d8f9b5c9a6db2fbdc263a1fa4570c4e656 100644 (file)
@@ -78,10 +78,10 @@ static int omap_target(struct cpufreq_policy *policy,
 
        /* Ensure desired rate is within allowed range.  Some govenors
         * (ondemand) will just pass target_freq=0 to get the minimum. */
-       if (target_freq < policy->cpuinfo.min_freq)
-               target_freq = policy->cpuinfo.min_freq;
-       if (target_freq > policy->cpuinfo.max_freq)
-               target_freq = policy->cpuinfo.max_freq;
+       if (target_freq < policy->min)
+               target_freq = policy->min;
+       if (target_freq > policy->max)
+               target_freq = policy->max;
 
        freqs.old = omap_getspeed(0);
        freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
index 7677a4a1cef26f0df05e5db328cf7134bd27e0ee..e3ac94f0900670b50d7ef2aa9c2a49755811a28a 100644 (file)
@@ -946,7 +946,9 @@ void omap_start_dma(int lch)
 
                        cur_lch = next_lch;
                } while (next_lch != -1);
-       } else if (cpu_class_is_omap2()) {
+       } else if (cpu_is_omap242x() ||
+               (cpu_is_omap243x() &&  omap_type() <= OMAP2430_REV_ES1_0)) {
+
                /* Errata: Need to write lch even if not using chaining */
                dma_write(lch, CLNK_CTRL(lch));
        }
index 26b387c1242393e9bd5450a6751d1ed9a2f3e54c..9298bc0ab171ff6150bfb1f36f07285b4f956575 100644 (file)
@@ -476,14 +476,12 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
        __raw_writel(l, reg);
 }
 
-static int __omap_get_gpio_datain(int gpio)
+static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
 {
-       struct gpio_bank *bank;
        void __iomem *reg;
 
        if (check_gpio(gpio) < 0)
                return -EINVAL;
-       bank = get_gpio_bank(gpio);
        reg = bank->base;
        switch (bank->method) {
 #ifdef CONFIG_ARCH_OMAP1
@@ -524,6 +522,53 @@ static int __omap_get_gpio_datain(int gpio)
                        & (1 << get_gpio_index(gpio))) != 0;
 }
 
+static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
+{
+       void __iomem *reg;
+
+       if (check_gpio(gpio) < 0)
+               return -EINVAL;
+       reg = bank->base;
+
+       switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+       case METHOD_MPUIO:
+               reg += OMAP_MPUIO_OUTPUT;
+               break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+       case METHOD_GPIO_1510:
+               reg += OMAP1510_GPIO_DATA_OUTPUT;
+               break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+       case METHOD_GPIO_1610:
+               reg += OMAP1610_GPIO_DATAOUT;
+               break;
+#endif
+#ifdef CONFIG_ARCH_OMAP730
+       case METHOD_GPIO_730:
+               reg += OMAP730_GPIO_DATA_OUTPUT;
+               break;
+#endif
+#ifdef CONFIG_ARCH_OMAP850
+       case METHOD_GPIO_850:
+               reg += OMAP850_GPIO_DATA_OUTPUT;
+               break;
+#endif
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \
+               defined(CONFIG_ARCH_OMAP4)
+       case METHOD_GPIO_24XX:
+               reg += OMAP24XX_GPIO_DATAOUT;
+               break;
+#endif
+       default:
+               return -EINVAL;
+       }
+
+       return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
+}
+
 #define MOD_REG_BIT(reg, bit_mask, set)        \
 do {   \
        int l = __raw_readl(base + reg); \
@@ -1189,6 +1234,7 @@ static void gpio_mask_irq(unsigned int irq)
        struct gpio_bank *bank = get_irq_chip_data(irq);
 
        _set_gpio_irqenable(bank, gpio, 0);
+       _set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
 }
 
 static void gpio_unmask_irq(unsigned int irq)
@@ -1196,6 +1242,11 @@ static void gpio_unmask_irq(unsigned int irq)
        unsigned int gpio = irq - IH_GPIO_BASE;
        struct gpio_bank *bank = get_irq_chip_data(irq);
        unsigned int irq_mask = 1 << get_gpio_index(gpio);
+       struct irq_desc *desc = irq_to_desc(irq);
+       u32 trigger = desc->status & IRQ_TYPE_SENSE_MASK;
+
+       if (trigger)
+               _set_gpio_triggering(bank, get_gpio_index(gpio), trigger);
 
        /* For level-triggered GPIOs, the clearing must be done after
         * the HW source is cleared, thus after the handler has run */
@@ -1350,9 +1401,49 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset)
        return 0;
 }
 
+static int gpio_is_input(struct gpio_bank *bank, int mask)
+{
+       void __iomem *reg = bank->base;
+
+       switch (bank->method) {
+       case METHOD_MPUIO:
+               reg += OMAP_MPUIO_IO_CNTL;
+               break;
+       case METHOD_GPIO_1510:
+               reg += OMAP1510_GPIO_DIR_CONTROL;
+               break;
+       case METHOD_GPIO_1610:
+               reg += OMAP1610_GPIO_DIRECTION;
+               break;
+       case METHOD_GPIO_730:
+               reg += OMAP730_GPIO_DIR_CONTROL;
+               break;
+       case METHOD_GPIO_850:
+               reg += OMAP850_GPIO_DIR_CONTROL;
+               break;
+       case METHOD_GPIO_24XX:
+               reg += OMAP24XX_GPIO_OE;
+               break;
+       }
+       return __raw_readl(reg) & mask;
+}
+
 static int gpio_get(struct gpio_chip *chip, unsigned offset)
 {
-       return __omap_get_gpio_datain(chip->base + offset);
+       struct gpio_bank *bank;
+       void __iomem *reg;
+       int gpio;
+       u32 mask;
+
+       gpio = chip->base + offset;
+       bank = get_gpio_bank(gpio);
+       reg = bank->base;
+       mask = 1 << get_gpio_index(gpio);
+
+       if (gpio_is_input(bank, mask))
+               return _get_gpio_datain(bank, gpio);
+       else
+               return _get_gpio_dataout(bank, gpio);
 }
 
 static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
@@ -1886,34 +1977,6 @@ arch_initcall(omap_gpio_sysinit);
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 
-static int gpio_is_input(struct gpio_bank *bank, int mask)
-{
-       void __iomem *reg = bank->base;
-
-       switch (bank->method) {
-       case METHOD_MPUIO:
-               reg += OMAP_MPUIO_IO_CNTL;
-               break;
-       case METHOD_GPIO_1510:
-               reg += OMAP1510_GPIO_DIR_CONTROL;
-               break;
-       case METHOD_GPIO_1610:
-               reg += OMAP1610_GPIO_DIRECTION;
-               break;
-       case METHOD_GPIO_730:
-               reg += OMAP730_GPIO_DIR_CONTROL;
-               break;
-       case METHOD_GPIO_850:
-               reg += OMAP850_GPIO_DIR_CONTROL;
-               break;
-       case METHOD_GPIO_24XX:
-               reg += OMAP24XX_GPIO_OE;
-               break;
-       }
-       return __raw_readl(reg) & mask;
-}
-
-
 static int dbg_gpio_show(struct seq_file *s, void *unused)
 {
        unsigned        i, j, gpio;
index f9f65e1ba3f13abe11d7c06d514b6581e6697016..4b8b0d65cbf20c10dfcc0b0795ed16b3bf054de9 100644 (file)
@@ -20,6 +20,8 @@ struct clockdomain;
 struct clkops {
        int                     (*enable)(struct clk *);
        void                    (*disable)(struct clk *);
+       void                    (*find_idlest)(struct clk *, void __iomem **, u8 *);
+       void                    (*find_companion)(struct clk *, void __iomem **, u8 *);
 };
 
 #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
index 285eaa3a82750bf986bb5ebe331f86b1e55177fe..11e73d9e8928458adc5656add696d835cf330d7a 100644 (file)
@@ -378,9 +378,6 @@ IS_OMAP_TYPE(3430, 0x3430)
 #define cpu_class_is_omap2()   (cpu_is_omap24xx() || cpu_is_omap34xx() || \
                                cpu_is_omap44xx())
 
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) || \
-                       defined(CONFIG_ARCH_OMAP4)
-
 /* Various silicon revisions for omap2 */
 #define OMAP242X_CLASS         0x24200024
 #define OMAP2420_REV_ES1_0     0x24200024
@@ -436,5 +433,3 @@ IS_OMAP_TYPE(3430, 0x3430)
 
 int omap_chip_is(struct omap_chip_id oci);
 void omap2_check_revision(void);
-
-#endif    /* defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) */
index 73f483d56ca6a0180ea64d896f0979cf80318419..21fb0efdda86a02f17931888bd16c1927295bb7d 100644 (file)
@@ -228,7 +228,8 @@ extern void omap1_map_common_io(void);
 extern void omap1_init_common_hw(void);
 
 extern void omap2_map_common_io(void);
-extern void omap2_init_common_hw(struct omap_sdrc_params *sp);
+extern void omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
+                                struct omap_sdrc_params *sdrc_cs1);
 
 #define __arch_ioremap(p,s,t)  omap_ioremap(p,s,t)
 #define __arch_iounmap(v)      omap_iounmap(v)
index 85a621705766eef343511478f57b3a7a9ffce671..80281c458baf26b74dee1bbcc0f516772272fd2a 100644 (file)
@@ -853,6 +853,10 @@ enum omap34xx_index {
        AE5_34XX_GPIO143,
        H19_34XX_GPIO164_OUT,
        J25_34XX_GPIO170,
+
+       /* OMAP3 SDRC CKE signals to SDR/DDR ram chips */
+       H16_34XX_SDRC_CKE0,
+       H17_34XX_SDRC_CKE1,
 };
 
 struct omap_mux_cfg {
index 24ac3c7159126eda9a7e88d00158fdc14713f704..cda2a70397b4acb3655d10364a669dda094e16d5 100644 (file)
@@ -25,6 +25,7 @@
 
 u32 omap_prcm_get_reset_sources(void);
 void omap_prcm_arch_reset(char mode);
+int omap2_cm_wait_idlest(void __iomem *reg, u32 mask, const char *name);
 
 #endif
 
index adc73522491fe03e75d7617ce94401d6c92c001b..0be18e4ff182b2902275de08d45eb44104bcd4a6 100644 (file)
 #define SDRC_ACTIM_CTRL_A_0    0x09c
 #define SDRC_ACTIM_CTRL_B_0    0x0a0
 #define SDRC_RFR_CTRL_0                0x0a4
+#define SDRC_MR_1              0x0B4
+#define SDRC_ACTIM_CTRL_A_1    0x0C4
+#define SDRC_ACTIM_CTRL_B_1    0x0C8
+#define SDRC_RFR_CTRL_1                0x0D4
 
 /*
  * These values represent the number of memory clock cycles between
@@ -102,8 +106,11 @@ struct omap_sdrc_params {
        u32 mr;
 };
 
-void __init omap2_sdrc_init(struct omap_sdrc_params *sp);
-struct omap_sdrc_params *omap2_sdrc_get_params(unsigned long r);
+void __init omap2_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
+                           struct omap_sdrc_params *sdrc_cs1);
+int omap2_sdrc_get_params(unsigned long r,
+                         struct omap_sdrc_params **sdrc_cs0,
+                         struct omap_sdrc_params **sdrc_cs1);
 
 #ifdef CONFIG_ARCH_OMAP2
 
index 13abd02d15279163291772ff129a71012d8a257e..def0529c75eb8ccc764657ee1bec2aa237ed9b62 100644 (file)
@@ -59,6 +59,7 @@ extern void omap_uart_check_wakeup(void);
 extern void omap_uart_prepare_suspend(void);
 extern void omap_uart_prepare_idle(int num);
 extern void omap_uart_resume_idle(int num);
+extern void omap_uart_enable_irqs(int enable);
 #endif
 
 #endif
index 4d53cc59d7a3b5acb34b4f4bb0a870f3d2ad6f3e..8974e3fc2691ea6d023462203a366c2b123735b1 100644 (file)
@@ -21,11 +21,12 @@ extern void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
                                      u32 mem_type);
 extern u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
 
-extern u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl,
-                                    u32 sdrc_actim_ctrla,
-                                    u32 sdrc_actim_ctrlb, u32 m2,
-                                    u32 unlock_dll, u32 f, u32 sdrc_mr,
-                                    u32 inc);
+extern u32 omap3_configure_core_dpll(
+                       u32 m2, u32 unlock_dll, u32 f, u32 inc,
+                       u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
+                       u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
+                       u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
+                       u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
 
 /* Do not use these */
 extern void omap1_sram_reprogram_clock(u32 ckctl, u32 dpllctl);
@@ -59,12 +60,12 @@ extern void omap243x_sram_reprogram_sdrc(u32 perf_level, u32 dll_val,
                                                u32 mem_type);
 extern unsigned long omap243x_sram_reprogram_sdrc_sz;
 
-
-extern u32 omap3_sram_configure_core_dpll(u32 sdrc_rfr_ctrl,
-                                         u32 sdrc_actim_ctrla,
-                                         u32 sdrc_actim_ctrlb, u32 m2,
-                                         u32 unlock_dll, u32 f, u32 sdrc_mr,
-                                         u32 inc);
+extern u32 omap3_sram_configure_core_dpll(
+                       u32 m2, u32 unlock_dll, u32 f, u32 inc,
+                       u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
+                       u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
+                       u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
+                       u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
 extern unsigned long omap3_sram_configure_core_dpll_sz;
 
 #endif
index 4ea73804d21e2ffcfbc4f5e314c9c27250e9d814..5eae7876979ce9a398b8fb93a73b69e961474287 100644 (file)
@@ -44,9 +44,9 @@
 #define OMAP2_SRAM_VA          0xe3000000
 #define OMAP2_SRAM_PUB_VA      (OMAP2_SRAM_VA + 0x800)
 #define OMAP3_SRAM_PA           0x40200000
-#define OMAP3_SRAM_VA           0xd7000000
+#define OMAP3_SRAM_VA           0xe3000000
 #define OMAP3_SRAM_PUB_PA       0x40208000
-#define OMAP3_SRAM_PUB_VA       0xd7008000
+#define OMAP3_SRAM_PUB_VA       (OMAP3_SRAM_VA + 0x8000)
 #define OMAP4_SRAM_PA          0x40200000              /*0x402f0000*/
 #define OMAP4_SRAM_VA          0xd7000000              /*0xd70f0000*/
 
@@ -373,20 +373,26 @@ static inline int omap243x_sram_init(void)
 
 #ifdef CONFIG_ARCH_OMAP3
 
-static u32 (*_omap3_sram_configure_core_dpll)(u32 sdrc_rfr_ctrl,
-                                             u32 sdrc_actim_ctrla,
-                                             u32 sdrc_actim_ctrlb,
-                                             u32 m2, u32 unlock_dll,
-                                             u32 f, u32 sdrc_mr, u32 inc);
-u32 omap3_configure_core_dpll(u32 sdrc_rfr_ctrl, u32 sdrc_actim_ctrla,
-                             u32 sdrc_actim_ctrlb, u32 m2, u32 unlock_dll,
-                             u32 f, u32 sdrc_mr, u32 inc)
+static u32 (*_omap3_sram_configure_core_dpll)(
+                       u32 m2, u32 unlock_dll, u32 f, u32 inc,
+                       u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
+                       u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
+                       u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
+                       u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1);
+
+u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc,
+                       u32 sdrc_rfr_ctrl_0, u32 sdrc_actim_ctrl_a_0,
+                       u32 sdrc_actim_ctrl_b_0, u32 sdrc_mr_0,
+                       u32 sdrc_rfr_ctrl_1, u32 sdrc_actim_ctrl_a_1,
+                       u32 sdrc_actim_ctrl_b_1, u32 sdrc_mr_1)
 {
        BUG_ON(!_omap3_sram_configure_core_dpll);
-       return _omap3_sram_configure_core_dpll(sdrc_rfr_ctrl,
-                                              sdrc_actim_ctrla,
-                                              sdrc_actim_ctrlb, m2,
-                                              unlock_dll, f, sdrc_mr, inc);
+       return _omap3_sram_configure_core_dpll(
+                       m2, unlock_dll, f, inc,
+                       sdrc_rfr_ctrl_0, sdrc_actim_ctrl_a_0,
+                       sdrc_actim_ctrl_b_0, sdrc_mr_0,
+                       sdrc_rfr_ctrl_1, sdrc_actim_ctrl_a_1,
+                       sdrc_actim_ctrl_b_1, sdrc_mr_1);
 }
 
 /* REVISIT: Should this be same as omap34xx_sram_init() after off-idle? */
index 5b75a797b5ab9f53cb54f9cf8bcf0cc839f51439..0afb217a775e1eec0ff34563dc2eaaf497490448 100644 (file)
@@ -129,7 +129,7 @@ static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
 
        /* calculate the MISCCR setting for the clock */
 
-       if (parent == &clk_xtal)
+       if (parent == &clk_mpll)
                source = S3C2410_MISCCR_CLK0_MPLL;
        else if (parent == &clk_upll)
                source = S3C2410_MISCCR_CLK0_UPLL;
index 96a14a426a7c39f7e2d4ccf5bef49a7be5c425f7..4320239cf4ef1c73e57ffba2288f9226dbbe8c2f 100644 (file)
 #define PAGE_SIZE      (1UL << PAGE_SHIFT)
 #define PAGE_MASK       (~((1 << PAGE_SHIFT) - 1))
 
+#ifdef CONFIG_HUGETLB_PAGE
 #define HPAGE_SHIFT    (PAGE_SHIFT + PAGE_SHIFT - 3)
 #define HPAGE_SIZE     ((1UL) << HPAGE_SHIFT)
 #define HPAGE_MASK     (~(HPAGE_SIZE - 1))
 #define HUGETLB_PAGE_ORDER     (HPAGE_SHIFT - PAGE_SHIFT)
+#endif /* CONFIG_HUGETLB_PAGE */
 
 #ifndef __ASSEMBLY__
 
index 8fed45a2fb8550dd4cf09f3f8844269194d613cd..15456a0773bfc598e3e49f97292861cd50eb9c63 100644 (file)
@@ -238,7 +238,7 @@ static struct platform_device ceu1_device = {
        },
 };
 
-/* KEYSC */
+/* KEYSC in SoC (Needs SW33-2 set to ON) */
 static struct sh_keysc_info keysc_info = {
        .mode = SH_KEYSC_MODE_1,
        .scan_timing = 10,
@@ -255,12 +255,13 @@ static struct sh_keysc_info keysc_info = {
 
 static struct resource keysc_resources[] = {
        [0] = {
-               .start  = 0x1a204000,
-               .end    = 0x1a20400f,
+               .name   = "KEYSC",
+               .start  = 0x044b0000,
+               .end    = 0x044b000f,
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = IRQ0_KEY,
+               .start  = 79,
                .flags  = IORESOURCE_IRQ,
        },
 };
index 5d888ef53d82b02e5eec2ebe1b29d63f2f7afa46..baf2d7d46b05ba35fe936d2788128d0c1ebe9df5 100644 (file)
@@ -26,8 +26,30 @@ ENTRY(sh_mobile_standby)
 
        tst     #SUSP_SH_SF, r0
        bt      skip_set_sf
+#ifdef CONFIG_CPU_SUBTYPE_SH7724
+       /* DBSC: put memory in self-refresh mode */
 
-       /* SDRAM: disable power down and put in self-refresh mode */
+       mov.l   dben_reg, r4
+       mov.l   dben_data0, r1
+       mov.l   r1, @r4
+
+       mov.l   dbrfpdn0_reg, r4
+       mov.l   dbrfpdn0_data0, r1
+       mov.l   r1, @r4
+
+       mov.l   dbcmdcnt_reg, r4
+       mov.l   dbcmdcnt_data0, r1
+       mov.l   r1, @r4
+
+       mov.l   dbcmdcnt_reg, r4
+       mov.l   dbcmdcnt_data1, r1
+       mov.l   r1, @r4
+
+       mov.l   dbrfpdn0_reg, r4
+       mov.l   dbrfpdn0_data1, r1
+       mov.l   r1, @r4
+#else
+       /* SBSC: disable power down and put in self-refresh mode */
        mov.l   1f, r4
        mov.l   2f, r1
        mov.l   @r4, r2
@@ -35,6 +57,7 @@ ENTRY(sh_mobile_standby)
        mov.l   3f, r3
        and     r3, r2
        mov.l   r2, @r4
+#endif
 
 skip_set_sf:
        tst     #SUSP_SH_SLEEP, r0
@@ -84,7 +107,36 @@ done_sleep:
        tst     #SUSP_SH_SF, r0
        bt      skip_restore_sf
 
-       /* SDRAM: set auto-refresh mode */
+#ifdef CONFIG_CPU_SUBTYPE_SH7724
+       /* DBSC: put memory in auto-refresh mode */
+
+       mov.l   dbrfpdn0_reg, r4
+       mov.l   dbrfpdn0_data0, r1
+       mov.l   r1, @r4
+
+       /* sleep 140 ns */
+       nop
+       nop
+       nop
+       nop
+
+       mov.l   dbcmdcnt_reg, r4
+       mov.l   dbcmdcnt_data0, r1
+       mov.l   r1, @r4
+
+       mov.l   dbcmdcnt_reg, r4
+       mov.l   dbcmdcnt_data1, r1
+       mov.l   r1, @r4
+
+       mov.l   dben_reg, r4
+       mov.l   dben_data1, r1
+       mov.l   r1, @r4
+
+       mov.l   dbrfpdn0_reg, r4
+       mov.l   dbrfpdn0_data2, r1
+       mov.l   r1, @r4
+#else
+       /* SBSC: set auto-refresh mode */
        mov.l   1f, r4
        mov.l   @r4, r2
        mov.l   4f, r3
@@ -98,15 +150,29 @@ done_sleep:
        add     r4, r3
        or      r2, r3
        mov.l   r3, @r1
+#endif
 skip_restore_sf:
        rts
         nop
 
        .balign 4
+#ifdef CONFIG_CPU_SUBTYPE_SH7724
+dben_reg:      .long   0xfd000010 /* DBEN */
+dben_data0:    .long   0
+dben_data1:    .long   1
+dbrfpdn0_reg:  .long   0xfd000040 /* DBRFPDN0 */
+dbrfpdn0_data0:        .long   0
+dbrfpdn0_data1:        .long   1
+dbrfpdn0_data2:        .long   0x00010000
+dbcmdcnt_reg:  .long   0xfd000014 /* DBCMDCNT */
+dbcmdcnt_data0:        .long   2
+dbcmdcnt_data1:        .long   4
+#else
 1:     .long   0xfe400008 /* SDCR0 */
 2:     .long   0x00000400
 3:     .long   0xffff7fff
 4:     .long   0xfffffbff
+#endif
 5:     .long   0xa4150020 /* STBCR */
 6:     .long   0xfe40001c /* RTCOR */
 7:     .long   0xfe400018 /* RTCNT */
index 2964f5f4a7ef3348104044f008992d22b08b55b1..6b3e0c2f33e2b193838fbecc0dda72aa9f0db5ef 100644 (file)
@@ -40,6 +40,7 @@ struct sh_cmt_priv {
        struct platform_device *pdev;
 
        unsigned long flags;
+       unsigned long flags_suspend;
        unsigned long match_value;
        unsigned long next_match_value;
        unsigned long max_match_value;
@@ -667,11 +668,38 @@ static int __devexit sh_cmt_remove(struct platform_device *pdev)
        return -EBUSY; /* cannot unregister clockevent and clocksource */
 }
 
+static int sh_cmt_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+
+       /* save flag state and stop CMT channel */
+       p->flags_suspend = p->flags;
+       sh_cmt_stop(p, p->flags);
+       return 0;
+}
+
+static int sh_cmt_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+
+       /* start CMT channel from saved state */
+       sh_cmt_start(p, p->flags_suspend);
+       return 0;
+}
+
+static struct dev_pm_ops sh_cmt_dev_pm_ops = {
+       .suspend = sh_cmt_suspend,
+       .resume = sh_cmt_resume,
+};
+
 static struct platform_driver sh_cmt_device_driver = {
        .probe          = sh_cmt_probe,
        .remove         = __devexit_p(sh_cmt_remove),
        .driver         = {
                .name   = "sh_cmt",
+               .pm     = &sh_cmt_dev_pm_ops,
        }
 };
 
index 0ca1ee768a1fcf4ac0f995813e69485dad4b6d0f..8ce74d95ae4d9b9a47e8fa5a1389e87d71f46b0d 100644 (file)
@@ -108,7 +108,7 @@ static int fill_pkg(struct cn_msg *msg, struct dm_ulog_request *tfr)
                                *(pkg->data_size) = 0;
                } else if (tfr->data_size > *(pkg->data_size)) {
                        DMERR("Insufficient space to receive package [%u] "
-                             "(%u vs %lu)", tfr->request_type,
+                             "(%u vs %zu)", tfr->request_type,
                              tfr->data_size, *(pkg->data_size));
 
                        *(pkg->data_size) = 0;
index 103f2d33fa8978bc5a01724846cf6628b260d0be..9dd872000cec843db28fd393f2eb3023725c4bf4 100644 (file)
@@ -4364,6 +4364,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
                if (mode == 1)
                        set_disk_ro(disk, 1);
                clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+               err = 0;
        }
 out:
        mutex_unlock(&mddev->open_mutex);
index 825aa1412e6f0ca039cb3729aded3d970fdc266f..9f5dba244cb86e7e361e992bbd45fedd41b1a1f9 100644 (file)
@@ -64,24 +64,22 @@ static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val)
 /* dump all registers */
 static void qt1010_dump_regs(struct qt1010_priv *priv)
 {
-       char buf[52], buf2[4];
        u8 reg, val;
 
        for (reg = 0; ; reg++) {
                if (reg % 16 == 0) {
                        if (reg)
-                               printk("%s\n", buf);
-                       sprintf(buf, "%02x: ", reg);
+                               printk(KERN_CONT "\n");
+                       printk(KERN_DEBUG "%02x:", reg);
                }
                if (qt1010_readreg(priv, reg, &val) == 0)
-                       sprintf(buf2, "%02x ", val);
+                       printk(KERN_CONT " %02x", val);
                else
-                       strcpy(buf2, "-- ");
-               strcat(buf, buf2);
+                       printk(KERN_CONT " --");
                if (reg == 0x2f)
                        break;
        }
-       printk("%s\n", buf);
+       printk(KERN_CONT "\n");
 }
 
 static int qt1010_set_params(struct dvb_frontend *fe,
index aa20ce8cc668ba96b566d3aa45119a6b93e37889..f270e605da8328a728f3c844fbd88d74bcfa0d4d 100644 (file)
@@ -1119,8 +1119,8 @@ static int xc2028_sleep(struct dvb_frontend *fe)
        struct xc2028_data *priv = fe->tuner_priv;
        int rc = 0;
 
-       /* Avoid firmware reload on slow devices */
-       if (no_poweroff)
+       /* Avoid firmware reload on slow devices or if PM disabled */
+       if (no_poweroff || priv->ctrl.disable_power_mgmt)
                return 0;
 
        tuner_dbg("Putting xc2028/3028 into poweroff mode.\n");
index 19de7928a74eb75b5a01177a633acdf7e7768559..a90c35d50add70c00a7deaa7476757d7d9cbd3bc 100644 (file)
@@ -38,6 +38,7 @@ struct xc2028_ctrl {
        unsigned int            input1:1;
        unsigned int            vhfbw7:1;
        unsigned int            uhfbw8:1;
+       unsigned int            disable_power_mgmt:1;
        unsigned int            demod;
        enum firmware_type      type:2;
 };
index 4cb31e7c13c2856be433e2feb3feee225d02db64..26690dfb32601b9fcde1825ba41d18392b663d08 100644 (file)
@@ -81,7 +81,6 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
 
        switch (req->cmd) {
        case GET_CONFIG:
-       case BOOT:
        case READ_MEMORY:
        case RECONNECT_USB:
        case GET_IR_CODE:
@@ -100,6 +99,7 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
        case WRITE_VIRTUAL_MEMORY:
        case COPY_FIRMWARE:
        case DOWNLOAD_FIRMWARE:
+       case BOOT:
                break;
        default:
                err("unknown command:%d", req->cmd);
index ace5cb17165daddf0e78c82a08aeaf215b5dec4d..fbd838eca268765e79268a3165f3fb34f9908a8d 100644 (file)
@@ -380,7 +380,7 @@ struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
        struct cx22700_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct cx22700_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct cx22700_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 5d1abe34bddb5cfc17694a7459877aaf0cbb86f7..00b5c7e91d5d8189ca212f297fbd0fccf908ae29 100644 (file)
@@ -580,7 +580,7 @@ struct dvb_frontend *cx22702_attach(const struct cx22702_config *config,
        struct cx22702_state *state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct cx22702_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 87ae29db024fc2aea18122996b60ac29a879b24d..ffbcfabd83f0c861aa5b0dc2c1532f7380a46750 100644 (file)
@@ -598,7 +598,7 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
        int ret;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct cx24110_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct cx24110_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index db8a937cc63008dbabe4a1225810f03e80916d31..a7fc7e53a5518f6b20edbb7d96d050c8a2a5dbe3 100644 (file)
@@ -117,7 +117,7 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void)
        struct dvb_dummy_fe_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* create dvb_frontend */
@@ -137,7 +137,7 @@ struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
        struct dvb_dummy_fe_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* create dvb_frontend */
@@ -157,7 +157,7 @@ struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
        struct dvb_dummy_fe_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* create dvb_frontend */
index e1e70e9e0cb9ced61f4b71f96a882bff38d40965..3051b64aa17c6bd3c8d7b3fbaad1727908d92b26 100644 (file)
@@ -501,7 +501,7 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config,
                           { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct l64781_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct l64781_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 855852fddf22c4ab294d15c81ee4a89f5df47720..bb37ed289a059542d2821b9612261a18e7751f1e 100644 (file)
@@ -387,7 +387,7 @@ lgs8gl5_attach(const struct lgs8gl5_config *config, struct i2c_adapter *i2c)
        dprintk("%s\n", __func__);
 
        /* Allocate memory for the internal state */
-       state = kmalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index a621f727935f217eb91f78e84a025bfc7a36767b..f69daaac78c9bf431d1371914d208ad5a9f9811e 100644 (file)
@@ -782,7 +782,7 @@ struct dvb_frontend *mt312_attach(const struct mt312_config *config,
        struct mt312_state *state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct mt312_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 0eef22dbf8a041ae5f82e0aecc5cc36770ab1d0a..a763ec756f7f84df840bcb38bfb3816ee016e174 100644 (file)
@@ -545,7 +545,7 @@ struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
        struct nxt6000_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 8133ea3cddd783023ff581c47c904b412ac47c0f..38e67accb8c360af874fc9b3d57804c523d4a34a 100644 (file)
@@ -562,7 +562,7 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config,
        struct or51132_state* state = NULL;
 
        /* Allocate memory for the internal state */
-       state = kmalloc(sizeof(struct or51132_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct or51132_state), GFP_KERNEL);
        if (state == NULL)
                return NULL;
 
index 16cf2fdd5d7d1c6a14189a5b56312a4b4acb3f99..c709ce6771c86ca831e9e17e1677e03da0b05e7c 100644 (file)
@@ -527,7 +527,7 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config,
        struct or51211_state* state = NULL;
 
        /* Allocate memory for the internal state */
-       state = kmalloc(sizeof(struct or51211_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct or51211_state), GFP_KERNEL);
        if (state == NULL)
                return NULL;
 
index 3e08d985d6e50cf2f1fb36df3169274c74b22dcb..fb30115184270e38883ebee422c5f54582d58884 100644 (file)
@@ -796,7 +796,7 @@ struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config,
        u16 reg;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct s5h1409_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct s5h1409_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 66e2dd6d6fe4eb725b21f203b21e180081c8ef45..d8adf1e32019a9f7b62a712d693dd242ee79e036 100644 (file)
@@ -844,7 +844,7 @@ struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
        u16 reg;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct s5h1411_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct s5h1411_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 0bd16af8a6cd0723ab127f5a8de3c8d99e81e581..9552a22ccffb23b215897979fd51f45a2d8dc07a 100644 (file)
@@ -928,7 +928,7 @@ struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
        dprintk("%s\n", __func__);
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct si21xx_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 1c9a9b4051b9efdbc8a4a9eba005d74f883c4e11..b85eb60a893e34954a313382a2fad0b5d8a88499 100644 (file)
@@ -557,7 +557,7 @@ struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
        struct sp8870_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct sp8870_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct sp8870_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 559509ab4dabfc2f4376bb0b46d58315defb74fd..4a7c3d8426088bdccd39ab95b197b8b2963ab3d9 100644 (file)
@@ -557,7 +557,7 @@ struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
        struct sp887x_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct sp887x_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct sp887x_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index ff1194de34c0cf176f655329af5213754b1f4fab..2930a5d6768a71d89d38ecf8d4a85b87c55a9905 100644 (file)
@@ -570,7 +570,7 @@ struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
        int id;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct stv0288_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 62caf802ed990b0343e50f8374c97f451b7a5e50..4fd7479bb62b98fdba6d933cd1f34ac14ef9b6b3 100644 (file)
@@ -663,7 +663,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config,
        struct stv0297_state *state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct stv0297_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct stv0297_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 6c1cb1973c6e09c90010a7ec0167a9e50ae5b23e..9688744697260e440221ce3017a4ebd5e0dac849 100644 (file)
@@ -667,7 +667,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
        int id;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct stv0299_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct stv0299_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index f648fdb64bb7dd33753522bb70e6619bc8c42f87..f5d7b3277a2fa585360aaafda331669a11ecd95a 100644 (file)
@@ -413,7 +413,7 @@ struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
        u8 id;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda10021_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index cc8862ce4aae9fff195506148f229cc4336b9eef..4e2a7c8b2f624e41f4d33adb27ef717f5172ae79 100644 (file)
@@ -1095,7 +1095,7 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
        dprintk(1, "%s()\n", __func__);
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda10048_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda10048_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index 4981cef8b444602d5f48a00881e2199843d073d1..f2a8abe0a243b87b09d09df9098991ba23036562 100644 (file)
@@ -1269,7 +1269,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
        int id;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
        if (!state) {
                printk(KERN_ERR "Can't alocate memory for tda10045 state\n");
                return NULL;
@@ -1339,7 +1339,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
        int id;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL);
        if (!state) {
                printk(KERN_ERR "Can't alocate memory for tda10046 state\n");
                return NULL;
index a17ce3c4ad860c8959609e22c56679e5a004fda1..f2c8faac6f36426e0c7beb3f361e223b3b12cfcd 100644 (file)
@@ -745,7 +745,7 @@ struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
        dprintk ("%s\n", __func__);
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda10086_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda10086_state), GFP_KERNEL);
        if (!state)
                return NULL;
 
index 5b843b2e67e874c03f79cdfb1407680e16ee99ad..9369f7442f273b810c8568873047153d7a1149ba 100644 (file)
@@ -417,7 +417,7 @@ struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
        struct tda8083_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct tda8083_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct tda8083_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index a184597f1d9be0002b8f567b245a849abef6553c..6e78e486551599bc47d76addb4e0af3e284175b6 100644 (file)
@@ -374,7 +374,7 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
        struct ves1820_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct ves1820_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct ves1820_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
 
index bd558960bd87222eed8a71e7f696554e461ea9be..8d7854c2fb0c142683a2c823a3447af61c637438 100644 (file)
@@ -456,7 +456,7 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
        u8 identity;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct ves1x93_state), GFP_KERNEL);
        if (state == NULL) goto error;
 
        /* setup the state */
index 148b6f7f6cb253534b785ef2e6a95769e236fa45..66f5c1fb3074e60e13d481b558d2403803e9d5eb 100644 (file)
@@ -98,7 +98,6 @@ static int zl10353_read_register(struct zl10353_state *state, u8 reg)
 static void zl10353_dump_regs(struct dvb_frontend *fe)
 {
        struct zl10353_state *state = fe->demodulator_priv;
-       char buf[52], buf2[4];
        int ret;
        u8 reg;
 
@@ -106,19 +105,18 @@ static void zl10353_dump_regs(struct dvb_frontend *fe)
        for (reg = 0; ; reg++) {
                if (reg % 16 == 0) {
                        if (reg)
-                               printk(KERN_DEBUG "%s\n", buf);
-                       sprintf(buf, "%02x: ", reg);
+                               printk(KERN_CONT "\n");
+                       printk(KERN_DEBUG "%02x:", reg);
                }
                ret = zl10353_read_register(state, reg);
                if (ret >= 0)
-                       sprintf(buf2, "%02x ", (u8)ret);
+                       printk(KERN_CONT " %02x", (u8)ret);
                else
-                       strcpy(buf2, "-- ");
-               strcat(buf, buf2);
+                       printk(KERN_CONT " --");
                if (reg == 0xff)
                        break;
        }
-       printk(KERN_DEBUG "%s\n", buf);
+       printk(KERN_CONT "\n");
 }
 
 static void zl10353_calc_nominal_rate(struct dvb_frontend *fe,
index dd863f26167244b1fa09925b6fa4bcec6ff0b682..88847d1dcbb5187ff3e0f645f51b2bc3534719f7 100644 (file)
@@ -4,7 +4,7 @@
 
 config DVB_SIANO_SMS1XXX
        tristate "Siano SMS1XXX USB dongle support"
-       depends on DVB_CORE && USB
+       depends on DVB_CORE && USB && INPUT
        ---help---
          Choose Y here if you have a USB dongle with a SMS1XXX chipset.
 
index d8b15d583bdeb2e662a3d336aabd7017d2414722..0420e2885e752971fd4ef1dbc01ac2d4d46e000f 100644 (file)
@@ -116,99 +116,21 @@ static inline void sms_gpio_assign_11xx_default_led_config(
 
 int sms_board_event(struct smscore_device_t *coredev,
                enum SMS_BOARD_EVENTS gevent) {
-       int board_id = smscore_get_board_id(coredev);
-       struct sms_board *board = sms_get_board(board_id);
        struct smscore_gpio_config MyGpioConfig;
 
        sms_gpio_assign_11xx_default_led_config(&MyGpioConfig);
 
        switch (gevent) {
        case BOARD_EVENT_POWER_INIT: /* including hotplug */
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       /* set I/O and turn off all LEDs */
-                       smscore_gpio_configure(coredev,
-                                       board->board_cfg.leds_power,
-                                       &MyGpioConfig);
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.leds_power, 0);
-                       smscore_gpio_configure(coredev, board->board_cfg.led0,
-                                       &MyGpioConfig);
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.led0, 0);
-                       smscore_gpio_configure(coredev, board->board_cfg.led1,
-                                       &MyGpioConfig);
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.led1, 0);
-                       break;
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-                       /* set I/O and turn off LNA */
-                       smscore_gpio_configure(coredev,
-                                       board->board_cfg.foreign_lna0_ctrl,
-                                       &MyGpioConfig);
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.foreign_lna0_ctrl,
-                                       0);
-                       break;
-               }
                break; /* BOARD_EVENT_BIND */
 
        case BOARD_EVENT_POWER_SUSPEND:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.leds_power, 0);
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led0, 0);
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led1, 0);
-                       break;
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.foreign_lna0_ctrl,
-                                       0);
-                       break;
-               }
                break; /* BOARD_EVENT_POWER_SUSPEND */
 
        case BOARD_EVENT_POWER_RESUME:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.leds_power, 1);
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led0, 1);
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led1, 0);
-                       break;
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.foreign_lna0_ctrl,
-                                       1);
-                       break;
-               }
                break; /* BOARD_EVENT_POWER_RESUME */
 
        case BOARD_EVENT_BIND:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                               board->board_cfg.leds_power, 1);
-                       smscore_gpio_set_level(coredev,
-                               board->board_cfg.led0, 1);
-                       smscore_gpio_set_level(coredev,
-                               board->board_cfg.led1, 0);
-                       break;
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
-               case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
-                       smscore_gpio_set_level(coredev,
-                                       board->board_cfg.foreign_lna0_ctrl,
-                                       1);
-                       break;
-               }
                break; /* BOARD_EVENT_BIND */
 
        case BOARD_EVENT_SCAN_PROG:
@@ -218,20 +140,8 @@ int sms_board_event(struct smscore_device_t *coredev,
        case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL:
                break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */
        case BOARD_EVENT_FE_LOCK:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                       board->board_cfg.led1, 1);
-                       break;
-               }
                break; /* BOARD_EVENT_FE_LOCK */
        case BOARD_EVENT_FE_UNLOCK:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led1, 0);
-                       break;
-               }
                break; /* BOARD_EVENT_FE_UNLOCK */
        case BOARD_EVENT_DEMOD_LOCK:
                break; /* BOARD_EVENT_DEMOD_LOCK */
@@ -248,20 +158,8 @@ int sms_board_event(struct smscore_device_t *coredev,
        case BOARD_EVENT_RECEPTION_LOST_0:
                break; /* BOARD_EVENT_RECEPTION_LOST_0 */
        case BOARD_EVENT_MULTIPLEX_OK:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led1, 1);
-                       break;
-               }
                break; /* BOARD_EVENT_MULTIPLEX_OK */
        case BOARD_EVENT_MULTIPLEX_ERRORS:
-               switch (board_id) {
-               case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
-                       smscore_gpio_set_level(coredev,
-                                               board->board_cfg.led1, 0);
-                       break;
-               }
                break; /* BOARD_EVENT_MULTIPLEX_ERRORS */
 
        default:
index a246903c3341bea1ba919f9a6b5262e73e3d6d6a..bd9ab9d0d12a27d753f09dd79fcd882d0963d31f 100644 (file)
@@ -816,7 +816,7 @@ int smscore_set_device_mode(struct smscore_device_t *coredev, int mode)
 
        sms_debug("set device mode to %d", mode);
        if (coredev->device_flags & SMS_DEVICE_FAMILY2) {
-               if (mode < DEVICE_MODE_DVBT || mode > DEVICE_MODE_RAW_TUNER) {
+               if (mode < DEVICE_MODE_DVBT || mode >= DEVICE_MODE_RAW_TUNER) {
                        sms_err("invalid mode specified %d", mode);
                        return -EINVAL;
                }
index 84b6fc15519d13807cf8c3601e4551ac87d72f49..dcf9fa9264bb720856775748a3e6e69d373fcee4 100644 (file)
@@ -920,6 +920,8 @@ source "drivers/media/video/pwc/Kconfig"
 config USB_ZR364XX
        tristate "USB ZR364XX Camera support"
        depends on VIDEO_V4L2
+       select VIDEOBUF_GEN
+       select VIDEOBUF_VMALLOC
        ---help---
          Say Y here if you want to connect this type of camera to your
          computer's USB port.
index 10dbd4a11b30f8e4aaf7e0ac2fad97f69bb56dbb..9e39bc5f7b00147098a2c660880e6f3853be5e6d 100644 (file)
@@ -992,7 +992,7 @@ static int accept_bwqcam(struct parport *port)
 
        if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
                /* user gave parport parameters */
-               for(n=0; parport[n] && n<MAX_CAMS; n++){
+               for (n = 0; n < MAX_CAMS && parport[n]; n++) {
                        char *ep;
                        unsigned long r;
                        r = simple_strtoul(parport[n], &ep, 0);
index 5136df198338bbbe6855889b84cf0b5486252b2d..93f0dae01350316d9c13110504df129baa4f5ecb 100644 (file)
@@ -20,6 +20,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  *  02111-1307  USA
  */
+#include <linux/kernel.h>
 
 #include "cx18-driver.h"
 #include "cx18-cards.h"
@@ -317,7 +318,7 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
                idx = p.audio_properties & 0x03;
                /* The audio clock of the digitizer must match the codec sample
                   rate otherwise you get some very strange effects. */
-               if (idx < sizeof(freqs))
+               if (idx < ARRAY_SIZE(freqs))
                        cx18_call_all(cx, audio, s_clock_freq, freqs[idx]);
                return err;
        }
index e0cf21e0b1bf52e3649841a6405d70ed3c4859ef..1a1048b18f7027c67eed1eac69b30fd1ad0b055d 100644 (file)
@@ -1715,6 +1715,8 @@ static struct video_device cx23885_mpeg_template = {
        .fops          = &mpeg_fops,
        .ioctl_ops     = &mpeg_ioctl_ops,
        .minor         = -1,
+       .tvnorms       = CX23885_NORMS,
+       .current_norm  = V4L2_STD_NTSC_M,
 };
 
 void cx23885_417_unregister(struct cx23885_dev *dev)
index a5cc1c1fc2d60c30329350a1ee1072c21efe68a5..39465301ec94ea78fa6d6f54ae467f0b9fc3e119 100644 (file)
@@ -3003,6 +3003,14 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
        case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
                ctl->demod = XC3028_FE_OREN538;
                break;
+       case CX88_BOARD_GENIATECH_X8000_MT:
+               /* FIXME: For this board, the xc3028 never recovers after being
+                  powered down (the reset GPIO probably is not set properly).
+                  We don't have access to the hardware so we cannot determine
+                  which GPIO is used for xc3028, so just disable power xc3028
+                  power management for now */
+               ctl->disable_power_mgmt = 1;
+               break;
        case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
        case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
        case CX88_BOARD_PROLINK_PV_8000GT:
index c44e8760021932bf907ce3be5e135db9f661c5a8..e237b507659ba82bc45a03022245118ef41fce2b 100644 (file)
@@ -501,6 +501,7 @@ static struct zl10353_config cx88_pinnacle_hybrid_pctv = {
 static struct zl10353_config cx88_geniatech_x8000_mt = {
        .demod_address = (0x1e >> 1),
        .no_tuner = 1,
+       .disable_i2c_gate_ctrl = 1,
 };
 
 static struct s5h1411_config dvico_fusionhdtv7_config = {
index da4e3912cd374991ba37f560779e2a871f05cf28..7172dcf2a4fa87ed94c4ac3c41789e1ddafc467d 100644 (file)
@@ -116,6 +116,10 @@ static int cx8802_start_dma(struct cx8802_dev    *dev,
                        udelay(100);
                        break;
                case CX88_BOARD_HAUPPAUGE_HVR1300:
+                       /* Enable MPEG parallel IO and video signal pins */
+                       cx_write(MO_PINMUX_IO, 0x88);
+                       cx_write(TS_SOP_STAT, 0);
+                       cx_write(TS_VALERR_CNTRL, 0);
                        break;
                case CX88_BOARD_PINNACLE_PCTV_HD_800i:
                        /* Enable MPEG parallel IO and video signal pins */
index 320f1f60276ec0a5fa71f58ba5eca48690d19f1a..ed281f5659459c20bc571fbfb3ed61e3348590bc 100644 (file)
@@ -218,7 +218,7 @@ static struct em28xx_reg_seq silvercrest_reg_seq[] = {
 struct em28xx_board em28xx_boards[] = {
        [EM2750_BOARD_UNKNOWN] = {
                .name          = "EM2710/EM2750/EM2751 webcam grabber",
-               .xclk          = EM28XX_XCLK_FREQUENCY_48MHZ,
+               .xclk          = EM28XX_XCLK_FREQUENCY_20MHZ,
                .tuner_type    = TUNER_ABSENT,
                .is_webcam     = 1,
                .input         = { {
@@ -622,22 +622,27 @@ struct em28xx_board em28xx_boards[] = {
        },
        [EM2861_BOARD_PLEXTOR_PX_TV100U] = {
                .name         = "Plextor ConvertX PX-TV100U",
-               .valid        = EM28XX_BOARD_NOT_VALIDATED,
                .tuner_type   = TUNER_TNF_5335MF,
+               .xclk         = EM28XX_XCLK_I2S_MSB_TIMING |
+                               EM28XX_XCLK_FREQUENCY_12MHZ,
                .tda9887_conf = TDA9887_PRESENT,
                .decoder      = EM28XX_TVP5150,
+               .has_msp34xx  = 1,
                .input        = { {
                        .type     = EM28XX_VMUX_TELEVISION,
                        .vmux     = TVP5150_COMPOSITE0,
                        .amux     = EM28XX_AMUX_LINE_IN,
+                       .gpio     = pinnacle_hybrid_pro_analog,
                }, {
                        .type     = EM28XX_VMUX_COMPOSITE1,
                        .vmux     = TVP5150_COMPOSITE1,
                        .amux     = EM28XX_AMUX_LINE_IN,
+                       .gpio     = pinnacle_hybrid_pro_analog,
                }, {
                        .type     = EM28XX_VMUX_SVIDEO,
                        .vmux     = TVP5150_SVIDEO,
                        .amux     = EM28XX_AMUX_LINE_IN,
+                       .gpio     = pinnacle_hybrid_pro_analog,
                } },
        },
 
@@ -1544,6 +1549,8 @@ struct usb_device_id em28xx_id_table[] = {
                        .driver_info = EM2750_BOARD_UNKNOWN },
        { USB_DEVICE(0xeb1a, 0x2800),
                        .driver_info = EM2800_BOARD_UNKNOWN },
+       { USB_DEVICE(0xeb1a, 0x2710),
+                       .driver_info = EM2820_BOARD_UNKNOWN },
        { USB_DEVICE(0xeb1a, 0x2820),
                        .driver_info = EM2820_BOARD_UNKNOWN },
        { USB_DEVICE(0xeb1a, 0x2821),
@@ -1761,6 +1768,7 @@ static int em28xx_hint_sensor(struct em28xx *dev)
        __be16 version_be;
        u16 version;
 
+       /* Micron sensor detection */
        dev->i2c_client.addr = 0xba >> 1;
        cmd = 0;
        i2c_master_send(&dev->i2c_client, &cmd, 1);
@@ -1769,15 +1777,27 @@ static int em28xx_hint_sensor(struct em28xx *dev)
                return -EINVAL;
 
        version = be16_to_cpu(version_be);
-
        switch (version) {
-       case 0x8243:            /* mt9v011 640x480 1.3 Mpix sensor */
+       case 0x8232:            /* mt9v011 640x480 1.3 Mpix sensor */
+       case 0x8243:            /* mt9v011 rev B 640x480 1.3 Mpix sensor */
                dev->model = EM2820_BOARD_SILVERCREST_WEBCAM;
+               em28xx_set_model(dev);
+
                sensor_name = "mt9v011";
                dev->em28xx_sensor = EM28XX_MT9V011;
                dev->sensor_xres = 640;
                dev->sensor_yres = 480;
-               dev->sensor_xtal = 6300000;
+               /*
+                * FIXME: mt9v011 uses I2S speed as xtal clk - at least with
+                * the Silvercrest cam I have here for testing - for higher
+                * resolutions, a high clock cause horizontal artifacts, so we
+                * need to use a lower xclk frequency.
+                * Yet, it would be possible to adjust xclk depending on the
+                * desired resolution, since this affects directly the
+                * frame rate.
+                */
+               dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ;
+               dev->sensor_xtal = 4300000;
 
                /* probably means GRGB 16 bit bayer */
                dev->vinmode = 0x0d;
@@ -1786,6 +1806,8 @@ static int em28xx_hint_sensor(struct em28xx *dev)
                break;
        case 0x8431:
                dev->model = EM2750_BOARD_UNKNOWN;
+               em28xx_set_model(dev);
+
                sensor_name = "mt9m001";
                dev->em28xx_sensor = EM28XX_MT9M001;
                em28xx_initialize_mt9m001(dev);
@@ -1802,6 +1824,9 @@ static int em28xx_hint_sensor(struct em28xx *dev)
                return -EINVAL;
        }
 
+       /* Setup webcam defaults */
+       em28xx_pre_card_setup(dev);
+
        em28xx_errdev("Sensor is %s, using model %s entry.\n",
                      sensor_name, em28xx_boards[dev->model].name);
 
@@ -1813,60 +1838,6 @@ static int em28xx_hint_sensor(struct em28xx *dev)
  */
 void em28xx_pre_card_setup(struct em28xx *dev)
 {
-       int rc;
-
-       em28xx_set_model(dev);
-
-       em28xx_info("Identified as %s (card=%d)\n",
-                   dev->board.name, dev->model);
-
-       /* Set the default GPO/GPIO for legacy devices */
-       dev->reg_gpo_num = EM2880_R04_GPO;
-       dev->reg_gpio_num = EM28XX_R08_GPIO;
-
-       dev->wait_after_write = 5;
-
-       /* Based on the Chip ID, set the device configuration */
-       rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
-       if (rc > 0) {
-               dev->chip_id = rc;
-
-               switch (dev->chip_id) {
-               case CHIP_ID_EM2750:
-                       em28xx_info("chip ID is em2750\n");
-                       break;
-               case CHIP_ID_EM2820:
-                       em28xx_info("chip ID is em2710 or em2820\n");
-                       break;
-               case CHIP_ID_EM2840:
-                       em28xx_info("chip ID is em2840\n");
-                       break;
-               case CHIP_ID_EM2860:
-                       em28xx_info("chip ID is em2860\n");
-                       break;
-               case CHIP_ID_EM2870:
-                       em28xx_info("chip ID is em2870\n");
-                       dev->wait_after_write = 0;
-                       break;
-               case CHIP_ID_EM2874:
-                       em28xx_info("chip ID is em2874\n");
-                       dev->reg_gpio_num = EM2874_R80_GPIO;
-                       dev->wait_after_write = 0;
-                       break;
-               case CHIP_ID_EM2883:
-                       em28xx_info("chip ID is em2882/em2883\n");
-                       dev->wait_after_write = 0;
-                       break;
-               default:
-                       em28xx_info("em28xx chip ID = %d\n", dev->chip_id);
-               }
-       }
-
-       /* Prepopulate cached GPO register content */
-       rc = em28xx_read_reg(dev, dev->reg_gpo_num);
-       if (rc >= 0)
-               dev->reg_gpo = rc;
-
        /* Set the initial XCLK and I2C clock values based on the board
           definition */
        em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f);
@@ -1876,9 +1847,8 @@ void em28xx_pre_card_setup(struct em28xx *dev)
        /* request some modules */
        switch (dev->model) {
        case EM2861_BOARD_PLEXTOR_PX_TV100U:
-               /* FIXME guess */
-               /* Turn on analog audio output */
-               em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+               /* Sets the msp34xx I2S speed */
+               dev->i2s_speed = 2048000;
                break;
        case EM2861_BOARD_KWORLD_PVRTV_300U:
        case EM2880_BOARD_KWORLD_DVB_305U:
@@ -2216,7 +2186,20 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
 
 void em28xx_card_setup(struct em28xx *dev)
 {
-       em28xx_set_model(dev);
+       /*
+        * If the device can be a webcam, seek for a sensor.
+        * If sensor is not found, then it isn't a webcam.
+        */
+       if (dev->board.is_webcam) {
+               if (em28xx_hint_sensor(dev) < 0)
+                       dev->board.is_webcam = 0;
+               else
+                       dev->progressive = 1;
+       } else
+               em28xx_set_model(dev);
+
+       em28xx_info("Identified as %s (card=%d)\n",
+                   dev->board.name, dev->model);
 
        dev->tuner_type = em28xx_boards[dev->model].tuner_type;
        if (em28xx_boards[dev->model].tuner_addr)
@@ -2290,10 +2273,6 @@ void em28xx_card_setup(struct em28xx *dev)
                em28xx_gpio_set(dev, dev->board.tuner_gpio);
                em28xx_set_mode(dev, EM28XX_ANALOG_MODE);
                break;
-       case EM2820_BOARD_SILVERCREST_WEBCAM:
-               /* FIXME: need to document the registers bellow */
-               em28xx_write_reg(dev, 0x0d, 0x42);
-               em28xx_write_reg(dev, 0x13, 0x08);
        }
 
        if (dev->board.has_snapshot_button)
@@ -2433,7 +2412,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
                           int minor)
 {
        struct em28xx *dev = *devhandle;
-       int retval = -ENOMEM;
+       int retval;
        int errCode;
 
        dev->udev = udev;
@@ -2450,6 +2429,58 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        dev->em28xx_read_reg_req = em28xx_read_reg_req;
        dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
 
+       em28xx_set_model(dev);
+
+       /* Set the default GPO/GPIO for legacy devices */
+       dev->reg_gpo_num = EM2880_R04_GPO;
+       dev->reg_gpio_num = EM28XX_R08_GPIO;
+
+       dev->wait_after_write = 5;
+
+       /* Based on the Chip ID, set the device configuration */
+       retval = em28xx_read_reg(dev, EM28XX_R0A_CHIPID);
+       if (retval > 0) {
+               dev->chip_id = retval;
+
+               switch (dev->chip_id) {
+               case CHIP_ID_EM2710:
+                       em28xx_info("chip ID is em2710\n");
+                       break;
+               case CHIP_ID_EM2750:
+                       em28xx_info("chip ID is em2750\n");
+                       break;
+               case CHIP_ID_EM2820:
+                       em28xx_info("chip ID is em2820 (or em2710)\n");
+                       break;
+               case CHIP_ID_EM2840:
+                       em28xx_info("chip ID is em2840\n");
+                       break;
+               case CHIP_ID_EM2860:
+                       em28xx_info("chip ID is em2860\n");
+                       break;
+               case CHIP_ID_EM2870:
+                       em28xx_info("chip ID is em2870\n");
+                       dev->wait_after_write = 0;
+                       break;
+               case CHIP_ID_EM2874:
+                       em28xx_info("chip ID is em2874\n");
+                       dev->reg_gpio_num = EM2874_R80_GPIO;
+                       dev->wait_after_write = 0;
+                       break;
+               case CHIP_ID_EM2883:
+                       em28xx_info("chip ID is em2882/em2883\n");
+                       dev->wait_after_write = 0;
+                       break;
+               default:
+                       em28xx_info("em28xx chip ID = %d\n", dev->chip_id);
+               }
+       }
+
+       /* Prepopulate cached GPO register content */
+       retval = em28xx_read_reg(dev, dev->reg_gpo_num);
+       if (retval >= 0)
+               dev->reg_gpo = retval;
+
        em28xx_pre_card_setup(dev);
 
        if (!dev->board.is_em2800) {
@@ -2484,14 +2515,6 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
        dev->vinmode = 0x10;
        dev->vinctl  = 0x11;
 
-       /*
-        * If the device can be a webcam, seek for a sensor.
-        * If sensor is not found, then it isn't a webcam.
-        */
-       if (dev->board.is_webcam)
-               if (em28xx_hint_sensor(dev) < 0)
-                       dev->board.is_webcam = 0;
-
        /* Do board specific init and eeprom reading */
        em28xx_card_setup(dev);
 
index 5b78e199abd1ac9bbf433dba0012eafe02b0ab46..98e140b5d95e66a48876514721ab203369cf2e89 100644 (file)
@@ -632,6 +632,9 @@ int em28xx_capture_start(struct em28xx *dev, int start)
                return rc;
        }
 
+       if (dev->board.is_webcam)
+               rc = em28xx_write_reg(dev, 0x13, 0x0c);
+
        /* enable video capture */
        rc = em28xx_write_reg(dev, 0x48, 0x00);
 
@@ -720,7 +723,10 @@ int em28xx_resolution_set(struct em28xx *dev)
 {
        int width, height;
        width = norm_maxw(dev);
-       height = norm_maxh(dev) >> 1;
+       height = norm_maxh(dev);
+
+       if (!dev->progressive)
+               height >>= norm_maxh(dev);
 
        em28xx_set_outfmt(dev);
 
index cf0ac7f2a30d59bed6a8e617a1a1ea38e0e3e6d5..d603575431b44b71d59288ac5d860f6d7e4ae254 100644 (file)
@@ -478,7 +478,6 @@ static int dvb_init(struct em28xx *dev)
                }
                break;
        case EM2880_BOARD_KWORLD_DVB_310U:
-       case EM2880_BOARD_EMPIRE_DUAL_TV:
                dvb->frontend = dvb_attach(zl10353_attach,
                                           &em28xx_zl10353_with_xc3028,
                                           &dev->i2c_adap);
@@ -488,6 +487,7 @@ static int dvb_init(struct em28xx *dev)
                }
                break;
        case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
+       case EM2880_BOARD_EMPIRE_DUAL_TV:
                dvb->frontend = dvb_attach(zl10353_attach,
                                           &em28xx_zl10353_xc3028_no_i2c_gate,
                                           &dev->i2c_adap);
index a2676d63cfd0a673cfd26b6e0ddd593ecab10e5a..6bf84bd787df81765b25d8924463cdbb14f344a4 100644 (file)
 
 /* FIXME: Need to be populated with the other chip ID's */
 enum em28xx_chip_id {
-       CHIP_ID_EM2820 = 18,    /* Also used by em2710 */
+       CHIP_ID_EM2710 = 17,
+       CHIP_ID_EM2820 = 18,    /* Also used by some em2710 */
        CHIP_ID_EM2840 = 20,
        CHIP_ID_EM2750 = 33,
        CHIP_ID_EM2860 = 34,
index ff37b4c15f444e43c54034622113384ac8f498e0..ab079d9256c463a0c9889841ed3e0946969f1929 100644 (file)
@@ -194,15 +194,24 @@ static void em28xx_copy_video(struct em28xx *dev,
        startread = p;
        remain = len;
 
-       /* Interlaces frame */
-       if (buf->top_field)
+       if (dev->progressive)
                fieldstart = outp;
-       else
-               fieldstart = outp + bytesperline;
+       else {
+               /* Interlaces two half frames */
+               if (buf->top_field)
+                       fieldstart = outp;
+               else
+                       fieldstart = outp + bytesperline;
+       }
 
        linesdone = dma_q->pos / bytesperline;
        currlinedone = dma_q->pos % bytesperline;
-       offset = linesdone * bytesperline * 2 + currlinedone;
+
+       if (dev->progressive)
+               offset = linesdone * bytesperline + currlinedone;
+       else
+               offset = linesdone * bytesperline * 2 + currlinedone;
+
        startwrite = fieldstart + offset;
        lencopy = bytesperline - currlinedone;
        lencopy = lencopy > remain ? remain : lencopy;
@@ -376,7 +385,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
                        em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
                                       len, (p[2] & 1) ? "odd" : "even");
 
-                       if (!(p[2] & 1)) {
+                       if (dev->progressive || !(p[2] & 1)) {
                                if (buf != NULL)
                                        buffer_filled(dev, dma_q, buf);
                                get_next_buf(dma_q, &buf);
@@ -689,7 +698,10 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 
        /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */
-       f->fmt.pix.field = dev->interlaced ?
+       if (dev->progressive)
+               f->fmt.pix.field = V4L2_FIELD_NONE;
+       else
+               f->fmt.pix.field = dev->interlaced ?
                           V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
 
        mutex_unlock(&dev->lock);
@@ -753,7 +765,11 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
        f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;
        f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
        f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
-       f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+       if (dev->progressive)
+               f->fmt.pix.field = V4L2_FIELD_NONE;
+       else
+               f->fmt.pix.field = dev->interlaced ?
+                          V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
 
        return 0;
 }
@@ -846,6 +862,41 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
        return 0;
 }
 
+static int vidioc_g_parm(struct file *file, void *priv,
+                        struct v4l2_streamparm *p)
+{
+       struct em28xx_fh   *fh  = priv;
+       struct em28xx      *dev = fh->dev;
+       int rc = 0;
+
+       if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       if (dev->board.is_webcam)
+               rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0,
+                                               video, g_parm, p);
+       else
+               v4l2_video_std_frame_period(dev->norm,
+                                                &p->parm.capture.timeperframe);
+
+       return rc;
+}
+
+static int vidioc_s_parm(struct file *file, void *priv,
+                        struct v4l2_streamparm *p)
+{
+       struct em28xx_fh   *fh  = priv;
+       struct em28xx      *dev = fh->dev;
+
+       if (!dev->board.is_webcam)
+               return -EINVAL;
+
+       if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       return v4l2_device_call_until_err(&dev->v4l2_dev, 0, video, s_parm, p);
+}
+
 static const char *iname[] = {
        [EM28XX_VMUX_COMPOSITE1] = "Composite1",
        [EM28XX_VMUX_COMPOSITE2] = "Composite2",
@@ -1624,6 +1675,7 @@ static int em28xx_v4l2_open(struct file *filp)
        struct em28xx *dev;
        enum v4l2_buf_type fh_type;
        struct em28xx_fh *fh;
+       enum v4l2_field field;
 
        dev = em28xx_get_device(minor, &fh_type, &radio);
 
@@ -1665,8 +1717,13 @@ static int em28xx_v4l2_open(struct file *filp)
 
        dev->users++;
 
+       if (dev->progressive)
+               field = V4L2_FIELD_NONE;
+       else
+               field = V4L2_FIELD_INTERLACED;
+
        videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops,
-                       NULL, &dev->slock, fh->type, V4L2_FIELD_INTERLACED,
+                       NULL, &dev->slock, fh->type, field,
                        sizeof(struct em28xx_buffer), fh);
 
        mutex_unlock(&dev->lock);
@@ -1885,6 +1942,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
        .vidioc_qbuf                = vidioc_qbuf,
        .vidioc_dqbuf               = vidioc_dqbuf,
        .vidioc_s_std               = vidioc_s_std,
+       .vidioc_g_parm              = vidioc_g_parm,
+       .vidioc_s_parm              = vidioc_s_parm,
        .vidioc_enum_input          = vidioc_enum_input,
        .vidioc_g_input             = vidioc_g_input,
        .vidioc_s_input             = vidioc_s_input,
index 45bd513f62dcb8ed42bd9e37c58956f204f1d23f..8c2dc38bca9ffe8b9a02f7e7af5d5dcc17a9df61 100644 (file)
@@ -484,6 +484,9 @@ struct em28xx {
        int sensor_xres, sensor_yres;
        int sensor_xtal;
 
+       /* Allows progressive (e. g. non-interlaced) mode */
+       int progressive;
+
        /* Vinmode/Vinctl used at the driver */
        int vinmode, vinctl;
 
index ccd47f57f42cf75633dd6c5badb91786d835d1e0..d678765cbba233a1b6bc869c858532b01735233b 100644 (file)
@@ -1220,6 +1220,8 @@ static const struct video_device hdpvr_video_template = {
                V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I |
                V4L2_STD_PAL_D | V4L2_STD_PAL_M | V4L2_STD_PAL_N |
                V4L2_STD_PAL_60,
+       .current_norm           = V4L2_STD_NTSC | V4L2_STD_PAL_M |
+               V4L2_STD_PAL_60,
 };
 
 int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
index a3b77ed3f08949a58729ea1edda921cb762d0dc7..4a9c8ce0ecb307cc07d167a0c6685bcd3583fefe 100644 (file)
@@ -17,6 +17,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#include <linux/kernel.h>
 
 #include "ivtv-driver.h"
 #include "ivtv-cards.h"
@@ -281,7 +282,7 @@ int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
                idx = p.audio_properties & 0x03;
                /* The audio clock of the digitizer must match the codec sample
                   rate otherwise you get some very strange effects. */
-               if (idx < sizeof(freqs))
+               if (idx < ARRAY_SIZE(freqs))
                        ivtv_call_all(itv, audio, s_clock_freq, freqs[idx]);
                return err;
        }
index b2260de645f0c16855dfd31ac8aa4b296a05f34f..cc85f77a570694e39fc0cc0fbc37eef118a568fa 100644 (file)
@@ -52,13 +52,34 @@ static struct v4l2_queryctrl mt9v011_qctrl[] = {
                .step = 1,
                .default_value = 0,
                .flags = 0,
-       },
+       }, {
+               .id      = V4L2_CID_HFLIP,
+               .type    = V4L2_CTRL_TYPE_BOOLEAN,
+               .name    = "Mirror",
+               .minimum = 0,
+               .maximum = 1,
+               .step    = 1,
+               .default_value = 0,
+               .flags = 0,
+       }, {
+               .id      = V4L2_CID_VFLIP,
+               .type    = V4L2_CTRL_TYPE_BOOLEAN,
+               .name    = "Vflip",
+               .minimum = 0,
+               .maximum = 1,
+               .step    = 1,
+               .default_value = 0,
+               .flags = 0,
+       }, {
+       }
 };
 
 struct mt9v011 {
        struct v4l2_subdev sd;
        unsigned width, height;
        unsigned xtal;
+       unsigned hflip:1;
+       unsigned vflip:1;
 
        u16 global_gain, red_bal, blue_bal;
 };
@@ -131,7 +152,6 @@ static const struct i2c_reg_value mt9v011_init_default[] = {
 
                { R0A_MT9V011_CLK_SPEED, 0x0000 },
                { R1E_MT9V011_DIGITAL_ZOOM,  0x0000 },
-               { R20_MT9V011_READ_MODE, 0x1000 },
 
                { R07_MT9V011_OUT_CTRL, 0x0002 },       /* chip enable */
 };
@@ -156,7 +176,7 @@ static void set_balance(struct v4l2_subdev *sd)
        mt9v011_write(sd, R2D_MT9V011_RED_GAIN, red_gain);
 }
 
-static void calc_fps(struct v4l2_subdev *sd)
+static void calc_fps(struct v4l2_subdev *sd, u32 *numerator, u32 *denominator)
 {
        struct mt9v011 *core = to_mt9v011(sd);
        unsigned height, width, hblank, vblank, speed;
@@ -179,6 +199,51 @@ static void calc_fps(struct v4l2_subdev *sd)
 
        v4l2_dbg(1, debug, sd, "Programmed to %u.%03u fps (%d pixel clcks)\n",
                tmp / 1000, tmp % 1000, t_time);
+
+       if (numerator && denominator) {
+               *numerator = 1000;
+               *denominator = (u32)frames_per_ms;
+       }
+}
+
+static u16 calc_speed(struct v4l2_subdev *sd, u32 numerator, u32 denominator)
+{
+       struct mt9v011 *core = to_mt9v011(sd);
+       unsigned height, width, hblank, vblank;
+       unsigned row_time, line_time;
+       u64 t_time, speed;
+
+       /* Avoid bogus calculus */
+       if (!numerator || !denominator)
+               return 0;
+
+       height = mt9v011_read(sd, R03_MT9V011_HEIGHT);
+       width = mt9v011_read(sd, R04_MT9V011_WIDTH);
+       hblank = mt9v011_read(sd, R05_MT9V011_HBLANK);
+       vblank = mt9v011_read(sd, R06_MT9V011_VBLANK);
+
+       row_time = width + 113 + hblank;
+       line_time = height + vblank + 1;
+
+       t_time = core->xtal * ((u64)numerator);
+       /* round to the closest value */
+       t_time += denominator / 2;
+       do_div(t_time, denominator);
+
+       speed = t_time;
+       do_div(speed, row_time * line_time);
+
+       /* Avoid having a negative value for speed */
+       if (speed < 2)
+               speed = 0;
+       else
+               speed -= 2;
+
+       /* Avoid speed overflow */
+       if (speed > 15)
+               return 15;
+
+       return (u16)speed;
 }
 
 static void set_res(struct v4l2_subdev *sd)
@@ -207,9 +272,23 @@ static void set_res(struct v4l2_subdev *sd)
        mt9v011_write(sd, R03_MT9V011_HEIGHT, core->height);
        mt9v011_write(sd, R06_MT9V011_VBLANK, 508 - core->height);
 
-       calc_fps(sd);
+       calc_fps(sd, NULL, NULL);
 };
 
+static void set_read_mode(struct v4l2_subdev *sd)
+{
+       struct mt9v011 *core = to_mt9v011(sd);
+       unsigned mode = 0x1000;
+
+       if (core->hflip)
+               mode |= 0x4000;
+
+       if (core->vflip)
+               mode |= 0x8000;
+
+       mt9v011_write(sd, R20_MT9V011_READ_MODE, mode);
+}
+
 static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
 {
        int i;
@@ -220,6 +299,7 @@ static int mt9v011_reset(struct v4l2_subdev *sd, u32 val)
 
        set_balance(sd);
        set_res(sd);
+       set_read_mode(sd);
 
        return 0;
 };
@@ -240,6 +320,12 @@ static int mt9v011_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
        case V4L2_CID_BLUE_BALANCE:
                ctrl->value = core->blue_bal;
                return 0;
+       case V4L2_CID_HFLIP:
+               ctrl->value = core->hflip ? 1 : 0;
+               return 0;
+       case V4L2_CID_VFLIP:
+               ctrl->value = core->vflip ? 1 : 0;
+               return 0;
        }
        return -EINVAL;
 }
@@ -288,6 +374,14 @@ static int mt9v011_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
        case V4L2_CID_BLUE_BALANCE:
                core->blue_bal = ctrl->value;
                break;
+       case V4L2_CID_HFLIP:
+               core->hflip = ctrl->value;
+               set_read_mode(sd);
+               return 0;
+       case V4L2_CID_VFLIP:
+               core->vflip = ctrl->value;
+               set_read_mode(sd);
+               return 0;
        default:
                return -EINVAL;
        }
@@ -322,6 +416,44 @@ static int mt9v011_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
        return 0;
 }
 
+static int mt9v011_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
+{
+       struct v4l2_captureparm *cp = &parms->parm.capture;
+
+       if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+
+       memset(cp, 0, sizeof(struct v4l2_captureparm));
+       cp->capability = V4L2_CAP_TIMEPERFRAME;
+       calc_fps(sd,
+                &cp->timeperframe.numerator,
+                &cp->timeperframe.denominator);
+
+       return 0;
+}
+
+static int mt9v011_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
+{
+       struct v4l2_captureparm *cp = &parms->parm.capture;
+       struct v4l2_fract *tpf = &cp->timeperframe;
+       u16 speed;
+
+       if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+               return -EINVAL;
+       if (cp->extendedmode != 0)
+               return -EINVAL;
+
+       speed = calc_speed(sd, tpf->numerator, tpf->denominator);
+
+       mt9v011_write(sd, R0A_MT9V011_CLK_SPEED, speed);
+       v4l2_dbg(1, debug, sd, "Setting speed to %d\n", speed);
+
+       /* Recalculate and update fps info */
+       calc_fps(sd, &tpf->numerator, &tpf->denominator);
+
+       return 0;
+}
+
 static int mt9v011_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
 {
        struct v4l2_pix_format *pix = &fmt->fmt.pix;
@@ -393,10 +525,13 @@ static int mt9v011_s_register(struct v4l2_subdev *sd,
 static int mt9v011_g_chip_ident(struct v4l2_subdev *sd,
                                struct v4l2_dbg_chip_ident *chip)
 {
+       u16 version;
        struct i2c_client *client = v4l2_get_subdevdata(sd);
 
+       version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
+
        return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_MT9V011,
-                                         MT9V011_VERSION);
+                                         version);
 }
 
 static const struct v4l2_subdev_core_ops mt9v011_core_ops = {
@@ -416,6 +551,8 @@ static const struct v4l2_subdev_video_ops mt9v011_video_ops = {
        .enum_fmt = mt9v011_enum_fmt,
        .try_fmt = mt9v011_try_fmt,
        .s_fmt = mt9v011_s_fmt,
+       .g_parm = mt9v011_g_parm,
+       .s_parm = mt9v011_s_parm,
 };
 
 static const struct v4l2_subdev_ops mt9v011_ops = {
@@ -449,8 +586,9 @@ static int mt9v011_probe(struct i2c_client *c,
 
        /* Check if the sensor is really a MT9V011 */
        version = mt9v011_read(sd, R00_MT9V011_CHIP_VERSION);
-       if (version != MT9V011_VERSION) {
-               v4l2_info(sd, "*** unknown micron chip detected (0x%04x.\n",
+       if ((version != MT9V011_VERSION) &&
+           (version != MT9V011_REV_B_VERSION)) {
+               v4l2_info(sd, "*** unknown micron chip detected (0x%04x).\n",
                          version);
                kfree(core);
                return -EINVAL;
@@ -461,8 +599,8 @@ static int mt9v011_probe(struct i2c_client *c,
        core->height = 480;
        core->xtal = 27000000;  /* Hz */
 
-       v4l_info(c, "chip found @ 0x%02x (%s)\n",
-                c->addr << 1, c->adapter->name);
+       v4l_info(c, "chip found @ 0x%02x (%s - chip version 0x%04x)\n",
+                c->addr << 1, c->adapter->name, version);
 
        return 0;
 }
index 9e443ee305585ee81da44a604c93d325ec7efd2e..3350fd6083c3d1fa8e40a4f6627f0e61c60968ac 100644 (file)
@@ -30,6 +30,7 @@
 #define R35_MT9V011_GLOBAL_GAIN                0x35
 #define RF1_MT9V011_CHIP_ENABLE                0xf1
 
-#define MT9V011_VERSION                        0x8243
+#define MT9V011_VERSION                        0x8232
+#define MT9V011_REV_B_VERSION          0x8243
 
 #endif
index 2d075205bdfe4b724e22882aa5e6a636edf81cef..736c31d23194525b233966c848ab7cae772c8dc9 100644 (file)
@@ -234,6 +234,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
        return ret;
 }
 
+/* Called under spinlock_irqsave(&pcdev->lock, ...) */
 static void mx1_videobuf_queue(struct videobuf_queue *vq,
                                                struct videobuf_buffer *vb)
 {
@@ -241,13 +242,10 @@ static void mx1_videobuf_queue(struct videobuf_queue *vq,
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
        struct mx1_camera_dev *pcdev = ici->priv;
        struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
-       unsigned long flags;
 
        dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
                vb, vb->baddr, vb->bsize);
 
-       spin_lock_irqsave(&pcdev->lock, flags);
-
        list_add_tail(&vb->queue, &pcdev->capture);
 
        vb->state = VIDEOBUF_ACTIVE;
@@ -264,8 +262,6 @@ static void mx1_videobuf_queue(struct videobuf_queue *vq,
                        __raw_writel(temp, pcdev->base + CSICR1);
                }
        }
-
-       spin_unlock_irqrestore(&pcdev->lock, flags);
 }
 
 static void mx1_videobuf_release(struct videobuf_queue *vq,
index e605c076ed89d43ae5533e98d5d4dc60009dfd19..9770cb7932caeb07fcb36be6568cac021d405094 100644 (file)
@@ -332,7 +332,10 @@ static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
        }
 }
 
-/* Called with .vb_lock held */
+/*
+ * Called with .vb_lock mutex held and
+ * under spinlock_irqsave(&mx3_cam->lock, ...)
+ */
 static void mx3_videobuf_queue(struct videobuf_queue *vq,
                               struct videobuf_buffer *vb)
 {
@@ -346,7 +349,8 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
        struct idmac_video_param *video = &ichan->params.video;
        const struct soc_camera_data_format *data_fmt = icd->current_fmt;
        dma_cookie_t cookie;
-       unsigned long flags;
+
+       BUG_ON(!irqs_disabled());
 
        /* This is the configuration of one sg-element */
        video->out_pixel_fmt    = fourcc_to_ipu_pix(data_fmt->fourcc);
@@ -359,8 +363,6 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
        memset((void *)vb->baddr, 0xaa, vb->bsize);
 #endif
 
-       spin_lock_irqsave(&mx3_cam->lock, flags);
-
        list_add_tail(&vb->queue, &mx3_cam->capture);
 
        if (!mx3_cam->active) {
@@ -370,24 +372,23 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
                vb->state = VIDEOBUF_QUEUED;
        }
 
-       spin_unlock_irqrestore(&mx3_cam->lock, flags);
+       spin_unlock_irq(&mx3_cam->lock);
 
        cookie = txd->tx_submit(txd);
        dev_dbg(&icd->dev, "Submitted cookie %d DMA 0x%08x\n", cookie, sg_dma_address(&buf->sg));
+
+       spin_lock_irq(&mx3_cam->lock);
+
        if (cookie >= 0)
                return;
 
        /* Submit error */
        vb->state = VIDEOBUF_PREPARED;
 
-       spin_lock_irqsave(&mx3_cam->lock, flags);
-
        list_del_init(&vb->queue);
 
        if (mx3_cam->active == buf)
                mx3_cam->active = NULL;
-
-       spin_unlock_irqrestore(&mx3_cam->lock, flags);
 }
 
 /* Called with .vb_lock held */
index 46e0d8ad880fc58e56a3928347e52907f6e70cb7..016bb45ba0c3e2f48e1801651c04dab25c262b74 100644 (file)
@@ -612,6 +612,7 @@ static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
        dev_dbg(pcdev->soc_host.dev, "%s\n", __func__);
 }
 
+/* Called under spinlock_irqsave(&pcdev->lock, ...) */
 static void pxa_videobuf_queue(struct videobuf_queue *vq,
                               struct videobuf_buffer *vb)
 {
@@ -619,13 +620,10 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
        struct pxa_camera_dev *pcdev = ici->priv;
        struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
-       unsigned long flags;
 
        dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d active=%p\n", __func__,
                vb, vb->baddr, vb->bsize, pcdev->active);
 
-       spin_lock_irqsave(&pcdev->lock, flags);
-
        list_add_tail(&vb->queue, &pcdev->capture);
 
        vb->state = VIDEOBUF_ACTIVE;
@@ -633,8 +631,6 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
 
        if (!pcdev->active)
                pxa_camera_start_capture(pcdev);
-
-       spin_unlock_irqrestore(&pcdev->lock, flags);
 }
 
 static void pxa_videobuf_release(struct videobuf_queue *vq,
@@ -1579,6 +1575,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
                pcdev->mclk = 20000000;
        }
 
+       pcdev->soc_host.dev = &pdev->dev;
        pcdev->mclk_divisor = mclk_get_divisor(pcdev);
 
        INIT_LIST_HEAD(&pcdev->capture);
@@ -1644,7 +1641,6 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
        pcdev->soc_host.drv_name        = PXA_CAM_DRV_NAME;
        pcdev->soc_host.ops             = &pxa_soc_camera_host_ops;
        pcdev->soc_host.priv            = pcdev;
-       pcdev->soc_host.dev             = &pdev->dev;
        pcdev->soc_host.nr              = pdev->id;
 
        err = soc_camera_host_register(&pcdev->soc_host);
index 06861b782b9529f503ac26102eb17fc2ddd68908..6eebe3ef97d37efa9f8375eafa53e6b75420f79a 100644 (file)
@@ -3331,8 +3331,8 @@ struct saa7134_board saa7134_boards[] = {
                        .gpio = 0x0200100,
                },
        },
-       [SAA7134_BOARD_HAUPPAUGE_HVR1120] = {
-               .name           = "Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid",
+       [SAA7134_BOARD_HAUPPAUGE_HVR1150] = {
+               .name           = "Hauppauge WinTV-HVR1150 ATSC/QAM-Hybrid",
                .audio_clock    = 0x00187de7,
                .tuner_type     = TUNER_PHILIPS_TDA8290,
                .radio_type     = UNSET,
@@ -3363,8 +3363,8 @@ struct saa7134_board saa7134_boards[] = {
                        .gpio = 0x0800100, /* GPIO 23 HI for FM */
                },
        },
-       [SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = {
-               .name           = "Hauppauge WinTV-HVR1110r3 DVB-T/Hybrid",
+       [SAA7134_BOARD_HAUPPAUGE_HVR1120] = {
+               .name           = "Hauppauge WinTV-HVR1120 DVB-T/Hybrid",
                .audio_clock    = 0x00187de7,
                .tuner_type     = TUNER_PHILIPS_TDA8290,
                .radio_type     = UNSET,
@@ -5862,31 +5862,31 @@ struct pci_device_id saa7134_pci_tbl[] = {
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x0070,
                .subdevice    = 0x6706,
-               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1150,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x0070,
                .subdevice    = 0x6707,
-               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1120,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x0070,
                .subdevice    = 0x6708,
-               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1150,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x0070,
                .subdevice    = 0x6709,
-               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1120,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
                .subvendor    = 0x0070,
                .subdevice    = 0x670a,
-               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+               .driver_data  = SAA7134_BOARD_HAUPPAUGE_HVR1120,
        },{
                .vendor       = PCI_VENDOR_ID_PHILIPS,
                .device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
@@ -6363,8 +6363,8 @@ static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
        switch (command) {
        case TDA18271_CALLBACK_CMD_AGC_ENABLE: /* 0 */
                switch (dev->board) {
+               case SAA7134_BOARD_HAUPPAUGE_HVR1150:
                case SAA7134_BOARD_HAUPPAUGE_HVR1120:
-               case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
                        ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg);
                        break;
                default:
@@ -6384,8 +6384,8 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev,
        int ret;
 
        switch (dev->board) {
+       case SAA7134_BOARD_HAUPPAUGE_HVR1150:
        case SAA7134_BOARD_HAUPPAUGE_HVR1120:
-       case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
                /* tda8290 + tda18271 */
                ret = saa7134_tda8290_18271_callback(dev, command, arg);
                break;
@@ -6427,7 +6427,7 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data)
        switch (tv.model) {
        case 67019: /* WinTV-HVR1110 (Retail, IR Blaster, hybrid, FM, SVid/Comp, 3.5mm audio in) */
        case 67109: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */
-       case 67201: /* WinTV-HVR1120 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
+       case 67201: /* WinTV-HVR1150 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
        case 67301: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */
        case 67209: /* WinTV-HVR1110 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
        case 67559: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
@@ -6435,7 +6435,7 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data)
        case 67579: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM) */
        case 67589: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */
        case 67599: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */
-       case 67651: /* WinTV-HVR1120 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
+       case 67651: /* WinTV-HVR1150 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
        case 67659: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
                break;
        default:
@@ -6625,8 +6625,8 @@ int saa7134_board_init1(struct saa7134_dev *dev)
 
                saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00);
                break;
+       case SAA7134_BOARD_HAUPPAUGE_HVR1150:
        case SAA7134_BOARD_HAUPPAUGE_HVR1120:
-       case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
                /* GPIO 26 high for digital, low for analog */
                saa7134_set_gpio(dev, 26, 0);
                msleep(1);
@@ -6891,8 +6891,8 @@ int saa7134_board_init2(struct saa7134_dev *dev)
                       dev->name, saa7134_boards[dev->board].name);
               }
               break;
+       case SAA7134_BOARD_HAUPPAUGE_HVR1150:
        case SAA7134_BOARD_HAUPPAUGE_HVR1120:
-       case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
                hauppauge_eeprom(dev, dev->eedata+0x80);
                break;
        case SAA7134_BOARD_HAUPPAUGE_HVR1110:
index 31930f26ffc7d5963aab8d24c7b3a70c918a62e3..98f3efd1e944defe96509f6b6dcb8b79ef00a47c 100644 (file)
@@ -1119,7 +1119,7 @@ static int dvb_init(struct saa7134_dev *dev)
                                         &tda827x_cfg_2) < 0)
                        goto dettach_frontend;
                break;
-       case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+       case SAA7134_BOARD_HAUPPAUGE_HVR1120:
                fe0->dvb.frontend = dvb_attach(tda10048_attach,
                                               &hcw_tda10048_config,
                                               &dev->i2c_adap);
@@ -1147,7 +1147,7 @@ static int dvb_init(struct saa7134_dev *dev)
                                         &tda827x_cfg_1) < 0)
                        goto dettach_frontend;
                break;
-       case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+       case SAA7134_BOARD_HAUPPAUGE_HVR1150:
                fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
                                               &hcw_lgdt3305_config,
                                               &dev->i2c_adap);
index 82268848f26a4cc8817e17f7a6c5a4281a6952d4..fb564f14887cc0e814f0adcb29a738595cea937c 100644 (file)
@@ -278,8 +278,8 @@ struct saa7134_format {
 #define SAA7134_BOARD_ASUSTeK_TIGER         152
 #define SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG 153
 #define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154
-#define SAA7134_BOARD_HAUPPAUGE_HVR1120     155
-#define SAA7134_BOARD_HAUPPAUGE_HVR1110R3   156
+#define SAA7134_BOARD_HAUPPAUGE_HVR1150     155
+#define SAA7134_BOARD_HAUPPAUGE_HVR1120   156
 #define SAA7134_BOARD_AVERMEDIA_STUDIO_507UA 157
 #define SAA7134_BOARD_AVERMEDIA_CARDBUS_501 158
 #define SAA7134_BOARD_BEHOLD_505RDS         159
index 0db88a53d92c54c60830862c6867d4dbe175bdcb..e86878deea71771d16decce32551f8ae78cfe88b 100644 (file)
@@ -282,27 +282,24 @@ out:
        return ret;
 }
 
+/* Called under spinlock_irqsave(&pcdev->lock, ...) */
 static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
                                         struct videobuf_buffer *vb)
 {
        struct soc_camera_device *icd = vq->priv_data;
        struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
        struct sh_mobile_ceu_dev *pcdev = ici->priv;
-       unsigned long flags;
 
        dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
                vb, vb->baddr, vb->bsize);
 
        vb->state = VIDEOBUF_QUEUED;
-       spin_lock_irqsave(&pcdev->lock, flags);
        list_add_tail(&vb->queue, &pcdev->capture);
 
        if (!pcdev->active) {
                pcdev->active = vb;
                sh_mobile_ceu_capture(pcdev);
        }
-
-       spin_unlock_irqrestore(&pcdev->lock, flags);
 }
 
 static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq,
index 4d6785e634556fbba9bc87a89708302907f40a0c..b154bd961e3b74472d7efccf367c8447004d0f84 100644 (file)
@@ -1050,8 +1050,8 @@ static int stk_setup_format(struct stk_camera *dev)
                depth = 1;
        else
                depth = 2;
-       while (stk_sizes[i].m != dev->vsettings.mode
-                       && i < ARRAY_SIZE(stk_sizes))
+       while (i < ARRAY_SIZE(stk_sizes) &&
+                       stk_sizes[i].m != dev->vsettings.mode)
                i++;
        if (i == ARRAY_SIZE(stk_sizes)) {
                STK_ERROR("Something is broken in %s\n", __func__);
index 89927b7aec28dce2dcd9131b7e36339de826436d..04b47832fa0a5d1d416cdf429cf9e320a69fc59f 100644 (file)
@@ -1845,11 +1845,29 @@ static struct usb_device_id uvc_ids[] = {
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
          .driver_info          = UVC_QUIRK_STREAM_NO_FID },
-       /* ViMicro */
-       { .match_flags          = USB_DEVICE_ID_MATCH_VENDOR
+       /* ViMicro Vega */
+       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+                               | USB_DEVICE_ID_MATCH_INT_INFO,
+         .idVendor             = 0x0ac8,
+         .idProduct            = 0x332d,
+         .bInterfaceClass      = USB_CLASS_VIDEO,
+         .bInterfaceSubClass   = 1,
+         .bInterfaceProtocol   = 0,
+         .driver_info          = UVC_QUIRK_FIX_BANDWIDTH },
+       /* ViMicro - Minoru3D */
+       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
+                               | USB_DEVICE_ID_MATCH_INT_INFO,
+         .idVendor             = 0x0ac8,
+         .idProduct            = 0x3410,
+         .bInterfaceClass      = USB_CLASS_VIDEO,
+         .bInterfaceSubClass   = 1,
+         .bInterfaceProtocol   = 0,
+         .driver_info          = UVC_QUIRK_FIX_BANDWIDTH },
+       /* ViMicro Venus - Minoru3D */
+       { .match_flags          = USB_DEVICE_ID_MATCH_DEVICE
                                | USB_DEVICE_ID_MATCH_INT_INFO,
          .idVendor             = 0x0ac8,
-         .idProduct            = 0x0000,
+         .idProduct            = 0x3420,
          .bInterfaceClass      = USB_CLASS_VIDEO,
          .bInterfaceSubClass   = 1,
          .bInterfaceProtocol   = 0,
index f152a9903862abe4780eebe67ba282f2bf6d9eac..1ca6dff7361241069f2a05ba4631bb00ec5b11d5 100644 (file)
@@ -145,8 +145,8 @@ static void uvc_status_complete(struct urb *urb)
                        break;
 
                default:
-                       uvc_printk(KERN_INFO, "unknown event type %u.\n",
-                               dev->status[0]);
+                       uvc_trace(UVC_TRACE_STATUS, "Unknown status event "
+                               "type %u.\n", dev->status[0]);
                        break;
                }
        }
index be64a502ea276e5a49ee3c97bea6d3f9a52a2fec..f2afc4e08379a1cee0c77201190dd698db576fbb 100644 (file)
@@ -1081,8 +1081,10 @@ static long __video_do_ioctl(struct file *file,
                /* Calls the specific handler */
                if (ops->vidioc_g_std)
                        ret = ops->vidioc_g_std(file, fh, id);
-               else
+               else if (vfd->current_norm)
                        *id = vfd->current_norm;
+               else
+                       ret = -EINVAL;
 
                if (!ret)
                        dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
@@ -1553,12 +1555,19 @@ static long __video_do_ioctl(struct file *file,
                                break;
                        ret = ops->vidioc_g_parm(file, fh, p);
                } else {
+                       v4l2_std_id std = vfd->current_norm;
+
                        if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
                                return -EINVAL;
 
-                       v4l2_video_std_frame_period(vfd->current_norm,
-                                                   &p->parm.capture.timeperframe);
                        ret = 0;
+                       if (ops->vidioc_g_std)
+                               ret = ops->vidioc_g_std(file, fh, &std);
+                       else if (std == 0)
+                               ret = -EINVAL;
+                       if (ret == 0)
+                               v4l2_video_std_frame_period(std,
+                                                   &p->parm.capture.timeperframe);
                }
 
                dbgarg(cmd, "type=%d\n", p->type);
index c204168509486ddf758915a23863fcaf9397dc40..45675889850b419201314f3ed5c7edb16cda0315 100644 (file)
@@ -235,6 +235,7 @@ enum vortex_chips {
        CH_3C900B_FL,
        CH_3C905_1,
        CH_3C905_2,
+       CH_3C905B_TX,
        CH_3C905B_1,
 
        CH_3C905B_2,
@@ -307,6 +308,8 @@ static struct vortex_chip_info {
         PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, },
        {"3c905 Boomerang 100baseT4",
         PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, },
+       {"3C905B-TX Fast Etherlink XL PCI",
+        PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
        {"3c905B Cyclone 100baseTx",
         PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
 
@@ -389,6 +392,7 @@ static struct pci_device_id vortex_pci_tbl[] = {
        { 0x10B7, 0x900A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C900B_FL },
        { 0x10B7, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905_1 },
        { 0x10B7, 0x9051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905_2 },
+       { 0x10B7, 0x9054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_TX },
        { 0x10B7, 0x9055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_1 },
 
        { 0x10B7, 0x9058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_2 },
index 50efde11ea6c8790e8f0e679d9faaeb15e40f6f6..d0dbbf39349a3cb87d6eb19c51591bb736c9b9f5 100644 (file)
@@ -515,7 +515,7 @@ rx_status_loop:
                dma_addr_t mapping;
                struct sk_buff *skb, *new_skb;
                struct cp_desc *desc;
-               unsigned buflen;
+               const unsigned buflen = cp->rx_buf_sz;
 
                skb = cp->rx_skb[rx_tail];
                BUG_ON(!skb);
@@ -549,8 +549,7 @@ rx_status_loop:
                        pr_debug("%s: rx slot %d status 0x%x len %d\n",
                               dev->name, rx_tail, status, len);
 
-               buflen = cp->rx_buf_sz + NET_IP_ALIGN;
-               new_skb = netdev_alloc_skb(dev, buflen);
+               new_skb = netdev_alloc_skb(dev, buflen + NET_IP_ALIGN);
                if (!new_skb) {
                        dev->stats.rx_dropped++;
                        goto rx_next;
index 607007d75b6fa82f5e2cd6e8328985ef10102c49..00d11b480af30b48956bb1633a329f282c584222 100644 (file)
@@ -232,11 +232,11 @@ static void atl1c_get_drvinfo(struct net_device *netdev,
 {
        struct atl1c_adapter *adapter = netdev_priv(netdev);
 
-       strncpy(drvinfo->driver,  atl1c_driver_name, sizeof(drvinfo->driver));
-       strncpy(drvinfo->version, atl1c_driver_version,
+       strlcpy(drvinfo->driver,  atl1c_driver_name, sizeof(drvinfo->driver));
+       strlcpy(drvinfo->version, atl1c_driver_version,
                sizeof(drvinfo->version));
-       strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
-       strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
+       strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+       strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
                sizeof(drvinfo->bus_info));
        drvinfo->n_stats = 0;
        drvinfo->testinfo_len = 0;
index 94d7325caf4ffc5a893c274dc3cf56a0e957897a..8bca12f71390db026025bb25eca3d76640223268 100644 (file)
@@ -3378,11 +3378,11 @@ static void atl1_get_drvinfo(struct net_device *netdev,
 {
        struct atl1_adapter *adapter = netdev_priv(netdev);
 
-       strncpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver));
-       strncpy(drvinfo->version, ATLX_DRIVER_VERSION,
+       strlcpy(drvinfo->driver, ATLX_DRIVER_NAME, sizeof(drvinfo->driver));
+       strlcpy(drvinfo->version, ATLX_DRIVER_VERSION,
                sizeof(drvinfo->version));
-       strncpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
-       strncpy(drvinfo->bus_info, pci_name(adapter->pdev),
+       strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+       strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
                sizeof(drvinfo->bus_info));
        drvinfo->eedump_len = ATL1_EEDUMP_LEN;
 }
index 36d4d377ec2fc5df3a78a96f609aa6055e7ad167..bafca672ea7d7d2857bc52b17bfe051cea8b4716 100644 (file)
@@ -952,9 +952,10 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
        int rc = NETDEV_TX_OK;
        dma_addr_t mapping;
        u32 len, entry, ctrl;
+       unsigned long flags;
 
        len = skb->len;
-       spin_lock_irq(&bp->lock);
+       spin_lock_irqsave(&bp->lock, flags);
 
        /* This is a hard error, log it. */
        if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
@@ -1027,7 +1028,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
        dev->trans_start = jiffies;
 
 out_unlock:
-       spin_unlock_irq(&bp->lock);
+       spin_unlock_irqrestore(&bp->lock, flags);
 
        return rc;
 
index b70cc99962fcfcf6ccb655213ccf0f1f0225fa89..06b901152d4487fa04164437cc179661b44657fe 100644 (file)
@@ -399,9 +399,11 @@ static int bnx2_unregister_cnic(struct net_device *dev)
        struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
        struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
 
+       mutex_lock(&bp->cnic_lock);
        cp->drv_state = 0;
        bnapi->cnic_present = 0;
        rcu_assign_pointer(bp->cnic_ops, NULL);
+       mutex_unlock(&bp->cnic_lock);
        synchronize_rcu();
        return 0;
 }
@@ -429,13 +431,13 @@ bnx2_cnic_stop(struct bnx2 *bp)
        struct cnic_ops *c_ops;
        struct cnic_ctl_info info;
 
-       rcu_read_lock();
-       c_ops = rcu_dereference(bp->cnic_ops);
+       mutex_lock(&bp->cnic_lock);
+       c_ops = bp->cnic_ops;
        if (c_ops) {
                info.cmd = CNIC_CTL_STOP_CMD;
                c_ops->cnic_ctl(bp->cnic_data, &info);
        }
-       rcu_read_unlock();
+       mutex_unlock(&bp->cnic_lock);
 }
 
 static void
@@ -444,8 +446,8 @@ bnx2_cnic_start(struct bnx2 *bp)
        struct cnic_ops *c_ops;
        struct cnic_ctl_info info;
 
-       rcu_read_lock();
-       c_ops = rcu_dereference(bp->cnic_ops);
+       mutex_lock(&bp->cnic_lock);
+       c_ops = bp->cnic_ops;
        if (c_ops) {
                if (!(bp->flags & BNX2_FLAG_USING_MSIX)) {
                        struct bnx2_napi *bnapi = &bp->bnx2_napi[0];
@@ -455,7 +457,7 @@ bnx2_cnic_start(struct bnx2 *bp)
                info.cmd = CNIC_CTL_START_CMD;
                c_ops->cnic_ctl(bp->cnic_data, &info);
        }
-       rcu_read_unlock();
+       mutex_unlock(&bp->cnic_lock);
 }
 
 #else
@@ -7663,6 +7665,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 
        spin_lock_init(&bp->phy_lock);
        spin_lock_init(&bp->indirect_lock);
+#ifdef BCM_CNIC
+       mutex_init(&bp->cnic_lock);
+#endif
        INIT_WORK(&bp->reset_task, bnx2_reset_task);
 
        dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0);
index f1edfaa9e56acd87afd0cb41aa20cd23248f7880..a4f12fd0ecd214cdea03039a5af5a0c69e1a8e2e 100644 (file)
@@ -6902,6 +6902,7 @@ struct bnx2 {
        u32                     idle_chk_status_idx;
 
 #ifdef BCM_CNIC
+       struct mutex            cnic_lock;
        struct cnic_eth_dev     cnic_eth_dev;
 #endif
 
index 9e4283aff828d9adc1f03db2276b38add2b9a31d..e1a4f8214239059ce079480bd4b2a5f08bd167c2 100644 (file)
@@ -611,11 +611,18 @@ nla_put_failure:
        return -EMSGSIZE;
 }
 
+static int can_newlink(struct net_device *dev,
+                      struct nlattr *tb[], struct nlattr *data[])
+{
+       return -EOPNOTSUPP;
+}
+
 static struct rtnl_link_ops can_link_ops __read_mostly = {
        .kind           = "can",
        .maxtype        = IFLA_CAN_MAX,
        .policy         = can_policy,
        .setup          = can_setup,
+       .newlink        = can_newlink,
        .changelink     = can_changelink,
        .fill_info      = can_fill_info,
        .fill_xstats    = can_fill_xstats,
index 4869d77cbe91dc9fde5cee6b82babc8f50517ff7..74c342959b7bdf98072311fd371b5e78d302b7e0 100644 (file)
@@ -138,6 +138,16 @@ static struct cnic_dev *cnic_from_netdev(struct net_device *netdev)
        return NULL;
 }
 
+static inline void ulp_get(struct cnic_ulp_ops *ulp_ops)
+{
+       atomic_inc(&ulp_ops->ref_count);
+}
+
+static inline void ulp_put(struct cnic_ulp_ops *ulp_ops)
+{
+       atomic_dec(&ulp_ops->ref_count);
+}
+
 static void cnic_ctx_wr(struct cnic_dev *dev, u32 cid_addr, u32 off, u32 val)
 {
        struct cnic_local *cp = dev->cnic_priv;
@@ -358,6 +368,7 @@ int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops)
        }
        read_unlock(&cnic_dev_lock);
 
+       atomic_set(&ulp_ops->ref_count, 0);
        rcu_assign_pointer(cnic_ulp_tbl[ulp_type], ulp_ops);
        mutex_unlock(&cnic_lock);
 
@@ -379,6 +390,8 @@ int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops)
 int cnic_unregister_driver(int ulp_type)
 {
        struct cnic_dev *dev;
+       struct cnic_ulp_ops *ulp_ops;
+       int i = 0;
 
        if (ulp_type >= MAX_CNIC_ULP_TYPE) {
                printk(KERN_ERR PFX "cnic_unregister_driver: Bad type %d\n",
@@ -386,7 +399,8 @@ int cnic_unregister_driver(int ulp_type)
                return -EINVAL;
        }
        mutex_lock(&cnic_lock);
-       if (!cnic_ulp_tbl[ulp_type]) {
+       ulp_ops = cnic_ulp_tbl[ulp_type];
+       if (!ulp_ops) {
                printk(KERN_ERR PFX "cnic_unregister_driver: Type %d has not "
                                    "been registered\n", ulp_type);
                goto out_unlock;
@@ -411,6 +425,14 @@ int cnic_unregister_driver(int ulp_type)
 
        mutex_unlock(&cnic_lock);
        synchronize_rcu();
+       while ((atomic_read(&ulp_ops->ref_count) != 0) && (i < 20)) {
+               msleep(100);
+               i++;
+       }
+
+       if (atomic_read(&ulp_ops->ref_count) != 0)
+               printk(KERN_WARNING PFX "%s: Failed waiting for ref count to go"
+                                       " to zero.\n", dev->netdev->name);
        return 0;
 
 out_unlock:
@@ -466,6 +488,7 @@ EXPORT_SYMBOL(cnic_register_driver);
 static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
 {
        struct cnic_local *cp = dev->cnic_priv;
+       int i = 0;
 
        if (ulp_type >= MAX_CNIC_ULP_TYPE) {
                printk(KERN_ERR PFX "cnic_unregister_device: Bad type %d\n",
@@ -486,6 +509,15 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)
 
        synchronize_rcu();
 
+       while (test_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[ulp_type]) &&
+              i < 20) {
+               msleep(100);
+               i++;
+       }
+       if (test_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[ulp_type]))
+               printk(KERN_WARNING PFX "%s: Failed waiting for ULP up call"
+                                       " to complete.\n", dev->netdev->name);
+
        return 0;
 }
 EXPORT_SYMBOL(cnic_unregister_driver);
@@ -1076,18 +1108,23 @@ static void cnic_ulp_stop(struct cnic_dev *dev)
        if (cp->cnic_uinfo)
                cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
 
-       rcu_read_lock();
        for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
                struct cnic_ulp_ops *ulp_ops;
 
-               ulp_ops = rcu_dereference(cp->ulp_ops[if_type]);
-               if (!ulp_ops)
+               mutex_lock(&cnic_lock);
+               ulp_ops = cp->ulp_ops[if_type];
+               if (!ulp_ops) {
+                       mutex_unlock(&cnic_lock);
                        continue;
+               }
+               set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
+               mutex_unlock(&cnic_lock);
 
                if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type]))
                        ulp_ops->cnic_stop(cp->ulp_handle[if_type]);
+
+               clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
        }
-       rcu_read_unlock();
 }
 
 static void cnic_ulp_start(struct cnic_dev *dev)
@@ -1095,18 +1132,23 @@ static void cnic_ulp_start(struct cnic_dev *dev)
        struct cnic_local *cp = dev->cnic_priv;
        int if_type;
 
-       rcu_read_lock();
        for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
                struct cnic_ulp_ops *ulp_ops;
 
-               ulp_ops = rcu_dereference(cp->ulp_ops[if_type]);
-               if (!ulp_ops || !ulp_ops->cnic_start)
+               mutex_lock(&cnic_lock);
+               ulp_ops = cp->ulp_ops[if_type];
+               if (!ulp_ops || !ulp_ops->cnic_start) {
+                       mutex_unlock(&cnic_lock);
                        continue;
+               }
+               set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
+               mutex_unlock(&cnic_lock);
 
                if (!test_and_set_bit(ULP_F_START, &cp->ulp_flags[if_type]))
                        ulp_ops->cnic_start(cp->ulp_handle[if_type]);
+
+               clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
        }
-       rcu_read_unlock();
 }
 
 static int cnic_ctl(void *data, struct cnic_ctl_info *info)
@@ -1116,22 +1158,18 @@ static int cnic_ctl(void *data, struct cnic_ctl_info *info)
        switch (info->cmd) {
        case CNIC_CTL_STOP_CMD:
                cnic_hold(dev);
-               mutex_lock(&cnic_lock);
 
                cnic_ulp_stop(dev);
                cnic_stop_hw(dev);
 
-               mutex_unlock(&cnic_lock);
                cnic_put(dev);
                break;
        case CNIC_CTL_START_CMD:
                cnic_hold(dev);
-               mutex_lock(&cnic_lock);
 
                if (!cnic_start_hw(dev))
                        cnic_ulp_start(dev);
 
-               mutex_unlock(&cnic_lock);
                cnic_put(dev);
                break;
        default:
@@ -1145,19 +1183,23 @@ static void cnic_ulp_init(struct cnic_dev *dev)
        int i;
        struct cnic_local *cp = dev->cnic_priv;
 
-       rcu_read_lock();
        for (i = 0; i < MAX_CNIC_ULP_TYPE_EXT; i++) {
                struct cnic_ulp_ops *ulp_ops;
 
-               ulp_ops = rcu_dereference(cnic_ulp_tbl[i]);
-               if (!ulp_ops || !ulp_ops->cnic_init)
+               mutex_lock(&cnic_lock);
+               ulp_ops = cnic_ulp_tbl[i];
+               if (!ulp_ops || !ulp_ops->cnic_init) {
+                       mutex_unlock(&cnic_lock);
                        continue;
+               }
+               ulp_get(ulp_ops);
+               mutex_unlock(&cnic_lock);
 
                if (!test_and_set_bit(ULP_F_INIT, &cp->ulp_flags[i]))
                        ulp_ops->cnic_init(dev);
 
+               ulp_put(ulp_ops);
        }
-       rcu_read_unlock();
 }
 
 static void cnic_ulp_exit(struct cnic_dev *dev)
@@ -1165,19 +1207,23 @@ static void cnic_ulp_exit(struct cnic_dev *dev)
        int i;
        struct cnic_local *cp = dev->cnic_priv;
 
-       rcu_read_lock();
        for (i = 0; i < MAX_CNIC_ULP_TYPE_EXT; i++) {
                struct cnic_ulp_ops *ulp_ops;
 
-               ulp_ops = rcu_dereference(cnic_ulp_tbl[i]);
-               if (!ulp_ops || !ulp_ops->cnic_exit)
+               mutex_lock(&cnic_lock);
+               ulp_ops = cnic_ulp_tbl[i];
+               if (!ulp_ops || !ulp_ops->cnic_exit) {
+                       mutex_unlock(&cnic_lock);
                        continue;
+               }
+               ulp_get(ulp_ops);
+               mutex_unlock(&cnic_lock);
 
                if (test_and_clear_bit(ULP_F_INIT, &cp->ulp_flags[i]))
                        ulp_ops->cnic_exit(dev);
 
+               ulp_put(ulp_ops);
        }
-       rcu_read_unlock();
 }
 
 static int cnic_cm_offload_pg(struct cnic_sock *csk)
@@ -2393,21 +2439,45 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)
        return 0;
 }
 
-static int cnic_start_hw(struct cnic_dev *dev)
+static int cnic_register_netdev(struct cnic_dev *dev)
 {
        struct cnic_local *cp = dev->cnic_priv;
        struct cnic_eth_dev *ethdev = cp->ethdev;
        int err;
 
-       if (test_bit(CNIC_F_CNIC_UP, &dev->flags))
-               return -EALREADY;
+       if (!ethdev)
+               return -ENODEV;
+
+       if (ethdev->drv_state & CNIC_DRV_STATE_REGD)
+               return 0;
 
        err = ethdev->drv_register_cnic(dev->netdev, cp->cnic_ops, dev);
-       if (err) {
+       if (err)
                printk(KERN_ERR PFX "%s: register_cnic failed\n",
                       dev->netdev->name);
-               goto err2;
-       }
+
+       return err;
+}
+
+static void cnic_unregister_netdev(struct cnic_dev *dev)
+{
+       struct cnic_local *cp = dev->cnic_priv;
+       struct cnic_eth_dev *ethdev = cp->ethdev;
+
+       if (!ethdev)
+               return;
+
+       ethdev->drv_unregister_cnic(dev->netdev);
+}
+
+static int cnic_start_hw(struct cnic_dev *dev)
+{
+       struct cnic_local *cp = dev->cnic_priv;
+       struct cnic_eth_dev *ethdev = cp->ethdev;
+       int err;
+
+       if (test_bit(CNIC_F_CNIC_UP, &dev->flags))
+               return -EALREADY;
 
        dev->regview = ethdev->io_base;
        cp->chip_id = ethdev->chip_id;
@@ -2438,18 +2508,13 @@ static int cnic_start_hw(struct cnic_dev *dev)
        return 0;
 
 err1:
-       ethdev->drv_unregister_cnic(dev->netdev);
        cp->free_resc(dev);
        pci_dev_put(dev->pcidev);
-err2:
        return err;
 }
 
 static void cnic_stop_bnx2_hw(struct cnic_dev *dev)
 {
-       struct cnic_local *cp = dev->cnic_priv;
-       struct cnic_eth_dev *ethdev = cp->ethdev;
-
        cnic_disable_bnx2_int_sync(dev);
 
        cnic_reg_wr_ind(dev, BNX2_CP_SCRATCH + 0x20, 0);
@@ -2461,8 +2526,6 @@ static void cnic_stop_bnx2_hw(struct cnic_dev *dev)
        cnic_setup_5709_context(dev, 0);
        cnic_free_irq(dev);
 
-       ethdev->drv_unregister_cnic(dev->netdev);
-
        cnic_free_resc(dev);
 }
 
@@ -2543,7 +2606,7 @@ static struct cnic_dev *init_bnx2_cnic(struct net_device *dev)
        probe = symbol_get(bnx2_cnic_probe);
        if (probe) {
                ethdev = (*probe)(dev);
-               symbol_put_addr(probe);
+               symbol_put(bnx2_cnic_probe);
        }
        if (!ethdev)
                return NULL;
@@ -2646,10 +2709,12 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
                else if (event == NETDEV_UNREGISTER)
                        cnic_ulp_exit(dev);
                else if (event == NETDEV_UP) {
-                       mutex_lock(&cnic_lock);
+                       if (cnic_register_netdev(dev) != 0) {
+                               cnic_put(dev);
+                               goto done;
+                       }
                        if (!cnic_start_hw(dev))
                                cnic_ulp_start(dev);
-                       mutex_unlock(&cnic_lock);
                }
 
                rcu_read_lock();
@@ -2668,10 +2733,9 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
                rcu_read_unlock();
 
                if (event == NETDEV_GOING_DOWN) {
-                       mutex_lock(&cnic_lock);
                        cnic_ulp_stop(dev);
                        cnic_stop_hw(dev);
-                       mutex_unlock(&cnic_lock);
+                       cnic_unregister_netdev(dev);
                } else if (event == NETDEV_UNREGISTER) {
                        write_lock(&cnic_dev_lock);
                        list_del_init(&dev->list);
@@ -2703,6 +2767,7 @@ static void cnic_release(void)
                }
 
                cnic_ulp_exit(dev);
+               cnic_unregister_netdev(dev);
                list_del_init(&dev->list);
                cnic_free_dev(dev);
        }
index 5192d4a9df5a5d56a48e22632a2fa75badb9e4fb..a94b302bb4648d751053b8cc8eea98473c12c1f6 100644 (file)
@@ -176,6 +176,7 @@ struct cnic_local {
        unsigned long ulp_flags[MAX_CNIC_ULP_TYPE];
 #define ULP_F_INIT     0
 #define ULP_F_START    1
+#define ULP_F_CALL_PENDING     2
        struct cnic_ulp_ops *ulp_ops[MAX_CNIC_ULP_TYPE];
 
        /* protected by ulp_lock */
index d1bce27ee99e9a28dc42f1773e889f88fd0b60f6..a49235739eef9444d1596df5dfb5248a4aba8a1e 100644 (file)
@@ -290,6 +290,7 @@ struct cnic_ulp_ops {
        void (*iscsi_nl_send_msg)(struct cnic_dev *dev, u32 msg_type,
                                  char *data, u16 data_size);
        struct module *owner;
+       atomic_t ref_count;
 };
 
 extern int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops);
index d56c7473144a6cd974a253b16033ad447081b3f9..99df2abf82a956d52d0e80658f0e655cb8cfe89d 100644 (file)
@@ -338,10 +338,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
 {
        struct e1000_nvm_info *nvm = &hw->nvm;
        struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
-       union ich8_hws_flash_status hsfsts;
-       u32 gfpreg;
-       u32 sector_base_addr;
-       u32 sector_end_addr;
+       u32 gfpreg, sector_base_addr, sector_end_addr;
        u16 i;
 
        /* Can't read flash registers if the register set isn't mapped. */
@@ -375,20 +372,6 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
        /* Adjust to word count */
        nvm->flash_bank_size /= sizeof(u16);
 
-       /*
-        * Make sure the flash bank size does not overwrite the 4k
-        * sector ranges. We may have 64k allotted to us but we only care
-        * about the first 2 4k sectors. Therefore, if we have anything less
-        * than 64k set in the HSFSTS register, we will reduce the bank size
-        * down to 4k and let the rest remain unused. If berasesz == 3, then
-        * we are working in 64k mode. Otherwise we are not.
-        */
-       if (nvm->flash_bank_size > E1000_ICH8_SHADOW_RAM_WORDS) {
-               hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
-               if (hsfsts.hsf_status.berasesz != 3)
-                       nvm->flash_bank_size = E1000_ICH8_SHADOW_RAM_WORDS;
-       }
-
        nvm->word_size = E1000_ICH8_SHADOW_RAM_WORDS;
 
        /* Clear shadow ram */
@@ -594,8 +577,8 @@ static DEFINE_MUTEX(nvm_mutex);
  **/
 static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
 {
-       u32 extcnf_ctrl;
-       u32 timeout = PHY_CFG_TIMEOUT;
+       u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT;
+       s32 ret_val = 0;
 
        might_sleep();
 
@@ -603,28 +586,46 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
 
        while (timeout) {
                extcnf_ctrl = er32(EXTCNF_CTRL);
+               if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG))
+                       break;
 
-               if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) {
-                       extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
-                       ew32(EXTCNF_CTRL, extcnf_ctrl);
+               mdelay(1);
+               timeout--;
+       }
+
+       if (!timeout) {
+               hw_dbg(hw, "SW/FW/HW has locked the resource for too long.\n");
+               ret_val = -E1000_ERR_CONFIG;
+               goto out;
+       }
+
+       timeout = PHY_CFG_TIMEOUT * 2;
+
+       extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
+       ew32(EXTCNF_CTRL, extcnf_ctrl);
+
+       while (timeout) {
+               extcnf_ctrl = er32(EXTCNF_CTRL);
+               if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
+                       break;
 
-                       extcnf_ctrl = er32(EXTCNF_CTRL);
-                       if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
-                               break;
-               }
                mdelay(1);
                timeout--;
        }
 
        if (!timeout) {
-               hw_dbg(hw, "FW or HW has locked the resource for too long.\n");
+               hw_dbg(hw, "Failed to acquire the semaphore.\n");
                extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
                ew32(EXTCNF_CTRL, extcnf_ctrl);
-               mutex_unlock(&nvm_mutex);
-               return -E1000_ERR_CONFIG;
+               ret_val = -E1000_ERR_CONFIG;
+               goto out;
        }
 
-       return 0;
+out:
+       if (ret_val)
+               mutex_unlock(&nvm_mutex);
+
+       return ret_val;
 }
 
 /**
@@ -1306,7 +1307,7 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
        struct e1000_nvm_info *nvm = &hw->nvm;
        struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
        u32 act_offset;
-       s32 ret_val;
+       s32 ret_val = 0;
        u32 bank = 0;
        u16 i, word;
 
@@ -1321,12 +1322,15 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
                goto out;
 
        ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
-       if (ret_val)
-               goto release;
+       if (ret_val) {
+               hw_dbg(hw, "Could not detect valid bank, assuming bank 0\n");
+               bank = 0;
+       }
 
        act_offset = (bank) ? nvm->flash_bank_size : 0;
        act_offset += offset;
 
+       ret_val = 0;
        for (i = 0; i < words; i++) {
                if ((dev_spec->shadow_ram) &&
                    (dev_spec->shadow_ram[offset+i].modified)) {
@@ -1341,7 +1345,6 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
                }
        }
 
-release:
        e1000_release_swflag_ich8lan(hw);
 
 out:
@@ -1592,7 +1595,6 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
 {
        struct e1000_nvm_info *nvm = &hw->nvm;
        struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
-       s32 ret_val;
        u16 i;
 
        if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) ||
@@ -1601,17 +1603,11 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
                return -E1000_ERR_NVM;
        }
 
-       ret_val = e1000_acquire_swflag_ich8lan(hw);
-       if (ret_val)
-               return ret_val;
-
        for (i = 0; i < words; i++) {
                dev_spec->shadow_ram[offset+i].modified = 1;
                dev_spec->shadow_ram[offset+i].value = data[i];
        }
 
-       e1000_release_swflag_ich8lan(hw);
-
        return 0;
 }
 
@@ -1652,8 +1648,8 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
         */
        ret_val =  e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
        if (ret_val) {
-               e1000_release_swflag_ich8lan(hw);
-               goto out;
+               hw_dbg(hw, "Could not detect valid bank, assuming bank 0\n");
+               bank = 0;
        }
 
        if (bank == 0) {
@@ -2039,12 +2035,8 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
                iteration = 1;
                break;
        case 2:
-               if (hw->mac.type == e1000_ich9lan) {
-                       sector_size = ICH_FLASH_SEG_SIZE_8K;
-                       iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_8K;
-               } else {
-                       return -E1000_ERR_NVM;
-               }
+               sector_size = ICH_FLASH_SEG_SIZE_8K;
+               iteration = 1;
                break;
        case 3:
                sector_size = ICH_FLASH_SEG_SIZE_64K;
@@ -2056,7 +2048,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
 
        /* Start with the base address, then add the sector offset. */
        flash_linear_addr = hw->nvm.flash_base_addr;
-       flash_linear_addr += (bank) ? (sector_size * iteration) : 0;
+       flash_linear_addr += (bank) ? flash_bank_size : 0;
 
        for (j = 0; j < iteration ; j++) {
                do {
index 63415bb6f48ff02f3e2e67ec45fef854fc1b9f39..fa92a683aefd3944d65cf5d6c72e042c6d34281d 100644 (file)
@@ -4538,8 +4538,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
                /* Allow time for pending master requests to run */
                e1000e_disable_pcie_master(&adapter->hw);
 
-               if ((adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) &&
-                   !(hw->mac.ops.check_mng_mode(hw))) {
+               if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
                        /* enable wakeup by the PHY */
                        retval = e1000_init_phy_wakeup(adapter, wufc);
                        if (retval)
@@ -4557,7 +4556,8 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
        *enable_wake = !!wufc;
 
        /* make sure adapter isn't asleep if manageability is enabled */
-       if (adapter->flags & FLAG_MNG_PT_ENABLED)
+       if ((adapter->flags & FLAG_MNG_PT_ENABLED) ||
+           (hw->mac.ops.check_mng_mode(hw)))
                *enable_wake = true;
 
        if (adapter->hw.phy.type == e1000_phy_igp_3)
@@ -4670,14 +4670,6 @@ static int e1000_resume(struct pci_dev *pdev)
                return err;
        }
 
-       /* AER (Advanced Error Reporting) hooks */
-       err = pci_enable_pcie_error_reporting(pdev);
-       if (err) {
-               dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
-                                   "0x%x\n", err);
-               /* non-fatal, continue */
-       }
-
        pci_set_master(pdev);
 
        pci_enable_wake(pdev, PCI_D3hot, 0);
@@ -4990,6 +4982,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        if (err)
                goto err_pci_reg;
 
+       /* AER (Advanced Error Reporting) hooks */
+       err = pci_enable_pcie_error_reporting(pdev);
+       if (err) {
+               dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
+                       "0x%x\n", err);
+               /* non-fatal, continue */
+       }
+
        pci_set_master(pdev);
        /* PCI config space info */
        err = pci_save_state(pdev);
index d4b98074b1b787e481c3d13f6dd351494245ac11..c9fd82d3a80d0dba6290af1720a9f11ccd0ca460 100644 (file)
@@ -285,6 +285,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
        struct bufdesc *bdp;
+       void *bufaddr;
        unsigned short  status;
        unsigned long flags;
 
@@ -312,7 +313,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        status &= ~BD_ENET_TX_STATS;
 
        /* Set buffer length and buffer pointer */
-       bdp->cbd_bufaddr = __pa(skb->data);
+       bufaddr = skb->data;
        bdp->cbd_datlen = skb->len;
 
        /*
@@ -320,11 +321,11 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
         * 4-byte boundaries. Use bounce buffers to copy data
         * and get it aligned. Ugh.
         */
-       if (bdp->cbd_bufaddr & FEC_ALIGNMENT) {
+       if (((unsigned long) bufaddr) & FEC_ALIGNMENT) {
                unsigned int index;
                index = bdp - fep->tx_bd_base;
                memcpy(fep->tx_bounce[index], (void *)skb->data, skb->len);
-               bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]);
+               bufaddr = fep->tx_bounce[index];
        }
 
        /* Save skb pointer */
@@ -336,7 +337,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Push the data cache so the CPM does not get stale memory
         * data.
         */
-       bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
+       bdp->cbd_bufaddr = dma_map_single(&dev->dev, bufaddr,
                        FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
 
        /* Send it on its way.  Tell FEC it's ready, interrupt when done,
index f8ffcbf0bc39551eac65f4f8cb969edf61908ee8..e212f2c5448b13cb40ede8bec2339b28ab64e264 100644 (file)
@@ -936,6 +936,7 @@ int startup_gfar(struct net_device *dev)
        struct gfar __iomem *regs = priv->regs;
        int err = 0;
        u32 rctrl = 0;
+       u32 tctrl = 0;
        u32 attrs = 0;
 
        gfar_write(&regs->imask, IMASK_INIT_CLEAR);
@@ -1111,11 +1112,19 @@ int startup_gfar(struct net_device *dev)
                rctrl |= RCTRL_PADDING(priv->padding);
        }
 
+       /* keep vlan related bits if it's enabled */
+       if (priv->vlgrp) {
+               rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT;
+               tctrl |= TCTRL_VLINS;
+       }
+
        /* Init rctrl based on our settings */
        gfar_write(&priv->regs->rctrl, rctrl);
 
        if (dev->features & NETIF_F_IP_CSUM)
-               gfar_write(&priv->regs->tctrl, TCTRL_INIT_CSUM);
+               tctrl |= TCTRL_INIT_CSUM;
+
+       gfar_write(&priv->regs->tctrl, tctrl);
 
        /* Set the extraction length and index */
        attrs = ATTRELI_EL(priv->rx_stash_size) |
@@ -1450,7 +1459,6 @@ static void gfar_vlan_rx_register(struct net_device *dev,
 
                /* Enable VLAN tag extraction */
                tempval = gfar_read(&priv->regs->rctrl);
-               tempval |= RCTRL_VLEX;
                tempval |= (RCTRL_VLEX | RCTRL_PRSDEP_INIT);
                gfar_write(&priv->regs->rctrl, tempval);
        } else {
index d0883835b0c6e0a179ac8107daaba9e6c204771f..fe4f2b2bff96dc579791cd5c1f41e832f3c51ccc 100644 (file)
@@ -115,7 +115,7 @@ static int __init w83977af_init(void)
 
        IRDA_DEBUG(0, "%s()\n", __func__ );
 
-       for (i=0; (io[i] < 2000) && (i < ARRAY_SIZE(dev_self)); i++) {
+       for (i=0; i < ARRAY_SIZE(dev_self) && io[i] < 2000; i++) {
                if (w83977af_open(i, io[i], irq[i], dma[i]) == 0)
                        return 0;
        }
index e11d83d5852bebca9fed0b4727dd049906e1fe8e..2c4dc8221dcd9d7f102ab29543e682fc23926332 100644 (file)
@@ -136,6 +136,8 @@ struct ixgbe_ring {
 
        u8 queue_index; /* needed for multiqueue queue management */
 
+#define IXGBE_RING_RX_PS_ENABLED                (u8)(1)
+       u8 flags;                       /* per ring feature flags */
        u16 head;
        u16 tail;
 
index 79144e950a348768c3d6fb35aac1eb0c1cd82fd8..dff8dfac7ed99edbedd1eed40e8a052a8eef2b88 100644 (file)
@@ -1948,6 +1948,7 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
                               struct ethtool_coalesce *ec)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_q_vector *q_vector;
        int i;
 
        if (ec->tx_max_coalesced_frames_irq)
@@ -1982,14 +1983,24 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
                adapter->itr_setting = 0;
        }
 
-       for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
-               struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
-               if (q_vector->txr_count && !q_vector->rxr_count)
-                       /* tx vector gets half the rate */
-                       q_vector->eitr = (adapter->eitr_param >> 1);
-               else
-                       /* rx only or mixed */
-                       q_vector->eitr = adapter->eitr_param;
+       /* MSI/MSIx Interrupt Mode */
+       if (adapter->flags &
+           (IXGBE_FLAG_MSIX_ENABLED | IXGBE_FLAG_MSI_ENABLED)) {
+               int num_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+               for (i = 0; i < num_vectors; i++) {
+                       q_vector = adapter->q_vector[i];
+                       if (q_vector->txr_count && !q_vector->rxr_count)
+                               /* tx vector gets half the rate */
+                               q_vector->eitr = (adapter->eitr_param >> 1);
+                       else
+                               /* rx only or mixed */
+                               q_vector->eitr = adapter->eitr_param;
+                       ixgbe_write_eitr(q_vector);
+               }
+       /* Legacy Interrupt Mode */
+       } else {
+               q_vector = adapter->q_vector[0];
+               q_vector->eitr = adapter->eitr_param;
                ixgbe_write_eitr(q_vector);
        }
 
index fa9f24e23683003d8d8b531f22793f87d1880cf7..28cf104e36cc57de90af65c37a0981ab07dc205e 100644 (file)
@@ -336,7 +336,7 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
                /* return 0 to bypass going to ULD for DDPed data */
                if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_DDP)
                        rc = 0;
-               else
+               else if (ddp->len)
                        rc = ddp->len;
        }
 
index 110c65ab5cb553ba85638c647c74a3ac150ce3fd..77b0381a2b5c7a3837ab58232ad85ea0eeb2fea6 100644 (file)
@@ -492,12 +492,12 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
 
        skb_record_rx_queue(skb, ring->queue_index);
        if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
-               if (adapter->vlgrp && is_vlan && (tag != 0))
+               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
                        vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
                else
                        napi_gro_receive(napi, skb);
        } else {
-               if (adapter->vlgrp && is_vlan && (tag != 0))
+               if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK))
                        vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
                else
                        netif_rx(skb);
@@ -585,7 +585,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
                rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
 
                if (!bi->page_dma &&
-                   (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) {
+                   (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)) {
                        if (!bi->page) {
                                bi->page = alloc_page(GFP_ATOMIC);
                                if (!bi->page) {
@@ -629,7 +629,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
                }
                /* Refresh the desc even if buffer_addrs didn't change because
                 * each write-back erases this info. */
-               if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+               if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
                        rx_desc->read.pkt_addr = cpu_to_le64(bi->page_dma);
                        rx_desc->read.hdr_addr = cpu_to_le64(bi->dma);
                } else {
@@ -726,7 +726,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                        break;
                (*work_done)++;
 
-               if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+               if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
                        hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc));
                        len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
                               IXGBE_RXDADV_HDRBUFLEN_SHIFT;
@@ -798,7 +798,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                        rx_ring->stats.packets++;
                        rx_ring->stats.bytes += skb->len;
                } else {
-                       if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+                       if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
                                rx_buffer_info->skb = next_buffer->skb;
                                rx_buffer_info->dma = next_buffer->dma;
                                next_buffer->skb = skb;
@@ -1898,46 +1898,19 @@ static void ixgbe_configure_tx(struct ixgbe_adapter *adapter)
 
 #define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2
 
-static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
+static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter,
+                                   struct ixgbe_ring *rx_ring)
 {
-       struct ixgbe_ring *rx_ring;
        u32 srrctl;
-       int queue0 = 0;
-       unsigned long mask;
+       int index;
        struct ixgbe_ring_feature *feature = adapter->ring_feature;
 
-       if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
-               if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-                       int dcb_i = feature[RING_F_DCB].indices;
-                       if (dcb_i == 8)
-                               queue0 = index >> 4;
-                       else if (dcb_i == 4)
-                               queue0 = index >> 5;
-                       else
-                               dev_err(&adapter->pdev->dev, "Invalid DCB "
-                                       "configuration\n");
-#ifdef IXGBE_FCOE
-                       if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
-                               struct ixgbe_ring_feature *f;
-
-                               rx_ring = &adapter->rx_ring[queue0];
-                               f = &adapter->ring_feature[RING_F_FCOE];
-                               if ((queue0 == 0) && (index > rx_ring->reg_idx))
-                                       queue0 = f->mask + index -
-                                                rx_ring->reg_idx - 1;
-                       }
-#endif /* IXGBE_FCOE */
-               } else {
-                       queue0 = index;
-               }
-       } else {
+       index = rx_ring->reg_idx;
+       if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+               unsigned long mask;
                mask = (unsigned long) feature[RING_F_RSS].mask;
-               queue0 = index & mask;
                index = index & mask;
        }
-
-       rx_ring = &adapter->rx_ring[queue0];
-
        srrctl = IXGBE_READ_REG(&adapter->hw, IXGBE_SRRCTL(index));
 
        srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
@@ -1946,7 +1919,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
        srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
                  IXGBE_SRRCTL_BSIZEHDR_MASK;
 
-       if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+       if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
 #if (PAGE_SIZE / 2) > IXGBE_MAX_RXBUFFER
                srrctl |= IXGBE_MAX_RXBUFFER >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
 #else
@@ -2002,6 +1975,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
 {
        u64 rdba;
        struct ixgbe_hw *hw = &adapter->hw;
+       struct ixgbe_ring *rx_ring;
        struct net_device *netdev = adapter->netdev;
        int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
        int i, j;
@@ -2018,11 +1992,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
        /* Decide whether to use packet split mode or not */
        adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
 
-#ifdef IXGBE_FCOE
-       if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
-               adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
-#endif /* IXGBE_FCOE */
-
        /* Set the RX buffer length according to the mode */
        if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
                rx_buf_len = IXGBE_RX_HDR_SIZE;
@@ -2070,29 +2039,35 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
         * the Base and Length of the Rx Descriptor Ring
         */
        for (i = 0; i < adapter->num_rx_queues; i++) {
-               rdba = adapter->rx_ring[i].dma;
-               j = adapter->rx_ring[i].reg_idx;
+               rx_ring = &adapter->rx_ring[i];
+               rdba = rx_ring->dma;
+               j = rx_ring->reg_idx;
                IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), (rdba & DMA_BIT_MASK(32)));
                IXGBE_WRITE_REG(hw, IXGBE_RDBAH(j), (rdba >> 32));
                IXGBE_WRITE_REG(hw, IXGBE_RDLEN(j), rdlen);
                IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0);
                IXGBE_WRITE_REG(hw, IXGBE_RDT(j), 0);
-               adapter->rx_ring[i].head = IXGBE_RDH(j);
-               adapter->rx_ring[i].tail = IXGBE_RDT(j);
-               adapter->rx_ring[i].rx_buf_len = rx_buf_len;
+               rx_ring->head = IXGBE_RDH(j);
+               rx_ring->tail = IXGBE_RDT(j);
+               rx_ring->rx_buf_len = rx_buf_len;
+
+               if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)
+                       rx_ring->flags |= IXGBE_RING_RX_PS_ENABLED;
 
 #ifdef IXGBE_FCOE
                if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
                        struct ixgbe_ring_feature *f;
                        f = &adapter->ring_feature[RING_F_FCOE];
-                       if ((rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE) &&
-                           (i >= f->mask) && (i < f->mask + f->indices))
-                               adapter->rx_ring[i].rx_buf_len =
-                                       IXGBE_FCOE_JUMBO_FRAME_SIZE;
+                       if ((i >= f->mask) && (i < f->mask + f->indices)) {
+                               rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED;
+                               if (rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE)
+                                       rx_ring->rx_buf_len =
+                                               IXGBE_FCOE_JUMBO_FRAME_SIZE;
+                       }
                }
 
 #endif /* IXGBE_FCOE */
-               ixgbe_configure_srrctl(adapter, j);
+               ixgbe_configure_srrctl(adapter, rx_ring);
        }
 
        if (hw->mac.type == ixgbe_mac_82598EB) {
@@ -2168,7 +2143,8 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
        if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
                /* Enable 82599 HW-RSC */
                for (i = 0; i < adapter->num_rx_queues; i++) {
-                       j = adapter->rx_ring[i].reg_idx;
+                       rx_ring = &adapter->rx_ring[i];
+                       j = rx_ring->reg_idx;
                        rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j));
                        rscctrl |= IXGBE_RSCCTL_RSCEN;
                        /*
@@ -2176,7 +2152,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
                         * total size of max desc * buf_len is not greater
                         * than 65535
                         */
-                       if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+                       if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
 #if (MAX_SKB_FRAGS > 16)
                                rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
 #elif (MAX_SKB_FRAGS > 8)
index 91bdfdfd431f214665e3b66c6c9028de3f64ff04..3ac0404d0d11e6391531385e7a79bd4662a4602a 100644 (file)
@@ -506,8 +506,9 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv,
                                 PCI_DMA_FROMDEVICE);
        }
        /* Adjust size of last fragment to match actual length */
-       skb_frags_rx[nr - 1].size = length -
-               priv->frag_info[nr - 1].frag_prefix_size;
+       if (nr > 0)
+               skb_frags_rx[nr - 1].size = length -
+                       priv->frag_info[nr - 1].frag_prefix_size;
        return nr;
 
 fail:
index f86e05047d19db0bdd56feb1b726373fcbeee733..a9c1fcca5e754064e48d420b33334591bce486d5 100644 (file)
@@ -1254,7 +1254,7 @@ struct netxen_adapter {
        u8 mc_enabled;
        u8 max_mc_count;
        u8 rss_supported;
-       u8 resv2;
+       u8 link_changed;
        u32 resv3;
 
        u8 has_link_events;
index 7acf204e38c9261b0168b4828a85f61bbc87eb47..5d3343ef3d86312713481186b541656b1eba3470 100644 (file)
@@ -184,13 +184,6 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
        kfree(recv_ctx->rds_rings);
 
 skip_rds:
-       if (recv_ctx->sds_rings == NULL)
-               goto skip_sds;
-
-       for(ring = 0; ring < adapter->max_sds_rings; ring++)
-               recv_ctx->sds_rings[ring].consumer = 0;
-
-skip_sds:
        if (adapter->tx_ring == NULL)
                return;
 
index 3cd8cfcf627ba69fd5cedbe7a52a2f0765607848..28f270f5ac784e47d6c12110752f988bcae65b33 100644 (file)
@@ -94,10 +94,6 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
 
 MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
 
-static struct workqueue_struct *netxen_workq;
-#define SCHEDULE_WORK(tp)      queue_work(netxen_workq, tp)
-#define FLUSH_SCHEDULED_WORK() flush_workqueue(netxen_workq)
-
 static void netxen_watchdog(unsigned long);
 
 static uint32_t crb_cmd_producer[4] = {
@@ -171,6 +167,8 @@ netxen_free_sds_rings(struct netxen_recv_context *recv_ctx)
 {
        if (recv_ctx->sds_rings != NULL)
                kfree(recv_ctx->sds_rings);
+
+       recv_ctx->sds_rings = NULL;
 }
 
 static int
@@ -192,6 +190,21 @@ netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev)
        return 0;
 }
 
+static void
+netxen_napi_del(struct netxen_adapter *adapter)
+{
+       int ring;
+       struct nx_host_sds_ring *sds_ring;
+       struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
+
+       for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+               sds_ring = &recv_ctx->sds_rings[ring];
+               netif_napi_del(&sds_ring->napi);
+       }
+
+       netxen_free_sds_rings(&adapter->recv_ctx);
+}
+
 static void
 netxen_napi_enable(struct netxen_adapter *adapter)
 {
@@ -260,7 +273,7 @@ nx_update_dma_mask(struct netxen_adapter *adapter)
        change = 0;
 
        shift = NXRD32(adapter, CRB_DMA_SHIFT);
-       if (shift >= 32)
+       if (shift > 32)
                return 0;
 
        if (NX_IS_REVISION_P3(adapter->ahw.revision_id) && (shift > 9))
@@ -272,7 +285,7 @@ nx_update_dma_mask(struct netxen_adapter *adapter)
                old_mask = pdev->dma_mask;
                old_cmask = pdev->dev.coherent_dma_mask;
 
-               mask = (1ULL<<(32+shift)) - 1;
+               mask = DMA_BIT_MASK(32+shift);
 
                err = pci_set_dma_mask(pdev, mask);
                if (err)
@@ -880,7 +893,6 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
        spin_unlock(&adapter->tx_clean_lock);
 
        del_timer_sync(&adapter->watchdog_timer);
-       FLUSH_SCHEDULED_WORK();
 }
 
 
@@ -894,10 +906,12 @@ netxen_nic_attach(struct netxen_adapter *adapter)
        struct nx_host_tx_ring *tx_ring;
 
        err = netxen_init_firmware(adapter);
-       if (err != 0) {
-               printk(KERN_ERR "Failed to init firmware\n");
-               return -EIO;
-       }
+       if (err)
+               return err;
+
+       err = netxen_napi_add(adapter, netdev);
+       if (err)
+               return err;
 
        if (adapter->fw_major < 4)
                adapter->max_rds_rings = 3;
@@ -961,6 +975,7 @@ netxen_nic_detach(struct netxen_adapter *adapter)
        netxen_free_hw_resources(adapter);
        netxen_release_rx_buffers(adapter);
        netxen_nic_free_irq(adapter);
+       netxen_napi_del(adapter);
        netxen_free_sw_resources(adapter);
 
        adapter->is_up = 0;
@@ -1105,9 +1120,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        netdev->irq = adapter->msix_entries[0].vector;
 
-       if (netxen_napi_add(adapter, netdev))
-               goto err_out_disable_msi;
-
        init_timer(&adapter->watchdog_timer);
        adapter->watchdog_timer.function = &netxen_watchdog;
        adapter->watchdog_timer.data = (unsigned long)adapter;
@@ -1177,6 +1189,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
        unregister_netdev(netdev);
 
+       cancel_work_sync(&adapter->watchdog_task);
+       cancel_work_sync(&adapter->tx_timeout_task);
+
        if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
                netxen_nic_detach(adapter);
        }
@@ -1185,7 +1200,6 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
                netxen_free_adapter_offload(adapter);
 
        netxen_teardown_intr(adapter);
-       netxen_free_sds_rings(&adapter->recv_ctx);
 
        netxen_cleanup_pci_map(adapter);
 
@@ -1211,6 +1225,9 @@ netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
        if (netif_running(netdev))
                netxen_nic_down(adapter, netdev);
 
+       cancel_work_sync(&adapter->watchdog_task);
+       cancel_work_sync(&adapter->tx_timeout_task);
+
        if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
                netxen_nic_detach(adapter);
 
@@ -1549,11 +1566,6 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter)
                       "%s: Device temperature %d degrees C exceeds"
                       " maximum allowed. Hardware has been shut down.\n",
                       netdev->name, temp_val);
-
-               netif_device_detach(netdev);
-               netxen_nic_down(adapter, netdev);
-               netxen_nic_detach(adapter);
-
                rv = 1;
        } else if (temp_state == NX_TEMP_WARN) {
                if (adapter->temp == NX_TEMP_NORMAL) {
@@ -1587,10 +1599,7 @@ void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup)
                        netif_carrier_off(netdev);
                        netif_stop_queue(netdev);
                }
-
-               if (!adapter->has_link_events)
-                       netxen_nic_set_link_parameters(adapter);
-
+               adapter->link_changed = !adapter->has_link_events;
        } else if (!adapter->ahw.linkup && linkup) {
                printk(KERN_INFO "%s: %s NIC Link is up\n",
                       netxen_nic_driver_name, netdev->name);
@@ -1599,9 +1608,7 @@ void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup)
                        netif_carrier_on(netdev);
                        netif_wake_queue(netdev);
                }
-
-               if (!adapter->has_link_events)
-                       netxen_nic_set_link_parameters(adapter);
+               adapter->link_changed = !adapter->has_link_events;
        }
 }
 
@@ -1628,11 +1635,36 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
        netxen_advert_link_change(adapter, linkup);
 }
 
+static void netxen_nic_thermal_shutdown(struct netxen_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+
+       netif_device_detach(netdev);
+       netxen_nic_down(adapter, netdev);
+       netxen_nic_detach(adapter);
+}
+
 static void netxen_watchdog(unsigned long v)
 {
        struct netxen_adapter *adapter = (struct netxen_adapter *)v;
 
-       SCHEDULE_WORK(&adapter->watchdog_task);
+       if (netxen_nic_check_temp(adapter))
+               goto do_sched;
+
+       if (!adapter->has_link_events) {
+               netxen_nic_handle_phy_intr(adapter);
+
+               if (adapter->link_changed)
+                       goto do_sched;
+       }
+
+       if (netif_running(adapter->netdev))
+               mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+
+       return;
+
+do_sched:
+       schedule_work(&adapter->watchdog_task);
 }
 
 void netxen_watchdog_task(struct work_struct *work)
@@ -1640,11 +1672,13 @@ void netxen_watchdog_task(struct work_struct *work)
        struct netxen_adapter *adapter =
                container_of(work, struct netxen_adapter, watchdog_task);
 
-       if (netxen_nic_check_temp(adapter))
+       if (adapter->temp == NX_TEMP_PANIC) {
+               netxen_nic_thermal_shutdown(adapter);
                return;
+       }
 
-       if (!adapter->has_link_events)
-               netxen_nic_handle_phy_intr(adapter);
+       if (adapter->link_changed)
+               netxen_nic_set_link_parameters(adapter);
 
        if (netif_running(adapter->netdev))
                mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
@@ -1652,9 +1686,8 @@ void netxen_watchdog_task(struct work_struct *work)
 
 static void netxen_tx_timeout(struct net_device *netdev)
 {
-       struct netxen_adapter *adapter = (struct netxen_adapter *)
-                                               netdev_priv(netdev);
-       SCHEDULE_WORK(&adapter->tx_timeout_task);
+       struct netxen_adapter *adapter = netdev_priv(netdev);
+       schedule_work(&adapter->tx_timeout_task);
 }
 
 static void netxen_tx_timeout_task(struct work_struct *work)
@@ -1811,9 +1844,6 @@ static int __init netxen_init_module(void)
 {
        printk(KERN_INFO "%s\n", netxen_nic_driver_string);
 
-       if ((netxen_workq = create_singlethread_workqueue("netxen")) == NULL)
-               return -ENOMEM;
-
        return pci_register_driver(&netxen_driver);
 }
 
@@ -1822,7 +1852,6 @@ module_init(netxen_init_module);
 static void __exit netxen_exit_module(void)
 {
        pci_unregister_driver(&netxen_driver);
-       destroy_workqueue(netxen_workq);
 }
 
 module_exit(netxen_exit_module);
index a646a445fda94a3eb250a7a09a1f063f55c2f9e7..23e1a0750fe0eba518dc87b1bfbbef7e4cf8283b 100644 (file)
@@ -1839,7 +1839,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
        lp->chip_version = chip_version;
        lp->msg_enable = pcnet32_debug;
        if ((cards_found >= MAX_UNITS)
-           || (options[cards_found] > sizeof(options_mapping)))
+           || (options[cards_found] >= sizeof(options_mapping)))
                lp->options = PCNET32_PORT_ASEL;
        else
                lp->options = options_mapping[options[cards_found]];
index 99a63649f4fcd1b75c807398fe9a872fb38c3bd1..4cf9a6588751eacadc2d798a7f14fba135ce7012 100644 (file)
@@ -652,8 +652,9 @@ tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
        int entry;
        u32 flag;
        dma_addr_t mapping;
+       unsigned long flags;
 
-       spin_lock_irq(&tp->lock);
+       spin_lock_irqsave(&tp->lock, flags);
 
        /* Calculate the next Tx descriptor entry. */
        entry = tp->cur_tx % TX_RING_SIZE;
@@ -688,7 +689,7 @@ tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Trigger an immediate transmit demand. */
        iowrite32(0, tp->base_addr + CSR1);
 
-       spin_unlock_irq(&tp->lock);
+       spin_unlock_irqrestore(&tp->lock, flags);
 
        dev->trans_start = jiffies;
 
index 027f7aba26af1d339dad5081a1ae8167b34c3d8c..42b6c6319bc29824fe4e2061ee882759cfeb05c1 100644 (file)
@@ -1048,20 +1048,15 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
        return err;
 }
 
-static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
+static int tun_get_iff(struct net *net, struct tun_struct *tun,
+                      struct ifreq *ifr)
 {
-       struct tun_struct *tun = tun_get(file);
-
-       if (!tun)
-               return -EBADFD;
-
        DBG(KERN_INFO "%s: tun_get_iff\n", tun->dev->name);
 
        strcpy(ifr->ifr_name, tun->dev->name);
 
        ifr->ifr_flags = tun_flags(tun);
 
-       tun_put(tun);
        return 0;
 }
 
@@ -1105,8 +1100,8 @@ static int set_offload(struct net_device *dev, unsigned long arg)
        return 0;
 }
 
-static int tun_chr_ioctl(struct inode *inode, struct file *file,
-                        unsigned int cmd, unsigned long arg)
+static long tun_chr_ioctl(struct file *file, unsigned int cmd,
+                         unsigned long arg)
 {
        struct tun_file *tfile = file->private_data;
        struct tun_struct *tun;
@@ -1128,34 +1123,32 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                                (unsigned int __user*)argp);
        }
 
+       rtnl_lock();
+
        tun = __tun_get(tfile);
        if (cmd == TUNSETIFF && !tun) {
-               int err;
-
                ifr.ifr_name[IFNAMSIZ-1] = '\0';
 
-               rtnl_lock();
-               err = tun_set_iff(tfile->net, file, &ifr);
-               rtnl_unlock();
+               ret = tun_set_iff(tfile->net, file, &ifr);
 
-               if (err)
-                       return err;
+               if (ret)
+                       goto unlock;
 
                if (copy_to_user(argp, &ifr, sizeof(ifr)))
-                       return -EFAULT;
-               return 0;
+                       ret = -EFAULT;
+               goto unlock;
        }
 
-
+       ret = -EBADFD;
        if (!tun)
-               return -EBADFD;
+               goto unlock;
 
        DBG(KERN_INFO "%s: tun_chr_ioctl cmd %d\n", tun->dev->name, cmd);
 
        ret = 0;
        switch (cmd) {
        case TUNGETIFF:
-               ret = tun_get_iff(current->nsproxy->net_ns, file, &ifr);
+               ret = tun_get_iff(current->nsproxy->net_ns, tun, &ifr);
                if (ret)
                        break;
 
@@ -1201,7 +1194,6 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
 
        case TUNSETLINK:
                /* Only allow setting the type when the interface is down */
-               rtnl_lock();
                if (tun->dev->flags & IFF_UP) {
                        DBG(KERN_INFO "%s: Linktype set failed because interface is up\n",
                                tun->dev->name);
@@ -1211,7 +1203,6 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                        DBG(KERN_INFO "%s: linktype set to %d\n", tun->dev->name, tun->dev->type);
                        ret = 0;
                }
-               rtnl_unlock();
                break;
 
 #ifdef TUN_DEBUG
@@ -1220,9 +1211,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                break;
 #endif
        case TUNSETOFFLOAD:
-               rtnl_lock();
                ret = set_offload(tun->dev, arg);
-               rtnl_unlock();
                break;
 
        case TUNSETTXFILTER:
@@ -1230,9 +1219,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                ret = -EINVAL;
                if ((tun->flags & TUN_TYPE_MASK) != TUN_TAP_DEV)
                        break;
-               rtnl_lock();
                ret = update_filter(&tun->txflt, (void __user *)arg);
-               rtnl_unlock();
                break;
 
        case SIOCGIFHWADDR:
@@ -1248,9 +1235,7 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                DBG(KERN_DEBUG "%s: set hw address: %pM\n",
                        tun->dev->name, ifr.ifr_hwaddr.sa_data);
 
-               rtnl_lock();
                ret = dev_set_mac_address(tun->dev, &ifr.ifr_hwaddr);
-               rtnl_unlock();
                break;
 
        case TUNGETSNDBUF:
@@ -1273,7 +1258,10 @@ static int tun_chr_ioctl(struct inode *inode, struct file *file,
                break;
        };
 
-       tun_put(tun);
+unlock:
+       rtnl_unlock();
+       if (tun)
+               tun_put(tun);
        return ret;
 }
 
@@ -1361,7 +1349,7 @@ static const struct file_operations tun_fops = {
        .write = do_sync_write,
        .aio_write = tun_chr_aio_write,
        .poll   = tun_chr_poll,
-       .ioctl  = tun_chr_ioctl,
+       .unlocked_ioctl = tun_chr_ioctl,
        .open   = tun_chr_open,
        .release = tun_chr_close,
        .fasync = tun_chr_fasync
index 3b957e6412ee7bfab7de95f7554fbf1112cab739..8a7b8c7bd7810a49baed432f3aba916dca16cf84 100644 (file)
@@ -3111,10 +3111,11 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
        u8 __iomem *bd;                 /* BD pointer */
        u32 bd_status;
        u8 txQ = 0;
+       unsigned long flags;
 
        ugeth_vdbg("%s: IN", __func__);
 
-       spin_lock_irq(&ugeth->lock);
+       spin_lock_irqsave(&ugeth->lock, flags);
 
        dev->stats.tx_bytes += skb->len;
 
@@ -3171,7 +3172,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
        uccf = ugeth->uccf;
        out_be16(uccf->p_utodr, UCC_FAST_TOD);
 #endif
-       spin_unlock_irq(&ugeth->lock);
+       spin_unlock_irqrestore(&ugeth->lock, flags);
 
        return 0;
 }
index c7467823cd1ca975349ec5ddfdac2ed293d7beac..f968c834ff63581bf73cdceec371352a5e44fa29 100644 (file)
@@ -250,6 +250,8 @@ PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
                DEFAULT_GPIO_RESET )
 PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
                DEFAULT_GPIO_RESET | PEGASUS_II )
+PEGASUS_DEV( "IO DATA USB ETX-US2", VENDOR_IODATA, 0x092a,
+               DEFAULT_GPIO_RESET | PEGASUS_II )
 PEGASUS_DEV( "Kingston KNU101TX Ethernet", VENDOR_KINGSTON, 0x000a,
                DEFAULT_GPIO_RESET)
 PEGASUS_DEV( "LANEED USB Ethernet LD-USB/TX", VENDOR_LANEED, 0x4002,
index 88c30a58b4bda50d0b5fb610916365076cbdf1c5..934f7671650a8dd3aa0c049fc85001177c3542b7 100644 (file)
@@ -1218,6 +1218,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
        struct rhine_private *rp = netdev_priv(dev);
        void __iomem *ioaddr = rp->base;
        unsigned entry;
+       unsigned long flags;
 
        /* Caution: the write order is important here, set the field
           with the "ownership" bits last. */
@@ -1261,7 +1262,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
                cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN));
 
        /* lock eth irq */
-       spin_lock_irq(&rp->lock);
+       spin_lock_irqsave(&rp->lock, flags);
        wmb();
        rp->tx_ring[entry].tx_status = cpu_to_le32(DescOwn);
        wmb();
@@ -1280,7 +1281,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
 
        dev->trans_start = jiffies;
 
-       spin_unlock_irq(&rp->lock);
+       spin_unlock_irqrestore(&rp->lock, flags);
 
        if (debug > 4) {
                printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
index 3ba35956327a37a4cb74046c39e18762f6659ccd..cee08a1e497a1f28340fe8d7314a10464638c46a 100644 (file)
@@ -1778,7 +1778,7 @@ static void velocity_error(struct velocity_info *vptr, int status)
                         *       mode
                         */
                        if (vptr->rev_id < REV_ID_VT3216_A0) {
-                               if (vptr->mii_status | VELOCITY_DUPLEX_FULL)
+                               if (vptr->mii_status & VELOCITY_DUPLEX_FULL)
                                        BYTE_REG_BITS_ON(TCR_TB2BDIS, &regs->TCR);
                                else
                                        BYTE_REG_BITS_OFF(TCR_TB2BDIS, &regs->TCR);
index 9d38cf60a0db2bd8ee1197d99ea6854769aa7357..88c3d8573869dbfab02b3738a26fed16d38d80ee 100644 (file)
@@ -1967,13 +1967,14 @@ static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
        int ret;
 
        mutex_lock(&ar->mutex);
-       if ((param) && !(queue > __AR9170_NUM_TXQ)) {
+       if (queue < __AR9170_NUM_TXQ) {
                memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
                       param, sizeof(*param));
 
                ret = ar9170_set_qos(ar);
-       } else
+       } else {
                ret = -EINVAL;
+       }
 
        mutex_unlock(&ar->mutex);
        return ret;
index 754b1f8d8da944155e3a2669499327749de491c9..007eb85fc67e27a4f6b11b9cf94129f142bf3b81 100644 (file)
@@ -598,11 +598,15 @@ static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
 
        err = request_firmware(&aru->init_values, "ar9170-1.fw",
                               &aru->udev->dev);
+       if (err) {
+               dev_err(&aru->udev->dev, "file with init values not found.\n");
+               return err;
+       }
 
        err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
        if (err) {
                release_firmware(aru->init_values);
-               dev_err(&aru->udev->dev, "file with init values not found.\n");
+               dev_err(&aru->udev->dev, "firmware file not found.\n");
                return err;
        }
 
index 44c29b3f67285ab608d3bf254db3498be3854962..6dcac73b4d299ee80e4bbf40877387620d3066ea 100644 (file)
@@ -6226,7 +6226,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv,
                        };
 
                        u8 channel;
-                       while (channel_index < IPW_SCAN_CHANNELS) {
+                       while (channel_index < IPW_SCAN_CHANNELS - 1) {
                                channel =
                                    priv->speed_scan[priv->speed_scan_pos];
                                if (channel == 0) {
index d6997371c27e9e0b0d2c61f2842c554c3bd7db84..b9b374119033f7fa92f04a0bfa7b6e8cf7e737ac 100644 (file)
@@ -1,7 +1,6 @@
 /* Copyright (C) 2006, Red Hat, Inc. */
 
 #include <linux/types.h>
-#include <linux/kernel.h>
 #include <linux/etherdevice.h>
 #include <linux/ieee80211.h>
 #include <linux/if_arp.h>
@@ -44,21 +43,21 @@ static int get_common_rates(struct lbs_private *priv,
        u16 *rates_size)
 {
        u8 *card_rates = lbs_bg_rates;
+       size_t num_card_rates = sizeof(lbs_bg_rates);
        int ret = 0, i, j;
-       u8 tmp[(ARRAY_SIZE(lbs_bg_rates) - 1) * (*rates_size - 1)];
+       u8 tmp[30];
        size_t tmp_size = 0;
 
        /* For each rate in card_rates that exists in rate1, copy to tmp */
-       for (i = 0; i < ARRAY_SIZE(lbs_bg_rates) && card_rates[i]; i++) {
-               for (j = 0; j < *rates_size && rates[j]; j++) {
+       for (i = 0; card_rates[i] && (i < num_card_rates); i++) {
+               for (j = 0; rates[j] && (j < *rates_size); j++) {
                        if (rates[j] == card_rates[i])
                                tmp[tmp_size++] = card_rates[i];
                }
        }
 
        lbs_deb_hex(LBS_DEB_JOIN, "AP rates    ", rates, *rates_size);
-       lbs_deb_hex(LBS_DEB_JOIN, "card rates  ", card_rates,
-                       ARRAY_SIZE(lbs_bg_rates));
+       lbs_deb_hex(LBS_DEB_JOIN, "card rates  ", card_rates, num_card_rates);
        lbs_deb_hex(LBS_DEB_JOIN, "common rates", tmp, tmp_size);
        lbs_deb_join("TX data rate 0x%02x\n", priv->cur_rate);
 
@@ -70,7 +69,10 @@ static int get_common_rates(struct lbs_private *priv,
                lbs_pr_alert("Previously set fixed data rate %#x isn't "
                       "compatible with the network.\n", priv->cur_rate);
                ret = -1;
+               goto done;
        }
+       ret = 0;
+
 done:
        memset(rates, 0, *rates_size);
        *rates_size = min_t(int, tmp_size, *rates_size);
@@ -320,7 +322,7 @@ static int lbs_associate(struct lbs_private *priv,
        rates = (struct mrvl_ie_rates_param_set *) pos;
        rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
        memcpy(&rates->rates, &bss->rates, MAX_RATES);
-       tmplen = min_t(u16, ARRAY_SIZE(rates->rates), MAX_RATES);
+       tmplen = MAX_RATES;
        if (get_common_rates(priv, rates->rates, &tmplen)) {
                ret = -1;
                goto done;
@@ -596,7 +598,7 @@ static int lbs_adhoc_join(struct lbs_private *priv,
 
        /* Copy Data rates from the rates recorded in scan response */
        memset(cmd.bss.rates, 0, sizeof(cmd.bss.rates));
-       ratesize = min_t(u16, ARRAY_SIZE(cmd.bss.rates), MAX_RATES);
+       ratesize = min_t(u16, sizeof(cmd.bss.rates), MAX_RATES);
        memcpy(cmd.bss.rates, bss->rates, ratesize);
        if (get_common_rates(priv, cmd.bss.rates, &ratesize)) {
                lbs_deb_join("ADHOC_JOIN: get_common_rates returned error.\n");
index 0a2e29140addb5ba9375259573912f22cc34e054..c8a1998d4744270021931124e7650a93bd3dea5b 100644 (file)
@@ -56,8 +56,8 @@ struct rxpd {
                        u8 bss_type;
                        /* BSS number */
                        u8 bss_num;
-               } bss;
-       } u;
+               } __attribute__ ((packed)) bss;
+       } __attribute__ ((packed)) u;
 
        /* SNR */
        u8 snr;
index a263d5c84c0874857b8ee02243cff89bc9e8eee6..83967afe0821681ca7140c08fac2d47bd3d4419e 100644 (file)
@@ -261,7 +261,7 @@ struct mwl8k_vif {
         */
 };
 
-#define MWL8K_VIF(_vif) (struct mwl8k_vif *)(&((_vif)->drv_priv))
+#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
 
 static const struct ieee80211_channel mwl8k_channels[] = {
        { .center_freq = 2412, .hw_value = 1, },
@@ -1012,6 +1012,8 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
                rmb();
 
                skb = rxq->rx_skb[rxq->rx_head];
+               if (skb == NULL)
+                       break;
                rxq->rx_skb[rxq->rx_head] = NULL;
 
                rxq->rx_head = (rxq->rx_head + 1) % MWL8K_RX_DESCS;
@@ -1591,6 +1593,9 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
        timeout = wait_for_completion_timeout(&cmd_wait,
                                msecs_to_jiffies(MWL8K_CMD_TIMEOUT_MS));
 
+       pci_unmap_single(priv->pdev, dma_addr, dma_size,
+                                       PCI_DMA_BIDIRECTIONAL);
+
        result = &cmd->result;
        if (!timeout) {
                spin_lock_irq(&priv->fw_lock);
@@ -1610,8 +1615,6 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
                               *result);
        }
 
-       pci_unmap_single(priv->pdev, dma_addr, dma_size,
-                                       PCI_DMA_BIDIRECTIONAL);
        return rc;
 }
 
@@ -1654,18 +1657,18 @@ static int mwl8k_cmd_get_hw_spec(struct ieee80211_hw *hw)
        memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
        cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
        cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rx_desc_dma);
-       cmd->num_tx_queues = MWL8K_TX_QUEUES;
+       cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
        for (i = 0; i < MWL8K_TX_QUEUES; i++)
                cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].tx_desc_dma);
-       cmd->num_tx_desc_per_queue = MWL8K_TX_DESCS;
-       cmd->total_rx_desc = MWL8K_RX_DESCS;
+       cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
+       cmd->total_rx_desc = cpu_to_le32(MWL8K_RX_DESCS);
 
        rc = mwl8k_post_cmd(hw, &cmd->header);
 
        if (!rc) {
                SET_IEEE80211_PERM_ADDR(hw, cmd->perm_addr);
                priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
-               priv->fw_rev = cmd->fw_rev;
+               priv->fw_rev = le32_to_cpu(cmd->fw_rev);
                priv->hw_rev = cmd->hw_rev;
                priv->region_code = le16_to_cpu(cmd->region_code);
        }
@@ -3216,15 +3219,19 @@ static int mwl8k_configure_filter_wt(struct work_struct *wt)
        struct dev_addr_list *mclist = worker->mclist;
 
        struct mwl8k_priv *priv = hw->priv;
-       struct mwl8k_vif *mv_vif;
        int rc = 0;
 
        if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
                if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
                        rc = mwl8k_cmd_set_pre_scan(hw);
                else {
-                       mv_vif = MWL8K_VIF(priv->vif);
-                       rc = mwl8k_cmd_set_post_scan(hw, mv_vif->bssid);
+                       u8 *bssid;
+
+                       bssid = "\x00\x00\x00\x00\x00\x00";
+                       if (priv->vif != NULL)
+                               bssid = MWL8K_VIF(priv->vif)->bssid;
+
+                       rc = mwl8k_cmd_set_post_scan(hw, bssid);
                }
        }
 
@@ -3726,6 +3733,8 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
 
        ieee80211_stop_queues(hw);
 
+       ieee80211_unregister_hw(hw);
+
        /* Remove tx reclaim tasklet */
        tasklet_kill(&priv->tx_reclaim_task);
 
@@ -3739,8 +3748,6 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
        for (i = 0; i < MWL8K_TX_QUEUES; i++)
                mwl8k_txq_reclaim(hw, i, 1);
 
-       ieee80211_unregister_hw(hw);
-
        for (i = 0; i < MWL8K_TX_QUEUES; i++)
                mwl8k_txq_deinit(hw, i);
 
index a498dde024e1b58c55555e00d349a5cc28846218..49c9e2c1433d98cc82c16346242fc68eb0548897 100644 (file)
@@ -849,13 +849,15 @@ struct rt2x00_dev {
 static inline void rt2x00_rf_read(struct rt2x00_dev *rt2x00dev,
                                  const unsigned int word, u32 *data)
 {
-       *data = rt2x00dev->rf[word];
+       BUG_ON(word < 1 || word > rt2x00dev->ops->rf_size / sizeof(u32));
+       *data = rt2x00dev->rf[word - 1];
 }
 
 static inline void rt2x00_rf_write(struct rt2x00_dev *rt2x00dev,
                                   const unsigned int word, u32 data)
 {
-       rt2x00dev->rf[word] = data;
+       BUG_ON(word < 1 || word > rt2x00dev->ops->rf_size / sizeof(u32));
+       rt2x00dev->rf[word - 1] = data;
 }
 
 /*
index 37c84e3b8be083426a89e1e68686dbb0ad569764..81c753a617ab93ab793b724428c9c0c97646da84 100644 (file)
@@ -120,6 +120,9 @@ static int __devinit zorro8390_init_one(struct zorro_dev *z,
     for (i = ARRAY_SIZE(cards)-1; i >= 0; i--)
        if (z->id == cards[i].id)
            break;
+    if (i < 0)
+        return -ENODEV;
+
     board = z->resource.start;
     ioaddr = board+cards[i].offset;
     dev = alloc_ei_netdev();
index 037c1e0b7c4c5bd137c0720ccaa3210716c09435..6553833c12db1e45f427cb65fe7d95e396310a6d 100644 (file)
@@ -527,7 +527,7 @@ config SERIAL_S3C24A0
 
 config SERIAL_S3C6400
        tristate "Samsung S3C6400/S3C6410 Serial port support"
-       depends on SERIAL_SAMSUNG && (CPU_S3C600 || CPU_S3C6410)
+       depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410)
        default y
        help
          Serial port support for the Samsung S3C6400 and S3C6410
index 8f24564f77b05e9939b964bfd97862f5078a73cf..07f22b625632872c10476c33ab5dab5e97792adc 100644 (file)
@@ -481,6 +481,9 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
        /* tell the board code to enable the panel */
        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
                ch = &priv->ch[k];
+               if (!ch->enabled)
+                       continue;
+
                board_cfg = &ch->cfg.board_cfg;
                if (board_cfg->display_on)
                        board_cfg->display_on(board_cfg->board_data);
@@ -498,6 +501,8 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)
        /* clean up deferred io and ask board code to disable panel */
        for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
                ch = &priv->ch[k];
+               if (!ch->enabled)
+                       continue;
 
                /* deferred io mode:
                 * flush frame, and wait for frame end interrupt
index 23419dc3027b69659aab64eeb0a6aced7504810e..a7cbfbd340c7d53fa282f41d543a9737dbebfe8b 100644 (file)
@@ -386,16 +386,16 @@ static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf)
 #define GDLM_ATTR(_name,_mode,_show,_store) \
 static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
 
-GDLM_ATTR(proto_name,     0444, proto_name_show,       NULL);
-GDLM_ATTR(block,          0644, block_show,            block_store);
-GDLM_ATTR(withdraw,       0644, withdraw_show,         withdraw_store);
-GDLM_ATTR(id,             0444, lkid_show,             NULL);
-GDLM_ATTR(jid,           0444, jid_show,               NULL);
-GDLM_ATTR(first,          0444, lkfirst_show,          NULL);
-GDLM_ATTR(first_done,     0444, first_done_show,       NULL);
-GDLM_ATTR(recover,        0200, NULL,                  recover_store);
-GDLM_ATTR(recover_done,   0444, recover_done_show,     NULL);
-GDLM_ATTR(recover_status, 0444, recover_status_show,   NULL);
+GDLM_ATTR(proto_name,          0444, proto_name_show,          NULL);
+GDLM_ATTR(block,               0644, block_show,               block_store);
+GDLM_ATTR(withdraw,            0644, withdraw_show,            withdraw_store);
+GDLM_ATTR(id,                  0444, lkid_show,                NULL);
+GDLM_ATTR(jid,                 0444, jid_show,                 NULL);
+GDLM_ATTR(first,               0444, lkfirst_show,             NULL);
+GDLM_ATTR(first_done,          0444, first_done_show,          NULL);
+GDLM_ATTR(recover,             0600, NULL,                     recover_store);
+GDLM_ATTR(recover_done,                0444, recover_done_show,        NULL);
+GDLM_ATTR(recover_status,      0444, recover_status_show,      NULL);
 
 static struct attribute *lock_module_attrs[] = {
        &gdlm_attr_proto_name.attr,
index 47cd258fd24d8dc2588b68759608205b87387891..5dcbafe72d71731e3fb2f540f26406e8662580af 100644 (file)
@@ -62,13 +62,14 @@ static int inotify_handle_event(struct fsnotify_group *group, struct fsnotify_ev
        event_priv->wd = wd;
 
        ret = fsnotify_add_notify_event(group, event, fsn_event_priv);
-       /* EEXIST is not an error */
-       if (ret == -EEXIST)
-               ret = 0;
-
-       /* did event_priv get attached? */
-       if (list_empty(&fsn_event_priv->event_list))
+       if (ret) {
                inotify_free_event_priv(fsn_event_priv);
+               /* EEXIST says we tail matched, EOVERFLOW isn't something
+                * to report up the stack. */
+               if ((ret == -EEXIST) ||
+                   (ret == -EOVERFLOW))
+                       ret = 0;
+       }
 
        /*
         * If we hold the entry until after the event is on the queue
index f30d9bbc2e1bf80f61d16eaa46efc09a5f1bc8d5..dc32ed8323ba85075190590ae081846ab99bf62a 100644 (file)
@@ -386,6 +386,7 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark_entry *entry,
        struct fsnotify_event *ignored_event;
        struct inotify_event_private_data *event_priv;
        struct fsnotify_event_private_data *fsn_event_priv;
+       int ret;
 
        ignored_event = fsnotify_create_event(NULL, FS_IN_IGNORED, NULL,
                                              FSNOTIFY_EVENT_NONE, NULL, 0,
@@ -404,10 +405,8 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark_entry *entry,
        fsn_event_priv->group = group;
        event_priv->wd = ientry->wd;
 
-       fsnotify_add_notify_event(group, ignored_event, fsn_event_priv);
-
-       /* did the private data get added? */
-       if (list_empty(&fsn_event_priv->event_list))
+       ret = fsnotify_add_notify_event(group, ignored_event, fsn_event_priv);
+       if (ret)
                inotify_free_event_priv(fsn_event_priv);
 
 skip_send_ignore:
@@ -568,7 +567,7 @@ static struct fsnotify_group *inotify_new_group(struct user_struct *user, unsign
 
        spin_lock_init(&group->inotify_data.idr_lock);
        idr_init(&group->inotify_data.idr);
-       group->inotify_data.last_wd = 0;
+       group->inotify_data.last_wd = 1;
        group->inotify_data.user = user;
        group->inotify_data.fa = NULL;
 
index 521368574e97b5841ec90c52ae8b4215ddc36dd4..3816d5750dd55eb6f8b2c710b6a017a4694b450c 100644 (file)
@@ -153,6 +153,10 @@ static bool event_compare(struct fsnotify_event *old, struct fsnotify_event *new
                                return true;
                        break;
                case (FSNOTIFY_EVENT_NONE):
+                       if (old->mask & FS_Q_OVERFLOW)
+                               return true;
+                       else if (old->mask & FS_IN_IGNORED)
+                               return false;
                        return false;
                };
        }
@@ -171,9 +175,7 @@ int fsnotify_add_notify_event(struct fsnotify_group *group, struct fsnotify_even
        struct list_head *list = &group->notification_list;
        struct fsnotify_event_holder *last_holder;
        struct fsnotify_event *last_event;
-
-       /* easy to tell if priv was attached to the event */
-       INIT_LIST_HEAD(&priv->event_list);
+       int ret = 0;
 
        /*
         * There is one fsnotify_event_holder embedded inside each fsnotify_event.
@@ -194,6 +196,7 @@ alloc_holder:
 
        if (group->q_len >= group->max_events) {
                event = &q_overflow_event;
+               ret = -EOVERFLOW;
                /* sorry, no private data on the overflow event */
                priv = NULL;
        }
@@ -235,7 +238,7 @@ alloc_holder:
        mutex_unlock(&group->notification_mutex);
 
        wake_up(&group->notification_waitq);
-       return 0;
+       return ret;
 }
 
 /*
index d870237e42c74f018b2824304345aa44a90b8607..8084834e123efed4e100fe030e2e26ced3ede1c9 100644 (file)
@@ -110,6 +110,7 @@ void poll_initwait(struct poll_wqueues *pwq)
 {
        init_poll_funcptr(&pwq->pt, __pollwait);
        pwq->polling_task = current;
+       pwq->triggered = 0;
        pwq->error = 0;
        pwq->table = NULL;
        pwq->inline_index = 0;
index b619d6b8ca4323afc02abab54d967f352d899e6a..98ef624d9baf65a2bb3503d0fb6c599fdbdfd02f 100644 (file)
@@ -708,6 +708,16 @@ xfs_reclaim_inode(
        return 0;
 }
 
+void
+__xfs_inode_set_reclaim_tag(
+       struct xfs_perag        *pag,
+       struct xfs_inode        *ip)
+{
+       radix_tree_tag_set(&pag->pag_ici_root,
+                          XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino),
+                          XFS_ICI_RECLAIM_TAG);
+}
+
 /*
  * We set the inode flag atomically with the radix tree tag.
  * Once we get tag lookups on the radix tree, this inode flag
@@ -722,8 +732,7 @@ xfs_inode_set_reclaim_tag(
 
        read_lock(&pag->pag_ici_lock);
        spin_lock(&ip->i_flags_lock);
-       radix_tree_tag_set(&pag->pag_ici_root,
-                       XFS_INO_TO_AGINO(mp, ip->i_ino), XFS_ICI_RECLAIM_TAG);
+       __xfs_inode_set_reclaim_tag(pag, ip);
        __xfs_iflags_set(ip, XFS_IRECLAIMABLE);
        spin_unlock(&ip->i_flags_lock);
        read_unlock(&pag->pag_ici_lock);
index 2a10301c99c79b8bf73e3d89a73f965ef580b23a..59120602588a370168282a3177a66c7a477bbb42 100644 (file)
@@ -48,6 +48,7 @@ int xfs_reclaim_inode(struct xfs_inode *ip, int locked, int sync_mode);
 int xfs_reclaim_inodes(struct xfs_mount *mp, int mode);
 
 void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
+void __xfs_inode_set_reclaim_tag(struct xfs_perag *pag, struct xfs_inode *ip);
 void xfs_inode_clear_reclaim_tag(struct xfs_inode *ip);
 void __xfs_inode_clear_reclaim_tag(struct xfs_mount *mp, struct xfs_perag *pag,
                                struct xfs_inode *ip);
index 34ec86923f7e354044fbe9ffa27a77126ce354cf..ecbf8b4d2e2e4d0f8ae4506b64a4b787dc84e5db 100644 (file)
@@ -191,80 +191,82 @@ xfs_iget_cache_hit(
        int                     flags,
        int                     lock_flags) __releases(pag->pag_ici_lock)
 {
+       struct inode            *inode = VFS_I(ip);
        struct xfs_mount        *mp = ip->i_mount;
-       int                     error = EAGAIN;
+       int                     error;
+
+       spin_lock(&ip->i_flags_lock);
 
        /*
-        * If INEW is set this inode is being set up
-        * If IRECLAIM is set this inode is being torn down
-        * Pause and try again.
+        * If we are racing with another cache hit that is currently
+        * instantiating this inode or currently recycling it out of
+        * reclaimabe state, wait for the initialisation to complete
+        * before continuing.
+        *
+        * XXX(hch): eventually we should do something equivalent to
+        *           wait_on_inode to wait for these flags to be cleared
+        *           instead of polling for it.
         */
-       if (xfs_iflags_test(ip, (XFS_INEW|XFS_IRECLAIM))) {
+       if (ip->i_flags & (XFS_INEW|XFS_IRECLAIM)) {
                XFS_STATS_INC(xs_ig_frecycle);
+               error = EAGAIN;
                goto out_error;
        }
 
-       /* If IRECLAIMABLE is set, we've torn down the vfs inode part */
-       if (xfs_iflags_test(ip, XFS_IRECLAIMABLE)) {
-
-               /*
-                * If lookup is racing with unlink, then we should return an
-                * error immediately so we don't remove it from the reclaim
-                * list and potentially leak the inode.
-                */
-               if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
-                       error = ENOENT;
-                       goto out_error;
-               }
+       /*
+        * If lookup is racing with unlink return an error immediately.
+        */
+       if (ip->i_d.di_mode == 0 && !(flags & XFS_IGET_CREATE)) {
+               error = ENOENT;
+               goto out_error;
+       }
 
+       /*
+        * If IRECLAIMABLE is set, we've torn down the VFS inode already.
+        * Need to carefully get it back into useable state.
+        */
+       if (ip->i_flags & XFS_IRECLAIMABLE) {
                xfs_itrace_exit_tag(ip, "xfs_iget.alloc");
 
                /*
-                * We need to re-initialise the VFS inode as it has been
-                * 'freed' by the VFS. Do this here so we can deal with
-                * errors cleanly, then tag it so it can be set up correctly
-                * later.
+                * We need to set XFS_INEW atomically with clearing the
+                * reclaimable tag so that we do have an indicator of the
+                * inode still being initialized.
                 */
-               if (inode_init_always(mp->m_super, VFS_I(ip))) {
-                       error = ENOMEM;
-                       goto out_error;
-               }
+               ip->i_flags |= XFS_INEW;
+               ip->i_flags &= ~XFS_IRECLAIMABLE;
+               __xfs_inode_clear_reclaim_tag(mp, pag, ip);
 
-               /*
-                * We must set the XFS_INEW flag before clearing the
-                * XFS_IRECLAIMABLE flag so that if a racing lookup does
-                * not find the XFS_IRECLAIMABLE above but has the igrab()
-                * below succeed we can safely check XFS_INEW to detect
-                * that this inode is still being initialised.
-                */
-               xfs_iflags_set(ip, XFS_INEW);
-               xfs_iflags_clear(ip, XFS_IRECLAIMABLE);
+               spin_unlock(&ip->i_flags_lock);
+               read_unlock(&pag->pag_ici_lock);
 
-               /* clear the radix tree reclaim flag as well. */
-               __xfs_inode_clear_reclaim_tag(mp, pag, ip);
-       } else if (!igrab(VFS_I(ip))) {
+               error = -inode_init_always(mp->m_super, inode);
+               if (error) {
+                       /*
+                        * Re-initializing the inode failed, and we are in deep
+                        * trouble.  Try to re-add it to the reclaim list.
+                        */
+                       read_lock(&pag->pag_ici_lock);
+                       spin_lock(&ip->i_flags_lock);
+
+                       ip->i_flags &= ~XFS_INEW;
+                       ip->i_flags |= XFS_IRECLAIMABLE;
+                       __xfs_inode_set_reclaim_tag(pag, ip);
+                       goto out_error;
+               }
+               inode->i_state = I_LOCK|I_NEW;
+       } else {
                /* If the VFS inode is being torn down, pause and try again. */
-               XFS_STATS_INC(xs_ig_frecycle);
-               goto out_error;
-       } else if (xfs_iflags_test(ip, XFS_INEW)) {
-               /*
-                * We are racing with another cache hit that is
-                * currently recycling this inode out of the XFS_IRECLAIMABLE
-                * state. Wait for the initialisation to complete before
-                * continuing.
-                */
-               wait_on_inode(VFS_I(ip));
-       }
+               if (!igrab(inode)) {
+                       error = EAGAIN;
+                       goto out_error;
+               }
 
-       if (ip->i_d.di_mode == 0 && !(flags & XFS_IGET_CREATE)) {
-               error = ENOENT;
-               iput(VFS_I(ip));
-               goto out_error;
+               /* We've got a live one. */
+               spin_unlock(&ip->i_flags_lock);
+               read_unlock(&pag->pag_ici_lock);
        }
 
-       /* We've got a live one. */
-       read_unlock(&pag->pag_ici_lock);
-
        if (lock_flags != 0)
                xfs_ilock(ip, lock_flags);
 
@@ -274,6 +276,7 @@ xfs_iget_cache_hit(
        return 0;
 
 out_error:
+       spin_unlock(&ip->i_flags_lock);
        read_unlock(&pag->pag_ici_lock);
        return error;
 }
index 0ffa41df0ee8ca007d9cda5b40fdbe315ee0a845..710e901085d0237195ca7a3d30b91b537287dc77 100644 (file)
@@ -19,6 +19,11 @@ enum {
  * @packets: number of seen packets
  */
 struct gnet_stats_basic
+{
+       __u64   bytes;
+       __u32   packets;
+};
+struct gnet_stats_basic_packed
 {
        __u64   bytes;
        __u32   packets;
index ba3a7cb1eaa0d6a3d3c67401592728c58742917f..9a72cc78e6b817d2b7c24b076eef7bd0061235f2 100644 (file)
@@ -34,8 +34,6 @@ extern int sysctl_legacy_va_layout;
 #define sysctl_legacy_va_layout 0
 #endif
 
-extern unsigned long mmap_min_addr;
-
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -574,19 +572,6 @@ static inline void set_page_links(struct page *page, enum zone_type zone,
        set_page_section(page, pfn_to_section_nr(pfn));
 }
 
-/*
- * If a hint addr is less than mmap_min_addr change hint to be as
- * low as possible but still greater than mmap_min_addr
- */
-static inline unsigned long round_hint_to_min(unsigned long hint)
-{
-       hint &= PAGE_MASK;
-       if (((void *)hint != NULL) &&
-           (hint < mmap_min_addr))
-               return PAGE_ALIGN(mmap_min_addr);
-       return hint;
-}
-
 /*
  * Some inline functions in vmstat.h depend on page_zone()
  */
index 5eff459b38338ace06bb7d9e83d10a462b906203..1f16eea2017b1062caf0be4540c4e0cb19a2bb27 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/resource.h>
 #include <linux/sem.h>
 #include <linux/shm.h>
+#include <linux/mm.h> /* PAGE_ALIGN */
 #include <linux/msg.h>
 #include <linux/sched.h>
 #include <linux/key.h>
@@ -66,6 +67,9 @@ extern int cap_inode_setxattr(struct dentry *dentry, const char *name,
 extern int cap_inode_removexattr(struct dentry *dentry, const char *name);
 extern int cap_inode_need_killpriv(struct dentry *dentry);
 extern int cap_inode_killpriv(struct dentry *dentry);
+extern int cap_file_mmap(struct file *file, unsigned long reqprot,
+                        unsigned long prot, unsigned long flags,
+                        unsigned long addr, unsigned long addr_only);
 extern int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags);
 extern int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
                          unsigned long arg4, unsigned long arg5);
@@ -92,6 +96,7 @@ extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
 extern int cap_netlink_recv(struct sk_buff *skb, int cap);
 
 extern unsigned long mmap_min_addr;
+extern unsigned long dac_mmap_min_addr;
 /*
  * Values used in the task_security_ops calls
  */
@@ -116,6 +121,21 @@ struct request_sock;
 #define LSM_UNSAFE_PTRACE      2
 #define LSM_UNSAFE_PTRACE_CAP  4
 
+/*
+ * If a hint addr is less than mmap_min_addr change hint to be as
+ * low as possible but still greater than mmap_min_addr
+ */
+static inline unsigned long round_hint_to_min(unsigned long hint)
+{
+       hint &= PAGE_MASK;
+       if (((void *)hint != NULL) &&
+           (hint < mmap_min_addr))
+               return PAGE_ALIGN(mmap_min_addr);
+       return hint;
+}
+extern int mmap_min_addr_handler(struct ctl_table *table, int write, struct file *filp,
+                                void __user *buffer, size_t *lenp, loff_t *ppos);
+
 #ifdef CONFIG_SECURITY
 
 struct security_mnt_opts {
@@ -2197,9 +2217,7 @@ static inline int security_file_mmap(struct file *file, unsigned long reqprot,
                                     unsigned long addr,
                                     unsigned long addr_only)
 {
-       if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO))
-               return -EACCES;
-       return 0;
+       return cap_file_mmap(file, reqprot, prot, flags, addr, addr_only);
 }
 
 static inline int security_file_mprotect(struct vm_area_struct *vma,
index 565eed8fe496d55c81c3454564eb5605e27afd71..c05fd717c588801a72c4fe7a18a000b4bf46e35c 100644 (file)
@@ -16,7 +16,7 @@ struct tcf_common {
        u32                             tcfc_capab;
        int                             tcfc_action;
        struct tcf_t                    tcfc_tm;
-       struct gnet_stats_basic         tcfc_bstats;
+       struct gnet_stats_basic_packed  tcfc_bstats;
        struct gnet_stats_queue         tcfc_qstats;
        struct gnet_stats_rate_est      tcfc_rate_est;
        spinlock_t                      tcfc_lock;
index d136b5240ef24a2e41cb6843b27d724295b4b9d3..c1488553e34964b9dbd4a3a66334d4c1f04f16bd 100644 (file)
@@ -28,7 +28,7 @@ extern int gnet_stats_start_copy_compat(struct sk_buff *skb, int type,
                                        spinlock_t *lock, struct gnet_dump *d);
 
 extern int gnet_stats_copy_basic(struct gnet_dump *d,
-                                struct gnet_stats_basic *b);
+                                struct gnet_stats_basic_packed *b);
 extern int gnet_stats_copy_rate_est(struct gnet_dump *d,
                                    struct gnet_stats_rate_est *r);
 extern int gnet_stats_copy_queue(struct gnet_dump *d,
@@ -37,14 +37,14 @@ extern int gnet_stats_copy_app(struct gnet_dump *d, void *st, int len);
 
 extern int gnet_stats_finish_copy(struct gnet_dump *d);
 
-extern int gen_new_estimator(struct gnet_stats_basic *bstats,
+extern int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
                             struct gnet_stats_rate_est *rate_est,
                             spinlock_t *stats_lock, struct nlattr *opt);
-extern void gen_kill_estimator(struct gnet_stats_basic *bstats,
+extern void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
                               struct gnet_stats_rate_est *rate_est);
-extern int gen_replace_estimator(struct gnet_stats_basic *bstats,
+extern int gen_replace_estimator(struct gnet_stats_basic_packed *bstats,
                                 struct gnet_stats_rate_est *rate_est,
                                 spinlock_t *stats_lock, struct nlattr *opt);
-extern bool gen_estimator_active(const struct gnet_stats_basic *bstats,
+extern bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats,
                                 const struct gnet_stats_rate_est *rate_est);
 #endif
index 65d594dffbff431e35a0ac7ec29a051bb022c8b6..ddbf37e19616a486b73b15a7e5314c47e1ed80a8 100644 (file)
@@ -8,7 +8,7 @@ struct xt_rateest {
        spinlock_t                      lock;
        struct gnet_estimator           params;
        struct gnet_stats_rate_est      rstats;
-       struct gnet_stats_basic         bstats;
+       struct gnet_stats_basic_packed  bstats;
 };
 
 extern struct xt_rateest *xt_rateest_lookup(const char *name);
index 964ffa0d8815139ae22d351590b5673a4dd38850..5482e9582f555ea9bae1d2a8e5f42bd571f97819 100644 (file)
@@ -72,7 +72,7 @@ struct Qdisc
         */
        unsigned long           state;
        struct sk_buff_head     q;
-       struct gnet_stats_basic bstats;
+       struct gnet_stats_basic_packed bstats;
        struct gnet_stats_queue qstats;
 };
 
index 98e02328c67de053dc55bdee746ca381e526660e..58be76017fd000f3b019c0acab6d3cdeb672afda 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/acpi.h>
 #include <linux/reboot.h>
 #include <linux/ftrace.h>
+#include <linux/security.h>
 #include <linux/slow-work.h>
 #include <linux/perf_counter.h>
 
@@ -1306,10 +1307,10 @@ static struct ctl_table vm_table[] = {
        {
                .ctl_name       = CTL_UNNUMBERED,
                .procname       = "mmap_min_addr",
-               .data           = &mmap_min_addr,
-               .maxlen         = sizeof(unsigned long),
+               .data           = &dac_mmap_min_addr,
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0644,
-               .proc_handler   = &proc_doulongvec_minmax,
+               .proc_handler   = &mmap_min_addr_handler,
        },
 #ifdef CONFIG_NUMA
        {
index c948d4ca8bde0dc0d73ba1c40b984d395a73b4d8..fe5f674d7a7d571a1f456d2df3d5a31bb965db2e 100644 (file)
@@ -225,9 +225,9 @@ config DEFAULT_MMAP_MIN_ADDR
          For most ia64, ppc64 and x86 users with lots of address space
          a value of 65536 is reasonable and should cause no problems.
          On arm and other archs it should not be higher than 32768.
-         Programs which use vm86 functionality would either need additional
-         permissions from either the LSM or the capabilities module or have
-         this protection disabled.
+         Programs which use vm86 functionality or have some need to map
+         this low address space will need CAP_SYS_RAWIO or disable this
+         protection by setting the value to 0.
 
          This value can be changed after boot using the
          /proc/sys/vm/mmap_min_addr tunable.
index 34579b23ebd55ebed1a99a5473c6ca0693b559e2..8101de490c73941ab8815733a3899c614cdb8cb7 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -88,9 +88,6 @@ int sysctl_overcommit_ratio = 50;     /* default is 50% */
 int sysctl_max_map_count __read_mostly = DEFAULT_MAX_MAP_COUNT;
 struct percpu_counter vm_committed_as;
 
-/* amount of vm to protect from userspace access */
-unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
-
 /*
  * Check that a process has enough memory to allocate a new virtual
  * mapping. 0 means there is enough memory for the allocation to
index 53cab10fece40a3f5835604e62754818de0e1e7c..28754c40be986608e96fe3cb1db7111a6e161cf8 100644 (file)
@@ -69,9 +69,6 @@ int sysctl_max_map_count = DEFAULT_MAX_MAP_COUNT;
 int sysctl_nr_trim_pages = CONFIG_NOMMU_INITIAL_TRIM_EXCESS;
 int heap_stack_gap = 0;
 
-/* amount of vm to protect from userspace access */
-unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
-
 atomic_long_t mmap_pages_allocated;
 
 EXPORT_SYMBOL(mem_map);
index bfbe13786bb468acfeedb888e8ee4a209c34b2e2..875eda5dbad7777949fcbdc848d6ee29ed0d7cec 100644 (file)
@@ -1238,6 +1238,7 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
                        return -ENOBUFS;
 
        *uaddr_len = sizeof(struct sockaddr_at);
+       memset(&sat.sat_zero, 0, sizeof(sat.sat_zero));
 
        if (peer) {
                if (sk->sk_state != TCP_ESTABLISHED)
index f4cc44548bdaa35a2b6947b8c7ef89affe8ac615..db3152df7d2b627fd2484c14734e9a084d3e93a0 100644 (file)
@@ -401,6 +401,7 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
        if (peer)
                return -EOPNOTSUPP;
 
+       memset(addr, 0, sizeof(*addr));
        addr->can_family  = AF_CAN;
        addr->can_ifindex = ro->ifindex;
 
index 78e5bfc454ae00e627705515cbd857cd3d9c67d9..493775f4f2f1d7c19b618640e186aae7195ded53 100644 (file)
@@ -81,7 +81,7 @@
 struct gen_estimator
 {
        struct list_head        list;
-       struct gnet_stats_basic *bstats;
+       struct gnet_stats_basic_packed  *bstats;
        struct gnet_stats_rate_est      *rate_est;
        spinlock_t              *stats_lock;
        int                     ewma_log;
@@ -165,7 +165,7 @@ static void gen_add_node(struct gen_estimator *est)
 }
 
 static
-struct gen_estimator *gen_find_node(const struct gnet_stats_basic *bstats,
+struct gen_estimator *gen_find_node(const struct gnet_stats_basic_packed *bstats,
                                    const struct gnet_stats_rate_est *rate_est)
 {
        struct rb_node *p = est_root.rb_node;
@@ -202,7 +202,7 @@ struct gen_estimator *gen_find_node(const struct gnet_stats_basic *bstats,
  *
  * NOTE: Called under rtnl_mutex
  */
-int gen_new_estimator(struct gnet_stats_basic *bstats,
+int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
                      struct gnet_stats_rate_est *rate_est,
                      spinlock_t *stats_lock,
                      struct nlattr *opt)
@@ -262,7 +262,7 @@ static void __gen_kill_estimator(struct rcu_head *head)
  *
  * NOTE: Called under rtnl_mutex
  */
-void gen_kill_estimator(struct gnet_stats_basic *bstats,
+void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
                        struct gnet_stats_rate_est *rate_est)
 {
        struct gen_estimator *e;
@@ -292,7 +292,7 @@ EXPORT_SYMBOL(gen_kill_estimator);
  *
  * Returns 0 on success or a negative error code.
  */
-int gen_replace_estimator(struct gnet_stats_basic *bstats,
+int gen_replace_estimator(struct gnet_stats_basic_packed *bstats,
                          struct gnet_stats_rate_est *rate_est,
                          spinlock_t *stats_lock, struct nlattr *opt)
 {
@@ -308,7 +308,7 @@ EXPORT_SYMBOL(gen_replace_estimator);
  *
  * Returns true if estimator is active, and false if not.
  */
-bool gen_estimator_active(const struct gnet_stats_basic *bstats,
+bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats,
                          const struct gnet_stats_rate_est *rate_est)
 {
        ASSERT_RTNL();
index c3d0ffeac24342417bca0017e3d55e7c05100018..8569310268ab76ba786402e6b2e6dc994621a7fd 100644 (file)
@@ -106,16 +106,21 @@ gnet_stats_start_copy(struct sk_buff *skb, int type, spinlock_t *lock,
  * if the room in the socket buffer was not sufficient.
  */
 int
-gnet_stats_copy_basic(struct gnet_dump *d, struct gnet_stats_basic *b)
+gnet_stats_copy_basic(struct gnet_dump *d, struct gnet_stats_basic_packed *b)
 {
        if (d->compat_tc_stats) {
                d->tc_stats.bytes = b->bytes;
                d->tc_stats.packets = b->packets;
        }
 
-       if (d->tail)
-               return gnet_stats_copy(d, TCA_STATS_BASIC, b, sizeof(*b));
+       if (d->tail) {
+               struct gnet_stats_basic sb;
 
+               memset(&sb, 0, sizeof(sb));
+               sb.bytes = b->bytes;
+               sb.packets = b->packets;
+               return gnet_stats_copy(d, TCA_STATS_BASIC, &sb, sizeof(sb));
+       }
        return 0;
 }
 
index 3281013ce038e02bafd4166716605185f4224e0f..1bca9205104e6c5ff41b4e3562825f9cf1079e9b 100644 (file)
@@ -1159,6 +1159,7 @@ static void __exit dccp_fini(void)
        kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
        dccp_ackvec_exit();
        dccp_sysctl_exit();
+       percpu_counter_destroy(&dccp_orphan_count);
 }
 
 module_init(dccp_init);
index 2e1f836d424064ffe346321e053c136f86682545..f0bbc57926cdbbb8d70b3e2e59cbdd4f090800f3 100644 (file)
@@ -520,6 +520,7 @@ static int econet_getname(struct socket *sock, struct sockaddr *uaddr,
        if (peer)
                return -EOPNOTSUPP;
 
+       memset(sec, 0, sizeof(*sec));
        mutex_lock(&econet_mutex);
 
        sk = sock->sk;
index 3bb6bdb1dac1d95b537af4752b4039acfd1d52e2..af661805b9fa2a916f4a670ff3c96223e26a03d2 100644 (file)
@@ -136,7 +136,7 @@ static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg,
                unsigned int cmd)
 {
        struct ifreq ifr;
-       int ret = -EINVAL;
+       int ret = -ENOIOCTLCMD;
        struct net_device *dev;
 
        if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
@@ -146,8 +146,10 @@ static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg,
 
        dev_load(sock_net(sk), ifr.ifr_name);
        dev = dev_get_by_name(sock_net(sk), ifr.ifr_name);
-       if (dev->type == ARPHRD_IEEE802154 ||
-           dev->type == ARPHRD_IEEE802154_PHY)
+
+       if ((dev->type == ARPHRD_IEEE802154 ||
+            dev->type == ARPHRD_IEEE802154_PHY) &&
+           dev->netdev_ops->ndo_do_ioctl)
                ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd);
 
        if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq)))
index 14d39840dd62e736e9dfb96efc011c5b41dd92ab..ba8b214dda8fc027c802fcc65c9845be40d0c562 100644 (file)
@@ -377,6 +377,18 @@ int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb)
        return ret;
 }
 
+static int dgram_getsockopt(struct sock *sk, int level, int optname,
+                   char __user *optval, int __user *optlen)
+{
+       return -EOPNOTSUPP;
+}
+
+static int dgram_setsockopt(struct sock *sk, int level, int optname,
+                   char __user *optval, int __user optlen)
+{
+       return -EOPNOTSUPP;
+}
+
 struct proto ieee802154_dgram_prot = {
        .name           = "IEEE-802.15.4-MAC",
        .owner          = THIS_MODULE,
@@ -391,5 +403,7 @@ struct proto ieee802154_dgram_prot = {
        .connect        = dgram_connect,
        .disconnect     = dgram_disconnect,
        .ioctl          = dgram_ioctl,
+       .getsockopt     = dgram_getsockopt,
+       .setsockopt     = dgram_setsockopt,
 };
 
index fca44d59f97ec05ca02d9221da22d5b6b9fea3dc..9315977c4c61de127499d9e151586f82cd8a61f4 100644 (file)
@@ -238,6 +238,18 @@ void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb)
        read_unlock(&raw_lock);
 }
 
+static int raw_getsockopt(struct sock *sk, int level, int optname,
+                   char __user *optval, int __user *optlen)
+{
+       return -EOPNOTSUPP;
+}
+
+static int raw_setsockopt(struct sock *sk, int level, int optname,
+                   char __user *optval, int __user optlen)
+{
+       return -EOPNOTSUPP;
+}
+
 struct proto ieee802154_raw_prot = {
        .name           = "IEEE-802.15.4-RAW",
        .owner          = THIS_MODULE,
@@ -250,5 +262,7 @@ struct proto ieee802154_raw_prot = {
        .unhash         = raw_unhash,
        .connect        = raw_connect,
        .disconnect     = raw_disconnect,
+       .getsockopt     = raw_getsockopt,
+       .setsockopt     = raw_setsockopt,
 };
 
index cb4a0f4bd5e5654b465ddee4f32a42504711d5d3..82c11dd10a628947e1486e300918acd848e0d718 100644 (file)
@@ -951,7 +951,7 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev)
                        addend += 4;
        }
        dev->needed_headroom = addend + hlen;
-       mtu -= dev->hard_header_len - addend;
+       mtu -= dev->hard_header_len + addend;
 
        if (mtu < 68)
                mtu = 68;
index 80cf29aae0967a8935646ecda366b94168449a1a..50b43c57d5d8e01c94796b988fa6e98a7f4aee2b 100644 (file)
@@ -715,6 +715,7 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr,
        struct sock *sk = sock->sk;
        struct irda_sock *self = irda_sk(sk);
 
+       memset(&saddr, 0, sizeof(saddr));
        if (peer) {
                if (sk->sk_state != TCP_ESTABLISHED)
                        return -ENOTCONN;
index 9e5762ad307d9faa55d4bd11400c5d76e7852dcc..a24e59816b9370018d9a01be95f065f9eb2a5745 100644 (file)
@@ -381,6 +381,14 @@ static void ieee80211_agg_splice_packets(struct ieee80211_local *local,
                &local->hw, queue,
                IEEE80211_QUEUE_STOP_REASON_AGGREGATION);
 
+       if (!(sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK))
+               return;
+
+       if (WARN(!sta->ampdu_mlme.tid_tx[tid],
+                "TID %d gone but expected when splicing aggregates from"
+                "the pending queue\n", tid))
+               return;
+
        if (!skb_queue_empty(&sta->ampdu_mlme.tid_tx[tid]->pending)) {
                spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
                /* mark queue as pending, it is stopped already */
index 43f5676b1af405d1a0c12a374710ae543d06346a..d80b8192e0d423a2f66ec27ea06efbcaf174d681 100644 (file)
@@ -74,7 +74,7 @@ static unsigned int
 xt_rateest_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
        const struct xt_rateest_target_info *info = par->targinfo;
-       struct gnet_stats_basic *stats = &info->est->bstats;
+       struct gnet_stats_basic_packed *stats = &info->est->bstats;
 
        spin_lock_bh(&info->est->lock);
        stats->bytes += skb->len;
index ce51ce012cdab48e4c0bbfd99c3053a0bfcaa636..ce1a34b99c2328f16648d5cf96cb8ff5edc25ed6 100644 (file)
@@ -847,6 +847,7 @@ static int nr_getname(struct socket *sock, struct sockaddr *uaddr,
                sax->fsa_ax25.sax25_family = AF_NETROM;
                sax->fsa_ax25.sax25_ndigis = 1;
                sax->fsa_ax25.sax25_call   = nr->user_addr;
+               memset(sax->fsa_digipeater, 0, sizeof(sax->fsa_digipeater));
                sax->fsa_digipeater[0]     = nr->dest_addr;
                *uaddr_len = sizeof(struct full_sockaddr_ax25);
        } else {
index e943c16552a204badf0737b3550d11f6d85df663..4eb1ac9a7679ca3c14c0d9c651fbbf1d4fe76694 100644 (file)
@@ -630,23 +630,23 @@ out:
        return dev;
 }
 
-static ax25_digi *nr_call_to_digi(int ndigis, ax25_address *digipeaters)
+static ax25_digi *nr_call_to_digi(ax25_digi *digi, int ndigis,
+       ax25_address *digipeaters)
 {
-       static ax25_digi ax25_digi;
        int i;
 
        if (ndigis == 0)
                return NULL;
 
        for (i = 0; i < ndigis; i++) {
-               ax25_digi.calls[i]    = digipeaters[i];
-               ax25_digi.repeated[i] = 0;
+               digi->calls[i]    = digipeaters[i];
+               digi->repeated[i] = 0;
        }
 
-       ax25_digi.ndigi      = ndigis;
-       ax25_digi.lastrepeat = -1;
+       digi->ndigi      = ndigis;
+       digi->lastrepeat = -1;
 
-       return &ax25_digi;
+       return digi;
 }
 
 /*
@@ -656,6 +656,7 @@ int nr_rt_ioctl(unsigned int cmd, void __user *arg)
 {
        struct nr_route_struct nr_route;
        struct net_device *dev;
+       ax25_digi digi;
        int ret;
 
        switch (cmd) {
@@ -673,13 +674,15 @@ int nr_rt_ioctl(unsigned int cmd, void __user *arg)
                        ret = nr_add_node(&nr_route.callsign,
                                nr_route.mnemonic,
                                &nr_route.neighbour,
-                               nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters),
+                               nr_call_to_digi(&digi, nr_route.ndigis,
+                                               nr_route.digipeaters),
                                dev, nr_route.quality,
                                nr_route.obs_count);
                        break;
                case NETROM_NEIGH:
                        ret = nr_add_neigh(&nr_route.callsign,
-                               nr_call_to_digi(nr_route.ndigis, nr_route.digipeaters),
+                               nr_call_to_digi(&digi, nr_route.ndigis,
+                                               nr_route.digipeaters),
                                dev, nr_route.quality);
                        break;
                default:
index b0d6ddd82a9da1b20ce14bf2b76099cdf72362bc..c2b77a698695371a5b08d2da94876ff2a71f50c7 100644 (file)
@@ -96,7 +96,7 @@ struct net_device *phonet_device_get(struct net *net)
 {
        struct phonet_device_list *pndevs = phonet_device_list(net);
        struct phonet_device *pnd;
-       struct net_device *dev;
+       struct net_device *dev = NULL;
 
        spin_lock_bh(&pndevs->lock);
        list_for_each_entry(pnd, &pndevs->list, list) {
index f0a76f6bca711a064f4611a592c82eeca9968f0f..e5f478ca3d61574e01bc74bad58cfdc910a33b4a 100644 (file)
@@ -954,6 +954,7 @@ static int rose_getname(struct socket *sock, struct sockaddr *uaddr,
        struct rose_sock *rose = rose_sk(sk);
        int n;
 
+       memset(srose, 0, sizeof(*srose));
        if (peer != 0) {
                if (sk->sk_state != TCP_ESTABLISHED)
                        return -ENOTCONN;
index 2a8b83af7c47a4bbee4471cc62894d46ca1d233a..ab82f145f68937a9c722322517fd2dd479550db0 100644 (file)
@@ -49,7 +49,7 @@ struct atm_flow_data {
        struct socket           *sock;          /* for closing */
        u32                     classid;        /* x:y type ID */
        int                     ref;            /* reference count */
-       struct gnet_stats_basic bstats;
+       struct gnet_stats_basic_packed  bstats;
        struct gnet_stats_queue qstats;
        struct atm_flow_data    *next;
        struct atm_flow_data    *excess;        /* flow for excess traffic;
index 23a167670fd5f11ed1affcfb07b9ad766b381b81..d5798e17a83205f3a44ac09d3c4b5318801d24d4 100644 (file)
@@ -128,7 +128,7 @@ struct cbq_class
        long                    avgidle;
        long                    deficit;        /* Saved deficit for WRR */
        psched_time_t           penalized;
-       struct gnet_stats_basic bstats;
+       struct gnet_stats_basic_packed bstats;
        struct gnet_stats_queue qstats;
        struct gnet_stats_rate_est rate_est;
        struct tc_cbq_xstats    xstats;
index 7597fe14686600e6fa2584544b69ebdfb1144edf..12b2fb04b29b6d4d873e6fe28981dabd7de039b6 100644 (file)
@@ -22,7 +22,7 @@ struct drr_class {
        unsigned int                    refcnt;
        unsigned int                    filter_cnt;
 
-       struct gnet_stats_basic         bstats;
+       struct gnet_stats_basic_packed          bstats;
        struct gnet_stats_queue         qstats;
        struct gnet_stats_rate_est      rate_est;
        struct list_head                alist;
index 362c2811b2dfe95b93daf0d3f10cf98a06373cd6..dad0144423da5a87be4d18c76333cca56f05af84 100644 (file)
@@ -116,7 +116,7 @@ struct hfsc_class
        struct Qdisc_class_common cl_common;
        unsigned int    refcnt;         /* usage count */
 
-       struct gnet_stats_basic bstats;
+       struct gnet_stats_basic_packed bstats;
        struct gnet_stats_queue qstats;
        struct gnet_stats_rate_est rate_est;
        unsigned int    level;          /* class level in hierarchy */
index 88cd0262662138f02fa18393a72667fc172e91c1..ec4d46399d59fbdfa638394b54136a294bf200bc 100644 (file)
@@ -74,7 +74,7 @@ enum htb_cmode {
 struct htb_class {
        struct Qdisc_class_common common;
        /* general class parameters */
-       struct gnet_stats_basic bstats;
+       struct gnet_stats_basic_packed bstats;
        struct gnet_stats_queue qstats;
        struct gnet_stats_rate_est rate_est;
        struct tc_htb_xstats xstats;    /* our special stats */
index 79cbd47f4df7482b08e11c976d290b5b94ee545b..a76da657244a8e38fdb692426857130034da5fd0 100644 (file)
@@ -160,6 +160,7 @@ static void sctp_proc_exit(void)
                remove_proc_entry("sctp", init_net.proc_net);
        }
 #endif
+       percpu_counter_destroy(&sctp_sockets_allocated);
 }
 
 /* Private helper to extract ipv4 address and stash them in
index d401dc8f05ed4b16ddde802bf3d2190d72cd2cf3..e5195c99f71e267e70cb62b3689f7e6f02a809dd 100644 (file)
@@ -16,7 +16,7 @@ static inline unsigned int __xfrm6_addr_hash(xfrm_address_t *addr)
 
 static inline unsigned int __xfrm4_daddr_saddr_hash(xfrm_address_t *daddr, xfrm_address_t *saddr)
 {
-       return ntohl(daddr->a4 ^ saddr->a4);
+       return ntohl(daddr->a4 + saddr->a4);
 }
 
 static inline unsigned int __xfrm6_daddr_saddr_hash(xfrm_address_t *daddr, xfrm_address_t *saddr)
index d23c839038f00836cb96a51e53e27db8b8ec163c..9c60c346a91ddded5dcbff3186a0c501619ae477 100644 (file)
@@ -113,6 +113,22 @@ config SECURITY_ROOTPLUG
 
          If you are unsure how to answer this question, answer N.
 
+config LSM_MMAP_MIN_ADDR
+       int "Low address space for LSM to from user allocation"
+       depends on SECURITY && SECURITY_SELINUX
+       default 65535
+       help
+         This is the portion of low virtual memory which should be protected
+         from userspace allocation.  Keeping a user from writing to low pages
+         can help reduce the impact of kernel NULL pointer bugs.
+
+         For most ia64, ppc64 and x86 users with lots of address space
+         a value of 65536 is reasonable and should cause no problems.
+         On arm and other archs it should not be higher than 32768.
+         Programs which use vm86 functionality or have some need to map
+         this low address space will need the permission specific to the
+         systems running LSM.
+
 source security/selinux/Kconfig
 source security/smack/Kconfig
 source security/tomoyo/Kconfig
index c67557cdaa857f9046d30cacb7f3ecc42196f9bb..b56e7f9ecbc2adf22706a849d704d8761dfa91dd 100644 (file)
@@ -8,7 +8,7 @@ subdir-$(CONFIG_SECURITY_SMACK)         += smack
 subdir-$(CONFIG_SECURITY_TOMOYO)        += tomoyo
 
 # always enable default capabilities
-obj-y          += commoncap.o
+obj-y          += commoncap.o min_addr.o
 
 # Object file lists
 obj-$(CONFIG_SECURITY)                 += security.o capability.o
index 21b6cead6a8ed38927abab1bd8cd9c491194c1bf..88f752e8152cbe1ea888747121181035fcb8fbbb 100644 (file)
@@ -330,15 +330,6 @@ static int cap_file_ioctl(struct file *file, unsigned int command,
        return 0;
 }
 
-static int cap_file_mmap(struct file *file, unsigned long reqprot,
-                        unsigned long prot, unsigned long flags,
-                        unsigned long addr, unsigned long addr_only)
-{
-       if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO))
-               return -EACCES;
-       return 0;
-}
-
 static int cap_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
                             unsigned long prot)
 {
index 48b7e0228fa38455ee6c2bf0cb37876e96c99afb..e3097c0a1311205cc231cee85cb012b271db1ed8 100644 (file)
@@ -984,3 +984,33 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
                cap_sys_admin = 1;
        return __vm_enough_memory(mm, pages, cap_sys_admin);
 }
+
+/*
+ * cap_file_mmap - check if able to map given addr
+ * @file: unused
+ * @reqprot: unused
+ * @prot: unused
+ * @flags: unused
+ * @addr: address attempting to be mapped
+ * @addr_only: unused
+ *
+ * If the process is attempting to map memory below mmap_min_addr they need
+ * CAP_SYS_RAWIO.  The other parameters to this function are unused by the
+ * capability security module.  Returns 0 if this mapping should be allowed
+ * -EPERM if not.
+ */
+int cap_file_mmap(struct file *file, unsigned long reqprot,
+                 unsigned long prot, unsigned long flags,
+                 unsigned long addr, unsigned long addr_only)
+{
+       int ret = 0;
+
+       if (addr < dac_mmap_min_addr) {
+               ret = cap_capable(current, current_cred(), CAP_SYS_RAWIO,
+                                 SECURITY_CAP_AUDIT);
+               /* set PF_SUPERPRIV if it turns out we allow the low mmap */
+               if (ret == 0)
+                       current->flags |= PF_SUPERPRIV;
+       }
+       return ret;
+}
diff --git a/security/min_addr.c b/security/min_addr.c
new file mode 100644 (file)
index 0000000..14cc7b3
--- /dev/null
@@ -0,0 +1,49 @@
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/security.h>
+#include <linux/sysctl.h>
+
+/* amount of vm to protect from userspace access by both DAC and the LSM*/
+unsigned long mmap_min_addr;
+/* amount of vm to protect from userspace using CAP_SYS_RAWIO (DAC) */
+unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR;
+/* amount of vm to protect from userspace using the LSM = CONFIG_LSM_MMAP_MIN_ADDR */
+
+/*
+ * Update mmap_min_addr = max(dac_mmap_min_addr, CONFIG_LSM_MMAP_MIN_ADDR)
+ */
+static void update_mmap_min_addr(void)
+{
+#ifdef CONFIG_LSM_MMAP_MIN_ADDR
+       if (dac_mmap_min_addr > CONFIG_LSM_MMAP_MIN_ADDR)
+               mmap_min_addr = dac_mmap_min_addr;
+       else
+               mmap_min_addr = CONFIG_LSM_MMAP_MIN_ADDR;
+#else
+       mmap_min_addr = dac_mmap_min_addr;
+#endif
+}
+
+/*
+ * sysctl handler which just sets dac_mmap_min_addr = the new value and then
+ * calls update_mmap_min_addr() so non MAP_FIXED hints get rounded properly
+ */
+int mmap_min_addr_handler(struct ctl_table *table, int write, struct file *filp,
+                         void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       int ret;
+
+       ret = proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos);
+
+       update_mmap_min_addr();
+
+       return ret;
+}
+
+int __init init_mmap_min_addr(void)
+{
+       update_mmap_min_addr();
+
+       return 0;
+}
+pure_initcall(init_mmap_min_addr);
index 1e8cfc4c2ed6214c7accf4a7429e3e051cf63670..8d8b69c5664ef7f1eaa89c8a19139152ca159477 100644 (file)
@@ -3030,9 +3030,21 @@ static int selinux_file_mmap(struct file *file, unsigned long reqprot,
        int rc = 0;
        u32 sid = current_sid();
 
-       if (addr < mmap_min_addr)
+       /*
+        * notice that we are intentionally putting the SELinux check before
+        * the secondary cap_file_mmap check.  This is such a likely attempt
+        * at bad behaviour/exploit that we always want to get the AVC, even
+        * if DAC would have also denied the operation.
+        */
+       if (addr < CONFIG_LSM_MMAP_MIN_ADDR) {
                rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
                                  MEMPROTECT__MMAP_ZERO, NULL);
+               if (rc)
+                       return rc;
+       }
+
+       /* do DAC check on address space usage */
+       rc = cap_file_mmap(file, reqprot, prot, flags, addr, addr_only);
        if (rc || addr_only)
                return rc;