diff --git a/[refs] b/[refs] index a901f5ef0f79..1f024ac524ca 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: b06d66be3b0b198ee30bd9f779874ae7115570a0 +refs/heads/master: 083f9560cdff268e2ca82dc90ba9c509742359b8 diff --git a/trunk/Documentation/ABI/testing/sysfs-bus-hsi b/trunk/Documentation/ABI/testing/sysfs-bus-hsi deleted file mode 100644 index 1b1b282a99e1..000000000000 --- a/trunk/Documentation/ABI/testing/sysfs-bus-hsi +++ /dev/null @@ -1,19 +0,0 @@ -What: /sys/bus/hsi -Date: April 2012 -KernelVersion: 3.4 -Contact: Carlos Chinea -Description: - High Speed Synchronous Serial Interface (HSI) is a - serial interface mainly used for connecting application - engines (APE) with cellular modem engines (CMT) in cellular - handsets. - The bus will be populated with devices (hsi_clients) representing - the protocols available in the system. Bus drivers implement - those protocols. - -What: /sys/bus/hsi/devices/.../modalias -Date: April 2012 -KernelVersion: 3.4 -Contact: Carlos Chinea -Description: Stores the same MODALIAS value emitted by uevent - Format: hsi: diff --git a/trunk/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml b/trunk/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml index 5274c24d11e0..3fd3ce5df270 100644 --- a/trunk/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml +++ b/trunk/Documentation/DocBook/media/v4l/pixfmt-nv12m.xml @@ -1,6 +1,6 @@ - V4L2_PIX_FMT_NV12M ('NM12') + V4L2_PIX_FMT_NV12M ('NV12M') &manvol; diff --git a/trunk/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml b/trunk/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml index 60308f1eefdf..9957863daf18 100644 --- a/trunk/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml +++ b/trunk/Documentation/DocBook/media/v4l/pixfmt-yuv420m.xml @@ -1,6 +1,6 @@ - V4L2_PIX_FMT_YUV420M ('YM12') + V4L2_PIX_FMT_YUV420M ('YU12M') &manvol; diff --git a/trunk/Documentation/devicetree/bindings/ata/ahci-platform.txt b/trunk/Documentation/devicetree/bindings/ata/calxeda-sata.txt similarity index 90% rename from trunk/Documentation/devicetree/bindings/ata/ahci-platform.txt rename to trunk/Documentation/devicetree/bindings/ata/calxeda-sata.txt index 8bb8a76d42e8..79caa5651f53 100644 --- a/trunk/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/trunk/Documentation/devicetree/bindings/ata/calxeda-sata.txt @@ -1,10 +1,10 @@ -* AHCI SATA Controller +* Calxeda SATA Controller SATA nodes are defined to describe on-chip Serial ATA controllers. Each SATA controller should have its own node. Required properties: -- compatible : compatible list, contains "calxeda,hb-ahci" or "snps,spear-ahci" +- compatible : compatible list, contains "calxeda,hb-ahci" - interrupts : - reg : @@ -14,3 +14,4 @@ Example: reg = <0xffe08000 0x1000>; interrupts = <115>; }; + diff --git a/trunk/Documentation/devicetree/bindings/sound/sgtl5000.txt b/trunk/Documentation/devicetree/bindings/sound/sgtl5000.txt index 9cc44449508d..2c3cd413f042 100644 --- a/trunk/Documentation/devicetree/bindings/sound/sgtl5000.txt +++ b/trunk/Documentation/devicetree/bindings/sound/sgtl5000.txt @@ -3,8 +3,6 @@ Required properties: - compatible : "fsl,sgtl5000". -- reg : the I2C address of the device - Example: codec: sgtl5000@0a { diff --git a/trunk/Documentation/networking/ip-sysctl.txt b/trunk/Documentation/networking/ip-sysctl.txt index 1619a8c80873..bd80ba5847d2 100644 --- a/trunk/Documentation/networking/ip-sysctl.txt +++ b/trunk/Documentation/networking/ip-sysctl.txt @@ -147,7 +147,7 @@ tcp_adv_win_scale - INTEGER (if tcp_adv_win_scale > 0) or bytes-bytes/2^(-tcp_adv_win_scale), if it is <= 0. Possible values are [-31, 31], inclusive. - Default: 1 + Default: 2 tcp_allowed_congestion_control - STRING Show/set the congestion control choices available to non-privileged @@ -410,7 +410,7 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max net.core.rmem_max. Calling setsockopt() with SO_RCVBUF disables automatic tuning of that socket's receive buffer size, in which case this value is ignored. - Default: between 87380B and 6MB, depending on RAM size. + Default: between 87380B and 4MB, depending on RAM size. tcp_sack - BOOLEAN Enable select acknowledgments (SACKS). diff --git a/trunk/Documentation/power/freezing-of-tasks.txt b/trunk/Documentation/power/freezing-of-tasks.txt index 6ec291ea1c78..ec715cd78fbb 100644 --- a/trunk/Documentation/power/freezing-of-tasks.txt +++ b/trunk/Documentation/power/freezing-of-tasks.txt @@ -9,7 +9,7 @@ architectures). II. How does it work? -There are three per-task flags used for that, PF_NOFREEZE, PF_FROZEN +There are four per-task flags used for that, PF_NOFREEZE, PF_FROZEN, TIF_FREEZE and PF_FREEZER_SKIP (the last one is auxiliary). The tasks that have PF_NOFREEZE unset (all user space processes and some kernel threads) are regarded as 'freezable' and treated in a special way before the system enters a @@ -17,31 +17,30 @@ suspend state as well as before a hibernation image is created (in what follows we only consider hibernation, but the description also applies to suspend). Namely, as the first step of the hibernation procedure the function -freeze_processes() (defined in kernel/power/process.c) is called. A system-wide -variable system_freezing_cnt (as opposed to a per-task flag) is used to indicate -whether the system is to undergo a freezing operation. And freeze_processes() -sets this variable. After this, it executes try_to_freeze_tasks() that sends a -fake signal to all user space processes, and wakes up all the kernel threads. -All freezable tasks must react to that by calling try_to_freeze(), which -results in a call to __refrigerator() (defined in kernel/freezer.c), which sets -the task's PF_FROZEN flag, changes its state to TASK_UNINTERRUPTIBLE and makes -it loop until PF_FROZEN is cleared for it. Then, we say that the task is -'frozen' and therefore the set of functions handling this mechanism is referred -to as 'the freezer' (these functions are defined in kernel/power/process.c, -kernel/freezer.c & include/linux/freezer.h). User space processes are generally -frozen before kernel threads. +freeze_processes() (defined in kernel/power/process.c) is called. It executes +try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and +either wakes them up, if they are kernel threads, or sends fake signals to them, +if they are user space processes. A task that has TIF_FREEZE set, should react +to it by calling the function called __refrigerator() (defined in +kernel/freezer.c), which sets the task's PF_FROZEN flag, changes its state +to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it. +Then, we say that the task is 'frozen' and therefore the set of functions +handling this mechanism is referred to as 'the freezer' (these functions are +defined in kernel/power/process.c, kernel/freezer.c & include/linux/freezer.h). +User space processes are generally frozen before kernel threads. __refrigerator() must not be called directly. Instead, use the try_to_freeze() function (defined in include/linux/freezer.h), that checks -if the task is to be frozen and makes the task enter __refrigerator(). +the task's TIF_FREEZE flag and makes the task enter __refrigerator() if the +flag is set. For user space processes try_to_freeze() is called automatically from the signal-handling code, but the freezable kernel threads need to call it explicitly in suitable places or use the wait_event_freezable() or wait_event_freezable_timeout() macros (defined in include/linux/freezer.h) -that combine interruptible sleep with checking if the task is to be frozen and -calling try_to_freeze(). The main loop of a freezable kernel thread may look -like the following one: +that combine interruptible sleep with checking if TIF_FREEZE is set and calling +try_to_freeze(). The main loop of a freezable kernel thread may look like the +following one: set_freezable(); do { @@ -54,7 +53,7 @@ like the following one: (from drivers/usb/core/hub.c::hub_thread()). If a freezable kernel thread fails to call try_to_freeze() after the freezer has -initiated a freezing operation, the freezing of tasks will fail and the entire +set TIF_FREEZE for it, the freezing of tasks will fail and the entire hibernation operation will be cancelled. For this reason, freezable kernel threads must call try_to_freeze() somewhere or use one of the wait_event_freezable() and wait_event_freezable_timeout() macros. diff --git a/trunk/Documentation/security/keys.txt b/trunk/Documentation/security/keys.txt index d389acd31e19..787717091421 100644 --- a/trunk/Documentation/security/keys.txt +++ b/trunk/Documentation/security/keys.txt @@ -123,7 +123,7 @@ KEY SERVICE OVERVIEW The key service provides a number of features besides keys: - (*) The key service defines three special key types: + (*) The key service defines two special key types: (+) "keyring" @@ -137,18 +137,6 @@ The key service provides a number of features besides keys: blobs of data. These can be created, updated and read by userspace, and aren't intended for use by kernel services. - (+) "logon" - - Like a "user" key, a "logon" key has a payload that is an arbitrary - blob of data. It is intended as a place to store secrets which are - accessible to the kernel but not to userspace programs. - - The description can be arbitrary, but must be prefixed with a non-zero - length string that describes the key "subclass". The subclass is - separated from the rest of the description by a ':'. "logon" keys can - be created and updated from userspace, but the payload is only - readable from kernel space. - (*) Each process subscribes to three keyrings: a thread-specific keyring, a process-specific keyring, and a session-specific keyring. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 707163365a93..b0f1073c40b0 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1968,7 +1968,10 @@ S: Maintained F: drivers/net/ethernet/ti/cpmac.c CPU FREQUENCY DRIVERS +M: Dave Jones L: cpufreq@vger.kernel.org +W: http://www.codemonkey.org.uk/projects/cpufreq/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq.git S: Maintained F: drivers/cpufreq/ F: include/linux/cpufreq.h @@ -2318,9 +2321,9 @@ S: Supported F: drivers/acpi/dock.c DOCUMENTATION -M: Rob Landley +M: Randy Dunlap L: linux-doc@vger.kernel.org -T: TBD +T: quilt http://xenotime.net/kernel-doc-patches/current/ S: Maintained F: Documentation/ @@ -3589,7 +3592,6 @@ S: Supported F: drivers/net/wireless/iwlegacy/ INTEL WIRELESS WIFI LINK (iwlwifi) -M: Johannes Berg M: Wey-Yi Guy M: Intel Linux Wireless L: linux-wireless@vger.kernel.org @@ -5889,11 +5891,11 @@ F: Documentation/scsi/st.txt F: drivers/scsi/st* SCTP PROTOCOL -M: Vlad Yasevich +M: Vlad Yasevich M: Sridhar Samudrala L: linux-sctp@vger.kernel.org W: http://lksctp.sourceforge.net -S: Maintained +S: Supported F: Documentation/networking/sctp.txt F: include/linux/sctp.h F: include/net/sctp/ @@ -7576,8 +7578,8 @@ F: Documentation/filesystems/xfs.txt F: fs/xfs/ XILINX AXI ETHERNET DRIVER -M: Anirudha Sarangi -M: John Linn +M: Ariane Keller +M: Daniel Borkmann S: Maintained F: drivers/net/ethernet/xilinx/xilinx_axienet* diff --git a/trunk/Makefile b/trunk/Makefile index 9e384ae6c403..f6578f47e21e 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 4 SUBLEVEL = 0 -EXTRAVERSION = -rc6 +EXTRAVERSION = -rc3 NAME = Saber-toothed Squirrel # *DOCUMENTATION* diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index 22e58a99f38b..56a4df952fb0 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -477,7 +477,7 @@ config ALPHA_BROKEN_IRQ_MASK config VGA_HOSE bool - depends on VGA_CONSOLE && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI) + depends on ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL || ALPHA_TSUNAMI default y help Support VGA on an arbitrary hose; needed for several platforms diff --git a/trunk/arch/alpha/include/asm/rtc.h b/trunk/arch/alpha/include/asm/rtc.h index d70408d36677..1f7fba671ae6 100644 --- a/trunk/arch/alpha/include/asm/rtc.h +++ b/trunk/arch/alpha/include/asm/rtc.h @@ -1,10 +1,14 @@ #ifndef _ALPHA_RTC_H #define _ALPHA_RTC_H -#if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) \ - || defined(CONFIG_ALPHA_GENERIC) +#if defined(CONFIG_ALPHA_GENERIC) # define get_rtc_time alpha_mv.rtc_get_time # define set_rtc_time alpha_mv.rtc_set_time +#else +# if defined(CONFIG_ALPHA_MARVEL) && defined(CONFIG_SMP) +# define get_rtc_time marvel_get_rtc_time +# define set_rtc_time marvel_set_rtc_time +# endif #endif #include diff --git a/trunk/arch/alpha/kernel/core_tsunami.c b/trunk/arch/alpha/kernel/core_tsunami.c index 61893d7bdda5..5e7c28f92f19 100644 --- a/trunk/arch/alpha/kernel/core_tsunami.c +++ b/trunk/arch/alpha/kernel/core_tsunami.c @@ -11,7 +11,6 @@ #include #undef __EXTERN_INLINE -#include #include #include #include diff --git a/trunk/arch/alpha/kernel/sys_marvel.c b/trunk/arch/alpha/kernel/sys_marvel.c index 407accc80877..14a4b6a7cf59 100644 --- a/trunk/arch/alpha/kernel/sys_marvel.c +++ b/trunk/arch/alpha/kernel/sys_marvel.c @@ -317,7 +317,7 @@ marvel_init_irq(void) } static int -marvel_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +marvel_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pci_controller *hose = dev->sysdata; struct io7_port *io7_port = hose->sysdata; diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 36586dba6fa6..cf006d40342c 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -1186,15 +1186,6 @@ if !MMU source "arch/arm/Kconfig-nommu" endif -config ARM_ERRATA_326103 - bool "ARM errata: FSR write bit incorrect on a SWP to read-only memory" - depends on CPU_V6 - help - Executing a SWP instruction to read-only memory does not set bit 11 - of the FSR on the ARM 1136 prior to r1p0. This causes the kernel to - treat the access as a read, preventing a COW from occurring and - causing the faulting task to livelock. - config ARM_ERRATA_411920 bool "ARM errata: Invalidation of the Instruction Cache operation can fail" depends on CPU_V6 || CPU_V6K diff --git a/trunk/arch/arm/boot/dts/msm8660-surf.dts b/trunk/arch/arm/boot/dts/msm8660-surf.dts index 45bc4bb04e57..15ded0deaa79 100644 --- a/trunk/arch/arm/boot/dts/msm8660-surf.dts +++ b/trunk/arch/arm/boot/dts/msm8660-surf.dts @@ -10,7 +10,7 @@ intc: interrupt-controller@02080000 { compatible = "qcom,msm-8660-qgic"; interrupt-controller; - #interrupt-cells = <3>; + #interrupt-cells = <1>; reg = < 0x02080000 0x1000 >, < 0x02081000 0x1000 >; }; @@ -19,6 +19,6 @@ compatible = "qcom,msm-hsuart", "qcom,msm-uart"; reg = <0x19c40000 0x1000>, <0x19c00000 0x1000>; - interrupts = <0 195 0x0>; + interrupts = <195>; }; }; diff --git a/trunk/arch/arm/boot/dts/versatile-ab.dts b/trunk/arch/arm/boot/dts/versatile-ab.dts index e2fe3195c0d1..0b32925f2147 100644 --- a/trunk/arch/arm/boot/dts/versatile-ab.dts +++ b/trunk/arch/arm/boot/dts/versatile-ab.dts @@ -173,7 +173,7 @@ mmc@5000 { compatible = "arm,primecell"; reg = < 0x5000 0x1000>; - interrupts = <22 34>; + interrupts = <22>; }; kmi@6000 { compatible = "arm,pl050", "arm,primecell"; diff --git a/trunk/arch/arm/boot/dts/versatile-pb.dts b/trunk/arch/arm/boot/dts/versatile-pb.dts index 7e8175269064..166461073b78 100644 --- a/trunk/arch/arm/boot/dts/versatile-pb.dts +++ b/trunk/arch/arm/boot/dts/versatile-pb.dts @@ -41,7 +41,7 @@ mmc@b000 { compatible = "arm,primecell"; reg = <0xb000 0x1000>; - interrupts = <23 34>; + interrupts = <23>; }; }; }; diff --git a/trunk/arch/arm/configs/imx_v4_v5_defconfig b/trunk/arch/arm/configs/imx_v4_v5_defconfig index 6b31cb60daab..b5ac644e12af 100644 --- a/trunk/arch/arm/configs/imx_v4_v5_defconfig +++ b/trunk/arch/arm/configs/imx_v4_v5_defconfig @@ -112,7 +112,6 @@ CONFIG_WATCHDOG=y CONFIG_IMX2_WDT=y CONFIG_MFD_MC13XXX=y CONFIG_REGULATOR=y -CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_MC13783=y CONFIG_REGULATOR_MC13892=y CONFIG_FB=y diff --git a/trunk/arch/arm/configs/mini2440_defconfig b/trunk/arch/arm/configs/mini2440_defconfig index 082175c54e7c..42da9183acc8 100644 --- a/trunk/arch/arm/configs/mini2440_defconfig +++ b/trunk/arch/arm/configs/mini2440_defconfig @@ -14,8 +14,6 @@ CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_BLK_DEV_INTEGRITY=y CONFIG_ARCH_S3C24XX=y -# CONFIG_CPU_S3C2410 is not set -CONFIG_CPU_S3C2440=y CONFIG_S3C_ADC=y CONFIG_S3C24XX_PWM=y CONFIG_MACH_MINI2440=y diff --git a/trunk/arch/arm/configs/u8500_defconfig b/trunk/arch/arm/configs/u8500_defconfig index 7e84f453e8a6..889d73ac1ae1 100644 --- a/trunk/arch/arm/configs/u8500_defconfig +++ b/trunk/arch/arm/configs/u8500_defconfig @@ -8,6 +8,8 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set CONFIG_ARCH_U8500=y +CONFIG_UX500_SOC_DB5500=y +CONFIG_UX500_SOC_DB8500=y CONFIG_MACH_HREFV60=y CONFIG_MACH_SNOWBALL=y CONFIG_MACH_U5500=y @@ -37,6 +39,7 @@ CONFIG_CAIF=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_MISC_DEVICES=y CONFIG_AB8500_PWM=y CONFIG_SENSORS_BH1780=y CONFIG_NETDEVICES=y @@ -62,18 +65,16 @@ CONFIG_SERIAL_AMBA_PL011=y CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_NOMADIK=y +CONFIG_I2C=y +CONFIG_I2C_NOMADIK=y CONFIG_SPI=y CONFIG_SPI_PL022=y CONFIG_GPIO_STMPE=y CONFIG_GPIO_TC3589X=y -CONFIG_POWER_SUPPLY=y -CONFIG_AB8500_BM=y -CONFIG_AB8500_BATTERY_THERM_ON_BATCTRL=y CONFIG_MFD_STMPE=y CONFIG_MFD_TC3589X=y CONFIG_AB5500_CORE=y CONFIG_AB8500_CORE=y -CONFIG_REGULATOR=y CONFIG_REGULATOR_AB8500=y # CONFIG_HID_SUPPORT is not set CONFIG_USB_GADGET=y diff --git a/trunk/arch/arm/include/asm/thread_info.h b/trunk/arch/arm/include/asm/thread_info.h index 0f04d84582e1..d4c24d412a8d 100644 --- a/trunk/arch/arm/include/asm/thread_info.h +++ b/trunk/arch/arm/include/asm/thread_info.h @@ -118,13 +118,6 @@ extern void iwmmxt_task_switch(struct thread_info *); extern void vfp_sync_hwstate(struct thread_info *); extern void vfp_flush_hwstate(struct thread_info *); -struct user_vfp; -struct user_vfp_exc; - -extern int vfp_preserve_user_clear_hwstate(struct user_vfp __user *, - struct user_vfp_exc __user *); -extern int vfp_restore_user_hwstate(struct user_vfp __user *, - struct user_vfp_exc __user *); #endif /* diff --git a/trunk/arch/arm/include/asm/tls.h b/trunk/arch/arm/include/asm/tls.h index 73409e6c0251..60843eb0f61c 100644 --- a/trunk/arch/arm/include/asm/tls.h +++ b/trunk/arch/arm/include/asm/tls.h @@ -7,8 +7,6 @@ .macro set_tls_v6k, tp, tmp1, tmp2 mcr p15, 0, \tp, c13, c0, 3 @ set TLS register - mov \tmp1, #0 - mcr p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register .endm .macro set_tls_v6, tp, tmp1, tmp2 @@ -17,8 +15,6 @@ mov \tmp2, #0xffff0fff tst \tmp1, #HWCAP_TLS @ hardware TLS available? mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register - movne \tmp1, #0 - mcrne p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0 .endm diff --git a/trunk/arch/arm/kernel/irq.c b/trunk/arch/arm/kernel/irq.c index 8349d4e97e2b..71ccdbfed662 100644 --- a/trunk/arch/arm/kernel/irq.c +++ b/trunk/arch/arm/kernel/irq.c @@ -155,10 +155,10 @@ static bool migrate_one_irq(struct irq_desc *desc) } c = irq_data_get_irq_chip(d); - if (!c->irq_set_affinity) + if (c->irq_set_affinity) + c->irq_set_affinity(d, affinity, true); + else pr_debug("IRQ%u: unable to set affinity\n", d->irq); - else if (c->irq_set_affinity(d, affinity, true) == IRQ_SET_MASK_OK && ret) - cpumask_copy(d->affinity, affinity); return ret; } diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index d68d1b694680..7cb532fc8aa4 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -180,23 +180,44 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame) static int preserve_vfp_context(struct vfp_sigframe __user *frame) { + struct thread_info *thread = current_thread_info(); + struct vfp_hard_struct *h = &thread->vfpstate.hard; const unsigned long magic = VFP_MAGIC; const unsigned long size = VFP_STORAGE_SIZE; int err = 0; + vfp_sync_hwstate(thread); __put_user_error(magic, &frame->magic, err); __put_user_error(size, &frame->size, err); - if (err) - return -EFAULT; + /* + * Copy the floating point registers. There can be unused + * registers see asm/hwcap.h for details. + */ + err |= __copy_to_user(&frame->ufp.fpregs, &h->fpregs, + sizeof(h->fpregs)); + /* + * Copy the status and control register. + */ + __put_user_error(h->fpscr, &frame->ufp.fpscr, err); - return vfp_preserve_user_clear_hwstate(&frame->ufp, &frame->ufp_exc); + /* + * Copy the exception registers. + */ + __put_user_error(h->fpexc, &frame->ufp_exc.fpexc, err); + __put_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); + __put_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); + + return err ? -EFAULT : 0; } static int restore_vfp_context(struct vfp_sigframe __user *frame) { + struct thread_info *thread = current_thread_info(); + struct vfp_hard_struct *h = &thread->vfpstate.hard; unsigned long magic; unsigned long size; + unsigned long fpexc; int err = 0; __get_user_error(magic, &frame->magic, err); @@ -207,7 +228,33 @@ static int restore_vfp_context(struct vfp_sigframe __user *frame) if (magic != VFP_MAGIC || size != VFP_STORAGE_SIZE) return -EINVAL; - return vfp_restore_user_hwstate(&frame->ufp, &frame->ufp_exc); + vfp_flush_hwstate(thread); + + /* + * Copy the floating point registers. There can be unused + * registers see asm/hwcap.h for details. + */ + err |= __copy_from_user(&h->fpregs, &frame->ufp.fpregs, + sizeof(h->fpregs)); + /* + * Copy the status and control register. + */ + __get_user_error(h->fpscr, &frame->ufp.fpscr, err); + + /* + * Sanitise and restore the exception registers. + */ + __get_user_error(fpexc, &frame->ufp_exc.fpexc, err); + /* Ensure the VFP is enabled. */ + fpexc |= FPEXC_EN; + /* Ensure FPINST2 is invalid and the exception flag is cleared. */ + fpexc &= ~(FPEXC_EX | FPEXC_FP2V); + h->fpexc = fpexc; + + __get_user_error(h->fpinst, &frame->ufp_exc.fpinst, err); + __get_user_error(h->fpinst2, &frame->ufp_exc.fpinst2, err); + + return err ? -EFAULT : 0; } #endif diff --git a/trunk/arch/arm/kernel/smp.c b/trunk/arch/arm/kernel/smp.c index f6a4d32b0421..addbbe8028c2 100644 --- a/trunk/arch/arm/kernel/smp.c +++ b/trunk/arch/arm/kernel/smp.c @@ -510,6 +510,10 @@ static void ipi_cpu_stop(unsigned int cpu) local_fiq_disable(); local_irq_disable(); +#ifdef CONFIG_HOTPLUG_CPU + platform_cpu_kill(cpu); +#endif + while (1) cpu_relax(); } @@ -572,25 +576,17 @@ void smp_send_reschedule(int cpu) smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); } -#ifdef CONFIG_HOTPLUG_CPU -static void smp_kill_cpus(cpumask_t *mask) -{ - unsigned int cpu; - for_each_cpu(cpu, mask) - platform_cpu_kill(cpu); -} -#else -static void smp_kill_cpus(cpumask_t *mask) { } -#endif - void smp_send_stop(void) { unsigned long timeout; - struct cpumask mask; - cpumask_copy(&mask, cpu_online_mask); - cpumask_clear_cpu(smp_processor_id(), &mask); - smp_cross_call(&mask, IPI_CPU_STOP); + if (num_online_cpus() > 1) { + struct cpumask mask; + cpumask_copy(&mask, cpu_online_mask); + cpumask_clear_cpu(smp_processor_id(), &mask); + + smp_cross_call(&mask, IPI_CPU_STOP); + } /* Wait up to one second for other CPUs to stop */ timeout = USEC_PER_SEC; @@ -599,8 +595,6 @@ void smp_send_stop(void) if (num_online_cpus() > 1) pr_warning("SMP: failed to stop secondary CPUs\n"); - - smp_kill_cpus(&mask); } /* diff --git a/trunk/arch/arm/kernel/smp_twd.c b/trunk/arch/arm/kernel/smp_twd.c index fef42b21cecb..5b150afb995b 100644 --- a/trunk/arch/arm/kernel/smp_twd.c +++ b/trunk/arch/arm/kernel/smp_twd.c @@ -118,10 +118,14 @@ static int twd_cpufreq_transition(struct notifier_block *nb, * The twd clock events must be reprogrammed to account for the new * frequency. The timer is local to a cpu, so cross-call to the * changing cpu. + * + * Only wait for it to finish, if the cpu is active to avoid + * deadlock when cpu1 is spinning on while(!cpu_active(cpu1)) during + * booting of that cpu. */ if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE) smp_call_function_single(freqs->cpu, twd_update_frequency, - NULL, 1); + NULL, cpu_active(freqs->cpu)); return NOTIFY_OK; } diff --git a/trunk/arch/arm/mach-at91/at91rm9200_devices.c b/trunk/arch/arm/mach-at91/at91rm9200_devices.c index 05774e5b1cba..99ce5c955e39 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200_devices.c +++ b/trunk/arch/arm/mach-at91/at91rm9200_devices.c @@ -1173,6 +1173,7 @@ void __init at91_add_device_serial(void) printk(KERN_INFO "AT91: No default serial console defined.\n"); } #else +void __init __deprecated at91_init_serial(struct at91_uart_config *config) {} void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {} void __init at91_set_serial_console(unsigned portnr) {} void __init at91_add_device_serial(void) {} diff --git a/trunk/arch/arm/mach-at91/at91rm9200_time.c b/trunk/arch/arm/mach-at91/at91rm9200_time.c index 104ca40d8d18..dd7f782b0b91 100644 --- a/trunk/arch/arm/mach-at91/at91rm9200_time.c +++ b/trunk/arch/arm/mach-at91/at91rm9200_time.c @@ -23,7 +23,6 @@ #include #include #include -#include #include @@ -177,7 +176,6 @@ static struct clock_event_device clkevt = { }; void __iomem *at91_st_base; -EXPORT_SYMBOL_GPL(at91_st_base); void __init at91rm9200_ioremap_st(u32 addr) { diff --git a/trunk/arch/arm/mach-at91/board-rm9200ek.c b/trunk/arch/arm/mach-at91/board-rm9200ek.c index b2e4fe21f346..11cbaa8946fe 100644 --- a/trunk/arch/arm/mach-at91/board-rm9200ek.c +++ b/trunk/arch/arm/mach-at91/board-rm9200ek.c @@ -117,7 +117,7 @@ static struct i2c_board_info __initdata ek_i2c_devices[] = { }; #define EK_FLASH_BASE AT91_CHIPSELECT_0 -#define EK_FLASH_SIZE SZ_8M +#define EK_FLASH_SIZE SZ_2M static struct physmap_flash_data ek_flash_data = { .width = 2, diff --git a/trunk/arch/arm/mach-at91/board-sam9261ek.c b/trunk/arch/arm/mach-at91/board-sam9261ek.c index 065fed342424..c3f994462864 100644 --- a/trunk/arch/arm/mach-at91/board-sam9261ek.c +++ b/trunk/arch/arm/mach-at91/board-sam9261ek.c @@ -85,6 +85,8 @@ static struct resource dm9000_resource[] = { .flags = IORESOURCE_MEM }, [2] = { + .start = AT91_PIN_PC11, + .end = AT91_PIN_PC11, .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE, } @@ -128,8 +130,6 @@ static struct sam9_smc_config __initdata dm9000_smc_config = { static void __init ek_add_device_dm9000(void) { - struct resource *r = &dm9000_resource[2]; - /* Configure chip-select 2 (DM9000) */ sam9_smc_configure(0, 2, &dm9000_smc_config); @@ -139,7 +139,6 @@ static void __init ek_add_device_dm9000(void) /* Configure Interrupt pin as input, no pull-up */ at91_set_gpio_input(AT91_PIN_PC11, 0); - r->start = r->end = gpio_to_irq(AT91_PIN_PC11); platform_device_register(&dm9000_device); } #else diff --git a/trunk/arch/arm/mach-at91/clock.c b/trunk/arch/arm/mach-at91/clock.c index 6b692824c988..a0f4d7424cdc 100644 --- a/trunk/arch/arm/mach-at91/clock.c +++ b/trunk/arch/arm/mach-at91/clock.c @@ -35,7 +35,6 @@ #include "generic.h" void __iomem *at91_pmc_base; -EXPORT_SYMBOL_GPL(at91_pmc_base); /* * There's a lot more which can be done with clocks, including cpufreq diff --git a/trunk/arch/arm/mach-at91/include/mach/at91_pmc.h b/trunk/arch/arm/mach-at91/include/mach/at91_pmc.h index ea2c57a86ca6..36604782a78f 100644 --- a/trunk/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/trunk/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -25,7 +25,7 @@ extern void __iomem *at91_pmc_base; #define at91_pmc_write(field, value) \ __raw_writel(value, at91_pmc_base + field) #else -.extern at91_pmc_base +.extern at91_aic_base #endif #define AT91_PMC_SCER 0x00 /* System Clock Enable Register */ diff --git a/trunk/arch/arm/mach-at91/setup.c b/trunk/arch/arm/mach-at91/setup.c index f44a2e7272e3..97cc04dc8073 100644 --- a/trunk/arch/arm/mach-at91/setup.c +++ b/trunk/arch/arm/mach-at91/setup.c @@ -54,7 +54,6 @@ void __init at91_init_interrupts(unsigned int *priority) } void __iomem *at91_ramc_base[2]; -EXPORT_SYMBOL_GPL(at91_ramc_base); void __init at91_ioremap_ramc(int id, u32 addr, u32 size) { @@ -293,7 +292,6 @@ void __init at91_ioremap_rstc(u32 base_addr) } void __iomem *at91_matrix_base; -EXPORT_SYMBOL_GPL(at91_matrix_base); void __init at91_ioremap_matrix(u32 base_addr) { diff --git a/trunk/arch/arm/mach-bcmring/core.c b/trunk/arch/arm/mach-bcmring/core.c index adbfb1994582..22e4e0a28ad1 100644 --- a/trunk/arch/arm/mach-bcmring/core.c +++ b/trunk/arch/arm/mach-bcmring/core.c @@ -52,8 +52,8 @@ #include #include -static AMBA_APB_DEVICE(uartA, "uartA", 0, MM_ADDR_IO_UARTA, {IRQ_UARTA}, NULL); -static AMBA_APB_DEVICE(uartB, "uartB", 0, MM_ADDR_IO_UARTB, {IRQ_UARTB}, NULL); +static AMBA_APB_DEVICE(uartA, "uarta", MM_ADDR_IO_UARTA, { IRQ_UARTA }, NULL); +static AMBA_APB_DEVICE(uartB, "uartb", MM_ADDR_IO_UARTB, { IRQ_UARTB }, NULL); static struct clk pll1_clk = { .name = "PLL1", diff --git a/trunk/arch/arm/mach-exynos/clock-exynos4.c b/trunk/arch/arm/mach-exynos/clock-exynos4.c index 6efd1e5919fd..df54c2a92225 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos4.c +++ b/trunk/arch/arm/mach-exynos/clock-exynos4.c @@ -497,25 +497,25 @@ static struct clk exynos4_init_clocks_off[] = { .ctrlbit = (1 << 3), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.0", + .devname = "s3c-sdhci.0", .parent = &exynos4_clk_aclk_133.clk, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit = (1 << 5), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.1", + .devname = "s3c-sdhci.1", .parent = &exynos4_clk_aclk_133.clk, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit = (1 << 6), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.2", + .devname = "s3c-sdhci.2", .parent = &exynos4_clk_aclk_133.clk, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit = (1 << 7), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.3", + .devname = "s3c-sdhci.3", .parent = &exynos4_clk_aclk_133.clk, .enable = exynos4_clk_ip_fsys_ctrl, .ctrlbit = (1 << 8), @@ -1202,7 +1202,7 @@ static struct clksrc_clk exynos4_clk_sclk_uart3 = { static struct clksrc_clk exynos4_clk_sclk_mmc0 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.0", + .devname = "s3c-sdhci.0", .parent = &exynos4_clk_dout_mmc0.clk, .enable = exynos4_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 0), @@ -1213,7 +1213,7 @@ static struct clksrc_clk exynos4_clk_sclk_mmc0 = { static struct clksrc_clk exynos4_clk_sclk_mmc1 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.1", + .devname = "s3c-sdhci.1", .parent = &exynos4_clk_dout_mmc1.clk, .enable = exynos4_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 4), @@ -1224,7 +1224,7 @@ static struct clksrc_clk exynos4_clk_sclk_mmc1 = { static struct clksrc_clk exynos4_clk_sclk_mmc2 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.2", + .devname = "s3c-sdhci.2", .parent = &exynos4_clk_dout_mmc2.clk, .enable = exynos4_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 8), @@ -1235,7 +1235,7 @@ static struct clksrc_clk exynos4_clk_sclk_mmc2 = { static struct clksrc_clk exynos4_clk_sclk_mmc3 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.3", + .devname = "s3c-sdhci.3", .parent = &exynos4_clk_dout_mmc3.clk, .enable = exynos4_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 12), @@ -1340,10 +1340,10 @@ static struct clk_lookup exynos4_clk_lookup[] = { CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos4_clk_sclk_uart1.clk), CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos4_clk_sclk_uart2.clk), CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos4_clk_sclk_uart3.clk), - CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk), - CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk), - CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk), - CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos4_clk_sclk_mmc0.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos4_clk_sclk_mmc1.clk), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos4_clk_sclk_mmc2.clk), + CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos4_clk_sclk_mmc3.clk), CLKDEV_INIT("exynos4-fb.0", "lcd", &exynos4_clk_fimd0), CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos4_clk_pdma0), CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos4_clk_pdma1), diff --git a/trunk/arch/arm/mach-exynos/clock-exynos5.c b/trunk/arch/arm/mach-exynos/clock-exynos5.c index 5cd7a8b8868c..d013982d0f8e 100644 --- a/trunk/arch/arm/mach-exynos/clock-exynos5.c +++ b/trunk/arch/arm/mach-exynos/clock-exynos5.c @@ -455,25 +455,25 @@ static struct clk exynos5_init_clocks_off[] = { .ctrlbit = (1 << 20), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.0", + .devname = "s3c-sdhci.0", .parent = &exynos5_clk_aclk_200.clk, .enable = exynos5_clk_ip_fsys_ctrl, .ctrlbit = (1 << 12), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.1", + .devname = "s3c-sdhci.1", .parent = &exynos5_clk_aclk_200.clk, .enable = exynos5_clk_ip_fsys_ctrl, .ctrlbit = (1 << 13), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.2", + .devname = "s3c-sdhci.2", .parent = &exynos5_clk_aclk_200.clk, .enable = exynos5_clk_ip_fsys_ctrl, .ctrlbit = (1 << 14), }, { .name = "hsmmc", - .devname = "exynos4-sdhci.3", + .devname = "s3c-sdhci.3", .parent = &exynos5_clk_aclk_200.clk, .enable = exynos5_clk_ip_fsys_ctrl, .ctrlbit = (1 << 15), @@ -813,7 +813,7 @@ static struct clksrc_clk exynos5_clk_sclk_uart3 = { static struct clksrc_clk exynos5_clk_sclk_mmc0 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.0", + .devname = "s3c-sdhci.0", .parent = &exynos5_clk_dout_mmc0.clk, .enable = exynos5_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 0), @@ -824,7 +824,7 @@ static struct clksrc_clk exynos5_clk_sclk_mmc0 = { static struct clksrc_clk exynos5_clk_sclk_mmc1 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.1", + .devname = "s3c-sdhci.1", .parent = &exynos5_clk_dout_mmc1.clk, .enable = exynos5_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 4), @@ -835,7 +835,7 @@ static struct clksrc_clk exynos5_clk_sclk_mmc1 = { static struct clksrc_clk exynos5_clk_sclk_mmc2 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.2", + .devname = "s3c-sdhci.2", .parent = &exynos5_clk_dout_mmc2.clk, .enable = exynos5_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 8), @@ -846,7 +846,7 @@ static struct clksrc_clk exynos5_clk_sclk_mmc2 = { static struct clksrc_clk exynos5_clk_sclk_mmc3 = { .clk = { .name = "sclk_mmc", - .devname = "exynos4-sdhci.3", + .devname = "s3c-sdhci.3", .parent = &exynos5_clk_dout_mmc3.clk, .enable = exynos5_clksrc_mask_fsys_ctrl, .ctrlbit = (1 << 12), @@ -990,10 +990,10 @@ static struct clk_lookup exynos5_clk_lookup[] = { CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos5_clk_sclk_uart1.clk), CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos5_clk_sclk_uart2.clk), CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos5_clk_sclk_uart3.clk), - CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk), - CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk), - CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk), - CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk), + CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk), + CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk), + CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk), + CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk), CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0), CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1), CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1), diff --git a/trunk/arch/arm/mach-exynos/common.c b/trunk/arch/arm/mach-exynos/common.c index 5ccd6e80a607..8614aab47cc0 100644 --- a/trunk/arch/arm/mach-exynos/common.c +++ b/trunk/arch/arm/mach-exynos/common.c @@ -326,11 +326,6 @@ static void __init exynos4_map_io(void) s3c_fimc_setname(2, "exynos4-fimc"); s3c_fimc_setname(3, "exynos4-fimc"); - s3c_sdhci_setname(0, "exynos4-sdhci"); - s3c_sdhci_setname(1, "exynos4-sdhci"); - s3c_sdhci_setname(2, "exynos4-sdhci"); - s3c_sdhci_setname(3, "exynos4-sdhci"); - /* The I2C bus controllers are directly compatible with s3c2440 */ s3c_i2c0_setname("s3c2440-i2c"); s3c_i2c1_setname("s3c2440-i2c"); @@ -349,11 +344,6 @@ static void __init exynos5_map_io(void) s3c_device_i2c0.resource[1].start = EXYNOS5_IRQ_IIC; s3c_device_i2c0.resource[1].end = EXYNOS5_IRQ_IIC; - s3c_sdhci_setname(0, "exynos4-sdhci"); - s3c_sdhci_setname(1, "exynos4-sdhci"); - s3c_sdhci_setname(2, "exynos4-sdhci"); - s3c_sdhci_setname(3, "exynos4-sdhci"); - /* The I2C bus controllers are directly compatible with s3c2440 */ s3c_i2c0_setname("s3c2440-i2c"); s3c_i2c1_setname("s3c2440-i2c"); @@ -547,9 +537,7 @@ void __init exynos5_init_irq(void) { int irq; -#ifdef CONFIG_OF - of_irq_init(exynos4_dt_irq_match); -#endif + gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); for (irq = 0; irq < EXYNOS5_MAX_COMBINER_NR; irq++) { combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), diff --git a/trunk/arch/arm/mach-exynos/dev-dwmci.c b/trunk/arch/arm/mach-exynos/dev-dwmci.c index 79035018fb74..b025db4bf602 100644 --- a/trunk/arch/arm/mach-exynos/dev-dwmci.c +++ b/trunk/arch/arm/mach-exynos/dev-dwmci.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -34,8 +33,16 @@ static int exynos4_dwmci_init(u32 slot_id, irq_handler_t handler, void *data) } static struct resource exynos4_dwmci_resource[] = { - [0] = DEFINE_RES_MEM(EXYNOS4_PA_DWMCI, SZ_4K), - [1] = DEFINE_RES_IRQ(EXYNOS4_IRQ_DWMCI), + [0] = { + .start = EXYNOS4_PA_DWMCI, + .end = EXYNOS4_PA_DWMCI + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_DWMCI, + .end = IRQ_DWMCI, + .flags = IORESOURCE_IRQ, + } }; static struct dw_mci_board exynos4_dwci_pdata = { diff --git a/trunk/arch/arm/mach-exynos/mach-nuri.c b/trunk/arch/arm/mach-exynos/mach-nuri.c index ed90aef404c3..b4f1f902ce6d 100644 --- a/trunk/arch/arm/mach-exynos/mach-nuri.c +++ b/trunk/arch/arm/mach-exynos/mach-nuri.c @@ -112,7 +112,6 @@ static struct s3c_sdhci_platdata nuri_hsmmc0_data __initdata = { .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | MMC_CAP_ERASE), - .host_caps2 = MMC_CAP2_BROKEN_VOLTAGE, .cd_type = S3C_SDHCI_CD_PERMANENT, .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, }; diff --git a/trunk/arch/arm/mach-exynos/mach-universal_c210.c b/trunk/arch/arm/mach-exynos/mach-universal_c210.c index cb2b027f09a6..7ebf79c2ab34 100644 --- a/trunk/arch/arm/mach-exynos/mach-universal_c210.c +++ b/trunk/arch/arm/mach-exynos/mach-universal_c210.c @@ -747,7 +747,6 @@ static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = { .max_width = 8, .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), - .host_caps2 = MMC_CAP2_BROKEN_VOLTAGE, .cd_type = S3C_SDHCI_CD_PERMANENT, .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, }; diff --git a/trunk/arch/arm/mach-imx/imx27-dt.c b/trunk/arch/arm/mach-imx/imx27-dt.c index ed38d03c61f2..861ceb8232d6 100644 --- a/trunk/arch/arm/mach-imx/imx27-dt.c +++ b/trunk/arch/arm/mach-imx/imx27-dt.c @@ -35,7 +35,7 @@ static const struct of_dev_auxdata imx27_auxdata_lookup[] __initconst = { static int __init imx27_avic_add_irq_domain(struct device_node *np, struct device_node *interrupt_parent) { - irq_domain_add_legacy(np, 64, 0, 0, &irq_domain_simple_ops, NULL); + irq_domain_add_simple(np, 0); return 0; } @@ -44,9 +44,7 @@ static int __init imx27_gpio_add_irq_domain(struct device_node *np, { static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS; - gpio_irq_base -= 32; - irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, - NULL); + irq_domain_add_simple(np, gpio_irq_base); return 0; } diff --git a/trunk/arch/arm/mach-imx/mm-imx5.c b/trunk/arch/arm/mach-imx/mm-imx5.c index e10f3914fcfe..05250aed61fb 100644 --- a/trunk/arch/arm/mach-imx/mm-imx5.c +++ b/trunk/arch/arm/mach-imx/mm-imx5.c @@ -35,7 +35,7 @@ static void imx5_idle(void) } clk_enable(gpc_dvfs_clk); mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF); - if (!tzic_enable_wake()) + if (tzic_enable_wake() != 0) cpu_do_idle(); clk_disable(gpc_dvfs_clk); } diff --git a/trunk/arch/arm/mach-msm/board-msm8x60.c b/trunk/arch/arm/mach-msm/board-msm8x60.c index fb3496a52ef4..962e71169750 100644 --- a/trunk/arch/arm/mach-msm/board-msm8x60.c +++ b/trunk/arch/arm/mach-msm/board-msm8x60.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -50,22 +49,10 @@ static void __init msm8x60_map_io(void) msm_map_msm8x60_io(); } -#ifdef CONFIG_OF -static struct of_device_id msm_dt_gic_match[] __initdata = { - { .compatible = "qcom,msm-8660-qgic", .data = gic_of_init }, - {} -}; -#endif - static void __init msm8x60_init_irq(void) { - if (!of_have_populated_dt()) - gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE, - (void *)MSM_QGIC_CPU_BASE); -#ifdef CONFIG_OF - else - of_irq_init(msm_dt_gic_match); -#endif + gic_init(0, GIC_PPI_START, MSM_QGIC_DIST_BASE, + (void *)MSM_QGIC_CPU_BASE); /* Edge trigger PPIs except AVS_SVICINT and AVS_SVICINTSWDONE */ writel(0xFFFFD7FF, MSM_QGIC_DIST_BASE + GIC_DIST_CONFIG + 4); @@ -86,8 +73,16 @@ static struct of_dev_auxdata msm_auxdata_lookup[] __initdata = { {} }; +static struct of_device_id msm_dt_gic_match[] __initdata = { + { .compatible = "qcom,msm-8660-qgic", }, + {} +}; + static void __init msm8x60_dt_init(void) { + irq_domain_generate_simple(msm_dt_gic_match, MSM8X60_QGIC_DIST_PHYS, + GIC_SPI_START); + if (of_machine_is_compatible("qcom,msm8660-surf")) { printk(KERN_INFO "Init surf UART registers\n"); msm8x60_init_uart12dm(); diff --git a/trunk/arch/arm/mach-omap1/mux.c b/trunk/arch/arm/mach-omap1/mux.c index e9cc52d4cb28..087dba0df47e 100644 --- a/trunk/arch/arm/mach-omap1/mux.c +++ b/trunk/arch/arm/mach-omap1/mux.c @@ -27,7 +27,6 @@ #include #include -#include #include diff --git a/trunk/arch/arm/mach-omap1/timer.c b/trunk/arch/arm/mach-omap1/timer.c index fb202af01d0d..6e90665a7c47 100644 --- a/trunk/arch/arm/mach-omap1/timer.c +++ b/trunk/arch/arm/mach-omap1/timer.c @@ -47,9 +47,9 @@ static int omap1_dm_timer_set_src(struct platform_device *pdev, int n = (pdev->id - 1) << 1; u32 l; - l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); + l = __raw_readl(MOD_CONF_CTRL_1) & ~(0x03 << n); l |= source << n; - omap_writel(l, MOD_CONF_CTRL_1); + __raw_writel(l, MOD_CONF_CTRL_1); return 0; } diff --git a/trunk/arch/arm/mach-omap2/board-4430sdp.c b/trunk/arch/arm/mach-omap2/board-4430sdp.c index 130ab00c09a2..a39fc4bbd2b8 100644 --- a/trunk/arch/arm/mach-omap2/board-4430sdp.c +++ b/trunk/arch/arm/mach-omap2/board-4430sdp.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -561,7 +560,7 @@ static struct regulator_init_data sdp4430_vusim = { }, }; -static struct twl6040_codec_data twl6040_codec = { +static struct twl4030_codec_data twl6040_codec = { /* single-step ramp for headset and handsfree */ .hs_left_step = 0x0f, .hs_right_step = 0x0f, @@ -569,7 +568,7 @@ static struct twl6040_codec_data twl6040_codec = { .hf_right_step = 0x1d, }; -static struct twl6040_vibra_data twl6040_vibra = { +static struct twl4030_vibra_data twl6040_vibra = { .vibldrv_res = 8, .vibrdrv_res = 3, .viblmotor_res = 10, @@ -578,14 +577,16 @@ static struct twl6040_vibra_data twl6040_vibra = { .vddvibr_uV = 0, /* fixed volt supply - VBAT */ }; -static struct twl6040_platform_data twl6040_data = { +static struct twl4030_audio_data twl6040_audio = { .codec = &twl6040_codec, .vibra = &twl6040_vibra, .audpwron_gpio = 127, + .naudint_irq = OMAP44XX_IRQ_SYS_2N, .irq_base = TWL6040_CODEC_IRQ_BASE, }; static struct twl4030_platform_data sdp4430_twldata = { + .audio = &twl6040_audio, /* Regulators */ .vusim = &sdp4430_vusim, .vaux1 = &sdp4430_vaux1, @@ -616,8 +617,7 @@ static int __init omap4_i2c_init(void) TWL_COMMON_REGULATOR_VCXIO | TWL_COMMON_REGULATOR_VUSB | TWL_COMMON_REGULATOR_CLK32KG); - omap4_pmic_init("twl6030", &sdp4430_twldata, - &twl6040_data, OMAP44XX_IRQ_SYS_2N); + omap4_pmic_init("twl6030", &sdp4430_twldata); omap_register_i2c_bus(2, 400, NULL, 0); omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo, ARRAY_SIZE(sdp4430_i2c_3_boardinfo)); diff --git a/trunk/arch/arm/mach-omap2/board-generic.c b/trunk/arch/arm/mach-omap2/board-generic.c index 098d183a0086..74e1687b5170 100644 --- a/trunk/arch/arm/mach-omap2/board-generic.c +++ b/trunk/arch/arm/mach-omap2/board-generic.c @@ -137,7 +137,7 @@ static struct twl4030_platform_data sdp4430_twldata = { static void __init omap4_i2c_init(void) { - omap4_pmic_init("twl6030", &sdp4430_twldata, NULL, 0); + omap4_pmic_init("twl6030", &sdp4430_twldata); } static void __init omap4_init(void) diff --git a/trunk/arch/arm/mach-omap2/board-omap4panda.c b/trunk/arch/arm/mach-omap2/board-omap4panda.c index 1b782ba53433..d8c0e89f0126 100644 --- a/trunk/arch/arm/mach-omap2/board-omap4panda.c +++ b/trunk/arch/arm/mach-omap2/board-omap4panda.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -285,7 +284,7 @@ static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers) return 0; } -static struct twl6040_codec_data twl6040_codec = { +static struct twl4030_codec_data twl6040_codec = { /* single-step ramp for headset and handsfree */ .hs_left_step = 0x0f, .hs_right_step = 0x0f, @@ -293,14 +292,17 @@ static struct twl6040_codec_data twl6040_codec = { .hf_right_step = 0x1d, }; -static struct twl6040_platform_data twl6040_data = { +static struct twl4030_audio_data twl6040_audio = { .codec = &twl6040_codec, .audpwron_gpio = 127, + .naudint_irq = OMAP44XX_IRQ_SYS_2N, .irq_base = TWL6040_CODEC_IRQ_BASE, }; /* Panda board uses the common PMIC configuration */ -static struct twl4030_platform_data omap4_panda_twldata; +static struct twl4030_platform_data omap4_panda_twldata = { + .audio = &twl6040_audio, +}; /* * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM @@ -324,8 +326,7 @@ static int __init omap4_panda_i2c_init(void) TWL_COMMON_REGULATOR_VCXIO | TWL_COMMON_REGULATOR_VUSB | TWL_COMMON_REGULATOR_CLK32KG); - omap4_pmic_init("twl6030", &omap4_panda_twldata, - &twl6040_data, OMAP44XX_IRQ_SYS_2N); + omap4_pmic_init("twl6030", &omap4_panda_twldata); omap_register_i2c_bus(2, 400, NULL, 0); /* * Bus 3 is attached to the DVI port where devices like the pico DLP diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod.c b/trunk/arch/arm/mach-omap2/omap_hwmod.c index 7144ae651d3d..2c27fdb61e66 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod.c @@ -1422,9 +1422,6 @@ static int _ocp_softreset(struct omap_hwmod *oh) goto dis_opt_clks; _write_sysconfig(v, oh); - if (oh->class->sysc->srst_udelay) - udelay(oh->class->sysc->srst_udelay); - if (oh->class->sysc->sysc_flags & SYSS_HAS_RESET_STATUS) omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs) @@ -1906,20 +1903,10 @@ void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs) */ int omap_hwmod_softreset(struct omap_hwmod *oh) { - u32 v; - int ret; - - if (!oh || !(oh->_sysc_cache)) + if (!oh) return -EINVAL; - v = oh->_sysc_cache; - ret = _set_softreset(oh, &v); - if (ret) - goto error; - _write_sysconfig(v, oh); - -error: - return ret; + return _ocp_softreset(oh); } /** diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c index a6bde34e443a..a5409ce3f323 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -1000,6 +1000,7 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = { .flags = OMAP_FIREWALL_L4, } }, + .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, }; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 04a3885f4475..c4f56cb60d7d 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -1049,6 +1049,7 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = { .slave = &omap2430_dss_venc_hwmod, .clk = "dss_ick", .addr = omap2_dss_venc_addrs, + .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, }; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index db86ce90c69f..34b9766d1d23 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1676,6 +1676,7 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = { .flags = OMAP_FIREWALL_L4, } }, + .flags = OCPIF_SWSUP_IDLE, .user = OCP_USER_MPU | OCP_USER_SDMA, }; diff --git a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 6abc75753e42..cc9bd106a854 100644 --- a/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/trunk/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2594,15 +2594,6 @@ static struct omap_hwmod omap44xx_ipu_hwmod = { static struct omap_hwmod_class_sysconfig omap44xx_iss_sysc = { .rev_offs = 0x0000, .sysc_offs = 0x0010, - /* - * ISS needs 100 OCP clk cycles delay after a softreset before - * accessing sysconfig again. - * The lowest frequency at the moment for L3 bus is 100 MHz, so - * 1usec delay is needed. Add an x2 margin to be safe (2 usecs). - * - * TODO: Indicate errata when available. - */ - .srst_udelay = 2, .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | diff --git a/trunk/arch/arm/mach-omap2/serial.c b/trunk/arch/arm/mach-omap2/serial.c index 9fc2f44188cb..0cdd359a128e 100644 --- a/trunk/arch/arm/mach-omap2/serial.c +++ b/trunk/arch/arm/mach-omap2/serial.c @@ -108,14 +108,8 @@ static void omap_uart_set_noidle(struct platform_device *pdev) static void omap_uart_set_smartidle(struct platform_device *pdev) { struct omap_device *od = to_omap_device(pdev); - u8 idlemode; - if (od->hwmods[0]->class->sysc->idlemodes & SIDLE_SMART_WKUP) - idlemode = HWMOD_IDLEMODE_SMART_WKUP; - else - idlemode = HWMOD_IDLEMODE_SMART; - - omap_hwmod_set_slave_idlemode(od->hwmods[0], idlemode); + omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART); } #else @@ -126,8 +120,124 @@ static void omap_uart_set_smartidle(struct platform_device *pdev) {} #endif /* CONFIG_PM */ #ifdef CONFIG_OMAP_MUX +static struct omap_device_pad default_uart1_pads[] __initdata = { + { + .name = "uart1_cts.uart1_cts", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "uart1_rts.uart1_rts", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart1_tx.uart1_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart1_rx.uart1_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad default_uart2_pads[] __initdata = { + { + .name = "uart2_cts.uart2_cts", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "uart2_rts.uart2_rts", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart2_tx.uart2_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart2_rx.uart2_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad default_uart3_pads[] __initdata = { + { + .name = "uart3_cts_rctx.uart3_cts_rctx", + .enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0, + }, + { + .name = "uart3_rts_sd.uart3_rts_sd", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart3_tx_irtx.uart3_tx_irtx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart3_rx_irrx.uart3_rx_irrx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + }, +}; + +static struct omap_device_pad default_omap36xx_uart4_pads[] __initdata = { + { + .name = "gpmc_wait2.uart4_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "gpmc_wait3.uart4_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE2, + .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE2, + }, +}; + +static struct omap_device_pad default_omap4_uart4_pads[] __initdata = { + { + .name = "uart4_tx.uart4_tx", + .enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0, + }, + { + .name = "uart4_rx.uart4_rx", + .flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP, + .enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + .idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0, + }, +}; + static void omap_serial_fill_default_pads(struct omap_board_data *bdata) { + switch (bdata->id) { + case 0: + bdata->pads = default_uart1_pads; + bdata->pads_cnt = ARRAY_SIZE(default_uart1_pads); + break; + case 1: + bdata->pads = default_uart2_pads; + bdata->pads_cnt = ARRAY_SIZE(default_uart2_pads); + break; + case 2: + bdata->pads = default_uart3_pads; + bdata->pads_cnt = ARRAY_SIZE(default_uart3_pads); + break; + case 3: + if (cpu_is_omap44xx()) { + bdata->pads = default_omap4_uart4_pads; + bdata->pads_cnt = + ARRAY_SIZE(default_omap4_uart4_pads); + } else if (cpu_is_omap3630()) { + bdata->pads = default_omap36xx_uart4_pads; + bdata->pads_cnt = + ARRAY_SIZE(default_omap36xx_uart4_pads); + } + break; + default: + break; + } } #else static void omap_serial_fill_default_pads(struct omap_board_data *bdata) {} diff --git a/trunk/arch/arm/mach-omap2/twl-common.c b/trunk/arch/arm/mach-omap2/twl-common.c index 7a7b89304c48..4b57757bf9d1 100644 --- a/trunk/arch/arm/mach-omap2/twl-common.c +++ b/trunk/arch/arm/mach-omap2/twl-common.c @@ -37,16 +37,6 @@ static struct i2c_board_info __initdata pmic_i2c_board_info = { .flags = I2C_CLIENT_WAKE, }; -static struct i2c_board_info __initdata omap4_i2c1_board_info[] = { - { - .addr = 0x48, - .flags = I2C_CLIENT_WAKE, - }, - { - I2C_BOARD_INFO("twl6040", 0x4b), - }, -}; - void __init omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq, struct twl4030_platform_data *pmic_data) @@ -59,31 +49,14 @@ void __init omap_pmic_init(int bus, u32 clkrate, omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1); } -void __init omap4_pmic_init(const char *pmic_type, - struct twl4030_platform_data *pmic_data, - struct twl6040_platform_data *twl6040_data, int twl6040_irq) -{ - /* PMIC part*/ - strncpy(omap4_i2c1_board_info[0].type, pmic_type, - sizeof(omap4_i2c1_board_info[0].type)); - omap4_i2c1_board_info[0].irq = OMAP44XX_IRQ_SYS_1N; - omap4_i2c1_board_info[0].platform_data = pmic_data; - - /* TWL6040 audio IC part */ - omap4_i2c1_board_info[1].irq = twl6040_irq; - omap4_i2c1_board_info[1].platform_data = twl6040_data; - - omap_register_i2c_bus(1, 400, omap4_i2c1_board_info, 2); - -} - void __init omap_pmic_late_init(void) { /* Init the OMAP TWL parameters (if PMIC has been registerd) */ - if (pmic_i2c_board_info.irq) - omap3_twl_init(); - if (omap4_i2c1_board_info[0].irq) - omap4_twl_init(); + if (!pmic_i2c_board_info.irq) + return; + + omap3_twl_init(); + omap4_twl_init(); } #if defined(CONFIG_ARCH_OMAP3) diff --git a/trunk/arch/arm/mach-omap2/twl-common.h b/trunk/arch/arm/mach-omap2/twl-common.h index 09627483a57f..275dde8cb27a 100644 --- a/trunk/arch/arm/mach-omap2/twl-common.h +++ b/trunk/arch/arm/mach-omap2/twl-common.h @@ -29,7 +29,6 @@ struct twl4030_platform_data; -struct twl6040_platform_data; void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq, struct twl4030_platform_data *pmic_data); @@ -47,9 +46,12 @@ static inline void omap3_pmic_init(const char *pmic_type, omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data); } -void omap4_pmic_init(const char *pmic_type, - struct twl4030_platform_data *pmic_data, - struct twl6040_platform_data *audio_data, int twl6040_irq); +static inline void omap4_pmic_init(const char *pmic_type, + struct twl4030_platform_data *pmic_data) +{ + /* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */ + omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data); +} void omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, u32 pdata_flags, u32 regulators_flags); diff --git a/trunk/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h b/trunk/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h index cbf51ae81855..c54cef25895c 100644 --- a/trunk/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h +++ b/trunk/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h @@ -17,7 +17,6 @@ * * bit 23 - Input/Output (PXA2xx specific) * bit 24 - Wakeup Enable(PXA2xx specific) - * bit 25 - Keep Output (PXA2xx specific) */ #define MFP_DIR_IN (0x0 << 23) @@ -26,12 +25,6 @@ #define MFP_DIR(x) (((x) >> 23) & 0x1) #define MFP_LPM_CAN_WAKEUP (0x1 << 24) - -/* - * MFP_LPM_KEEP_OUTPUT must be specified for pins that need to - * retain their last output level (low or high). - * Note: MFP_LPM_KEEP_OUTPUT has no effect on pins configured for input. - */ #define MFP_LPM_KEEP_OUTPUT (0x1 << 25) #define WAKEUP_ON_EDGE_RISE (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE) diff --git a/trunk/arch/arm/mach-pxa/mfp-pxa2xx.c b/trunk/arch/arm/mach-pxa/mfp-pxa2xx.c index ef0426a159d4..b0a842887780 100644 --- a/trunk/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/trunk/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -33,8 +33,6 @@ #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) #define GPLR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5)) #define GPDR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x0c) -#define GPSR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x18) -#define GPCR(x) __REG2(0x40E00000, BANK_OFF((x) >> 5) + 0x24) #define PWER_WE35 (1 << 24) @@ -350,7 +348,6 @@ static inline void pxa27x_mfp_init(void) {} #ifdef CONFIG_PM static unsigned long saved_gafr[2][4]; static unsigned long saved_gpdr[4]; -static unsigned long saved_gplr[4]; static unsigned long saved_pgsr[4]; static int pxa2xx_mfp_suspend(void) @@ -369,26 +366,14 @@ static int pxa2xx_mfp_suspend(void) } for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { + saved_gafr[0][i] = GAFR_L(i); saved_gafr[1][i] = GAFR_U(i); saved_gpdr[i] = GPDR(i * 32); - saved_gplr[i] = GPLR(i * 32); saved_pgsr[i] = PGSR(i); - GPSR(i * 32) = PGSR(i); - GPCR(i * 32) = ~PGSR(i); - } - - /* set GPDR bits taking into account MFP_LPM_KEEP_OUTPUT */ - for (i = 0; i < pxa_last_gpio; i++) { - if ((gpdr_lpm[gpio_to_bank(i)] & GPIO_bit(i)) || - ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) && - (saved_gpdr[gpio_to_bank(i)] & GPIO_bit(i)))) - GPDR(i) |= GPIO_bit(i); - else - GPDR(i) &= ~GPIO_bit(i); + GPDR(i * 32) = gpdr_lpm[i]; } - return 0; } @@ -399,8 +384,6 @@ static void pxa2xx_mfp_resume(void) for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) { GAFR_L(i) = saved_gafr[0][i]; GAFR_U(i) = saved_gafr[1][i]; - GPSR(i * 32) = saved_gplr[i]; - GPCR(i * 32) = ~saved_gplr[i]; GPDR(i * 32) = saved_gpdr[i]; PGSR(i) = saved_pgsr[i]; } diff --git a/trunk/arch/arm/mach-pxa/pxa27x.c b/trunk/arch/arm/mach-pxa/pxa27x.c index 4726c246dcdc..6bce78edce7a 100644 --- a/trunk/arch/arm/mach-pxa/pxa27x.c +++ b/trunk/arch/arm/mach-pxa/pxa27x.c @@ -421,11 +421,8 @@ void __init pxa27x_set_i2c_power_info(struct i2c_pxa_platform_data *info) pxa_register_device(&pxa27x_device_i2c_power, info); } -static struct pxa_gpio_platform_data pxa27x_gpio_info __initdata = { - .gpio_set_wake = gpio_set_wake, -}; - static struct platform_device *devices[] __initdata = { + &pxa_device_gpio, &pxa27x_device_udc, &pxa_device_pmu, &pxa_device_i2s, @@ -461,7 +458,6 @@ static int __init pxa27x_init(void) register_syscore_ops(&pxa2xx_mfp_syscore_ops); register_syscore_ops(&pxa2xx_clock_syscore_ops); - pxa_register_device(&pxa_device_gpio, &pxa27x_gpio_info); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/trunk/arch/arm/mach-s3c24xx/Kconfig b/trunk/arch/arm/mach-s3c24xx/Kconfig index b34287ab5afd..0f3a327ebcaa 100644 --- a/trunk/arch/arm/mach-s3c24xx/Kconfig +++ b/trunk/arch/arm/mach-s3c24xx/Kconfig @@ -111,6 +111,10 @@ config S3C24XX_SETUP_TS help Compile in platform device definition for Samsung TouchScreen. +# cpu-specific sections + +if CPU_S3C2410 + config S3C2410_DMA bool depends on S3C24XX_DMA && (CPU_S3C2410 || CPU_S3C2442) @@ -123,10 +127,6 @@ config S3C2410_PM help Power Management code common to S3C2410 and better -# cpu-specific sections - -if CPU_S3C2410 - config S3C24XX_SIMTEC_NOR bool help diff --git a/trunk/arch/arm/mach-s5pv210/mach-goni.c b/trunk/arch/arm/mach-s5pv210/mach-goni.c index 32395664e879..a8933de3d627 100644 --- a/trunk/arch/arm/mach-s5pv210/mach-goni.c +++ b/trunk/arch/arm/mach-s5pv210/mach-goni.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include @@ -766,7 +765,6 @@ static void __init goni_pmic_init(void) /* MoviNAND */ static struct s3c_sdhci_platdata goni_hsmmc0_data __initdata = { .max_width = 4, - .host_caps2 = MMC_CAP2_BROKEN_VOLTAGE, .cd_type = S3C_SDHCI_CD_PERMANENT, }; diff --git a/trunk/arch/arm/mach-sa1100/generic.c b/trunk/arch/arm/mach-sa1100/generic.c index 16be4c56abe3..7c524b4e415d 100644 --- a/trunk/arch/arm/mach-sa1100/generic.c +++ b/trunk/arch/arm/mach-sa1100/generic.c @@ -306,7 +306,7 @@ void sa11x0_register_irda(struct irda_platform_data *irda) } static struct resource sa1100_rtc_resources[] = { - DEFINE_RES_MEM(0x90010000, 0x40), + DEFINE_RES_MEM(0x90010000, 0x9001003f), DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"), DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"), }; diff --git a/trunk/arch/arm/mach-u300/core.c b/trunk/arch/arm/mach-u300/core.c index 33339745d432..1621ad07d284 100644 --- a/trunk/arch/arm/mach-u300/core.c +++ b/trunk/arch/arm/mach-u300/core.c @@ -1667,10 +1667,8 @@ void __init u300_init_irq(void) for (i = 0; i < U300_VIC_IRQS_END; i++) set_bit(i, (unsigned long *) &mask[0]); - vic_init((void __iomem *) U300_INTCON0_VBASE, IRQ_U300_INTCON0_START, - mask[0], mask[0]); - vic_init((void __iomem *) U300_INTCON1_VBASE, IRQ_U300_INTCON1_START, - mask[1], mask[1]); + vic_init((void __iomem *) U300_INTCON0_VBASE, 0, mask[0], mask[0]); + vic_init((void __iomem *) U300_INTCON1_VBASE, 32, mask[1], mask[1]); } diff --git a/trunk/arch/arm/mach-u300/i2c.c b/trunk/arch/arm/mach-u300/i2c.c index cb04bd6ab3e7..a38f80238ea9 100644 --- a/trunk/arch/arm/mach-u300/i2c.c +++ b/trunk/arch/arm/mach-u300/i2c.c @@ -146,6 +146,9 @@ static struct ab3100_platform_data ab3100_plf_data = { .min_uV = 1800000, .max_uV = 1800000, .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, .always_on = 1, .boot_on = 1, }, @@ -157,6 +160,9 @@ static struct ab3100_platform_data ab3100_plf_data = { .min_uV = 2500000, .max_uV = 2500000, .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, .always_on = 1, .boot_on = 1, }, @@ -224,7 +230,8 @@ static struct ab3100_platform_data ab3100_plf_data = { .max_uV = 1800000, .valid_modes_mask = REGULATOR_MODE_NORMAL, .valid_ops_mask = - REGULATOR_CHANGE_VOLTAGE, + REGULATOR_CHANGE_VOLTAGE | + REGULATOR_CHANGE_STATUS, .always_on = 1, .boot_on = 1, }, diff --git a/trunk/arch/arm/mach-u300/include/mach/irqs.h b/trunk/arch/arm/mach-u300/include/mach/irqs.h index ec09c1e07b1a..ee78a26707eb 100644 --- a/trunk/arch/arm/mach-u300/include/mach/irqs.h +++ b/trunk/arch/arm/mach-u300/include/mach/irqs.h @@ -12,101 +12,101 @@ #ifndef __MACH_IRQS_H #define __MACH_IRQS_H -#define IRQ_U300_INTCON0_START 1 -#define IRQ_U300_INTCON1_START 33 +#define IRQ_U300_INTCON0_START 0 +#define IRQ_U300_INTCON1_START 32 /* These are on INTCON0 - 30 lines */ -#define IRQ_U300_IRQ0_EXT 1 -#define IRQ_U300_IRQ1_EXT 2 -#define IRQ_U300_DMA 3 -#define IRQ_U300_VIDEO_ENC_0 4 -#define IRQ_U300_VIDEO_ENC_1 5 -#define IRQ_U300_AAIF_RX 6 -#define IRQ_U300_AAIF_TX 7 -#define IRQ_U300_AAIF_VGPIO 8 -#define IRQ_U300_AAIF_WAKEUP 9 -#define IRQ_U300_PCM_I2S0_FRAME 10 -#define IRQ_U300_PCM_I2S0_FIFO 11 -#define IRQ_U300_PCM_I2S1_FRAME 12 -#define IRQ_U300_PCM_I2S1_FIFO 13 -#define IRQ_U300_XGAM_GAMCON 14 -#define IRQ_U300_XGAM_CDI 15 -#define IRQ_U300_XGAM_CDICON 16 +#define IRQ_U300_IRQ0_EXT 0 +#define IRQ_U300_IRQ1_EXT 1 +#define IRQ_U300_DMA 2 +#define IRQ_U300_VIDEO_ENC_0 3 +#define IRQ_U300_VIDEO_ENC_1 4 +#define IRQ_U300_AAIF_RX 5 +#define IRQ_U300_AAIF_TX 6 +#define IRQ_U300_AAIF_VGPIO 7 +#define IRQ_U300_AAIF_WAKEUP 8 +#define IRQ_U300_PCM_I2S0_FRAME 9 +#define IRQ_U300_PCM_I2S0_FIFO 10 +#define IRQ_U300_PCM_I2S1_FRAME 11 +#define IRQ_U300_PCM_I2S1_FIFO 12 +#define IRQ_U300_XGAM_GAMCON 13 +#define IRQ_U300_XGAM_CDI 14 +#define IRQ_U300_XGAM_CDICON 15 #if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) /* MMIACC not used on the DB3210 or DB3350 chips */ -#define IRQ_U300_XGAM_MMIACC 17 +#define IRQ_U300_XGAM_MMIACC 16 #endif -#define IRQ_U300_XGAM_PDI 18 -#define IRQ_U300_XGAM_PDICON 19 -#define IRQ_U300_XGAM_GAMEACC 20 -#define IRQ_U300_XGAM_MCIDCT 21 -#define IRQ_U300_APEX 22 -#define IRQ_U300_UART0 23 -#define IRQ_U300_SPI 24 -#define IRQ_U300_TIMER_APP_OS 25 -#define IRQ_U300_TIMER_APP_DD 26 -#define IRQ_U300_TIMER_APP_GP1 27 -#define IRQ_U300_TIMER_APP_GP2 28 -#define IRQ_U300_TIMER_OS 29 -#define IRQ_U300_TIMER_MS 30 -#define IRQ_U300_KEYPAD_KEYBF 31 -#define IRQ_U300_KEYPAD_KEYBR 32 +#define IRQ_U300_XGAM_PDI 17 +#define IRQ_U300_XGAM_PDICON 18 +#define IRQ_U300_XGAM_GAMEACC 19 +#define IRQ_U300_XGAM_MCIDCT 20 +#define IRQ_U300_APEX 21 +#define IRQ_U300_UART0 22 +#define IRQ_U300_SPI 23 +#define IRQ_U300_TIMER_APP_OS 24 +#define IRQ_U300_TIMER_APP_DD 25 +#define IRQ_U300_TIMER_APP_GP1 26 +#define IRQ_U300_TIMER_APP_GP2 27 +#define IRQ_U300_TIMER_OS 28 +#define IRQ_U300_TIMER_MS 29 +#define IRQ_U300_KEYPAD_KEYBF 30 +#define IRQ_U300_KEYPAD_KEYBR 31 /* These are on INTCON1 - 32 lines */ -#define IRQ_U300_GPIO_PORT0 33 -#define IRQ_U300_GPIO_PORT1 34 -#define IRQ_U300_GPIO_PORT2 35 +#define IRQ_U300_GPIO_PORT0 32 +#define IRQ_U300_GPIO_PORT1 33 +#define IRQ_U300_GPIO_PORT2 34 #if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) || \ defined(CONFIG_MACH_U300_BS335) /* These are for DB3150, DB3200 and DB3350 */ -#define IRQ_U300_WDOG 36 -#define IRQ_U300_EVHIST 37 -#define IRQ_U300_MSPRO 38 -#define IRQ_U300_MMCSD_MCIINTR0 39 -#define IRQ_U300_MMCSD_MCIINTR1 40 -#define IRQ_U300_I2C0 41 -#define IRQ_U300_I2C1 42 -#define IRQ_U300_RTC 43 -#define IRQ_U300_NFIF 44 -#define IRQ_U300_NFIF2 45 +#define IRQ_U300_WDOG 35 +#define IRQ_U300_EVHIST 36 +#define IRQ_U300_MSPRO 37 +#define IRQ_U300_MMCSD_MCIINTR0 38 +#define IRQ_U300_MMCSD_MCIINTR1 39 +#define IRQ_U300_I2C0 40 +#define IRQ_U300_I2C1 41 +#define IRQ_U300_RTC 42 +#define IRQ_U300_NFIF 43 +#define IRQ_U300_NFIF2 44 #endif /* DB3150 and DB3200 have only 45 IRQs */ #if defined(CONFIG_MACH_U300_BS2X) || defined(CONFIG_MACH_U300_BS330) -#define U300_VIC_IRQS_END 46 +#define U300_VIC_IRQS_END 45 #endif /* The DB3350-specific interrupt lines */ #ifdef CONFIG_MACH_U300_BS335 -#define IRQ_U300_ISP_F0 46 -#define IRQ_U300_ISP_F1 47 -#define IRQ_U300_ISP_F2 48 -#define IRQ_U300_ISP_F3 49 -#define IRQ_U300_ISP_F4 50 -#define IRQ_U300_GPIO_PORT3 51 -#define IRQ_U300_SYSCON_PLL_LOCK 52 -#define IRQ_U300_UART1 53 -#define IRQ_U300_GPIO_PORT4 54 -#define IRQ_U300_GPIO_PORT5 55 -#define IRQ_U300_GPIO_PORT6 56 -#define U300_VIC_IRQS_END 57 +#define IRQ_U300_ISP_F0 45 +#define IRQ_U300_ISP_F1 46 +#define IRQ_U300_ISP_F2 47 +#define IRQ_U300_ISP_F3 48 +#define IRQ_U300_ISP_F4 49 +#define IRQ_U300_GPIO_PORT3 50 +#define IRQ_U300_SYSCON_PLL_LOCK 51 +#define IRQ_U300_UART1 52 +#define IRQ_U300_GPIO_PORT4 53 +#define IRQ_U300_GPIO_PORT5 54 +#define IRQ_U300_GPIO_PORT6 55 +#define U300_VIC_IRQS_END 56 #endif /* The DB3210-specific interrupt lines */ #ifdef CONFIG_MACH_U300_BS365 -#define IRQ_U300_GPIO_PORT3 36 -#define IRQ_U300_GPIO_PORT4 37 -#define IRQ_U300_WDOG 38 -#define IRQ_U300_EVHIST 39 -#define IRQ_U300_MSPRO 40 -#define IRQ_U300_MMCSD_MCIINTR0 41 -#define IRQ_U300_MMCSD_MCIINTR1 42 -#define IRQ_U300_I2C0 43 -#define IRQ_U300_I2C1 44 -#define IRQ_U300_RTC 45 -#define IRQ_U300_NFIF 46 -#define IRQ_U300_NFIF2 47 -#define IRQ_U300_SYSCON_PLL_LOCK 48 -#define U300_VIC_IRQS_END 49 +#define IRQ_U300_GPIO_PORT3 35 +#define IRQ_U300_GPIO_PORT4 36 +#define IRQ_U300_WDOG 37 +#define IRQ_U300_EVHIST 38 +#define IRQ_U300_MSPRO 39 +#define IRQ_U300_MMCSD_MCIINTR0 40 +#define IRQ_U300_MMCSD_MCIINTR1 41 +#define IRQ_U300_I2C0 42 +#define IRQ_U300_I2C1 43 +#define IRQ_U300_RTC 44 +#define IRQ_U300_NFIF 45 +#define IRQ_U300_NFIF2 46 +#define IRQ_U300_SYSCON_PLL_LOCK 47 +#define U300_VIC_IRQS_END 48 #endif /* Maximum 8*7 GPIO lines */ @@ -117,6 +117,6 @@ #define IRQ_U300_GPIO_END (U300_VIC_IRQS_END) #endif -#define NR_IRQS (IRQ_U300_GPIO_END - IRQ_U300_INTCON0_START) +#define NR_IRQS (IRQ_U300_GPIO_END) #endif diff --git a/trunk/arch/arm/mach-ux500/Kconfig b/trunk/arch/arm/mach-ux500/Kconfig index ef7099eea0f2..880d02ec89d4 100644 --- a/trunk/arch/arm/mach-ux500/Kconfig +++ b/trunk/arch/arm/mach-ux500/Kconfig @@ -17,7 +17,6 @@ config UX500_SOC_DB5500 config UX500_SOC_DB8500 bool select MFD_DB8500_PRCMU - select REGULATOR select REGULATOR_DB8500_PRCMU select CPU_FREQ_TABLE if CPU_FREQ diff --git a/trunk/arch/arm/mach-ux500/mbox-db5500.c b/trunk/arch/arm/mach-ux500/mbox-db5500.c index 0127490218cd..2b2d51caf9d8 100644 --- a/trunk/arch/arm/mach-ux500/mbox-db5500.c +++ b/trunk/arch/arm/mach-ux500/mbox-db5500.c @@ -168,7 +168,7 @@ static ssize_t mbox_read_fifo(struct device *dev, return sprintf(buf, "0x%X\n", mbox_value); } -static DEVICE_ATTR(fifo, S_IWUSR | S_IRUGO, mbox_read_fifo, mbox_write_fifo); +static DEVICE_ATTR(fifo, S_IWUGO | S_IRUGO, mbox_read_fifo, mbox_write_fifo); static int mbox_show(struct seq_file *s, void *data) { diff --git a/trunk/arch/arm/mach-ux500/platsmp.c b/trunk/arch/arm/mach-ux500/platsmp.c index eff5842f6232..d2058ef8345f 100644 --- a/trunk/arch/arm/mach-ux500/platsmp.c +++ b/trunk/arch/arm/mach-ux500/platsmp.c @@ -99,7 +99,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) */ write_pen_release(cpu_logical_map(cpu)); - smp_send_reschedule(cpu); + gic_raise_softirq(cpumask_of(cpu), 1); timeout = jiffies + (1 * HZ); while (time_before(jiffies, timeout)) { diff --git a/trunk/arch/arm/mm/abort-ev6.S b/trunk/arch/arm/mm/abort-ev6.S index 80741992a9fc..ff1f7cc11f87 100644 --- a/trunk/arch/arm/mm/abort-ev6.S +++ b/trunk/arch/arm/mm/abort-ev6.S @@ -26,23 +26,18 @@ ENTRY(v6_early_abort) mrc p15, 0, r1, c5, c0, 0 @ get FSR mrc p15, 0, r0, c6, c0, 0 @ get FAR /* - * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR. + * Faulty SWP instruction on 1136 doesn't set bit 11 in DFSR (erratum 326103). + * The test below covers all the write situations, including Java bytecodes */ -#ifdef CONFIG_ARM_ERRATA_326103 - ldr ip, =0x4107b36 - mrc p15, 0, r3, c0, c0, 0 @ get processor id - teq ip, r3, lsr #4 @ r0 ARM1136? - bne do_DataAbort + bic r1, r1, #1 << 11 @ clear bit 11 of FSR tst r5, #PSR_J_BIT @ Java? - tsteq r5, #PSR_T_BIT @ Thumb? bne do_DataAbort - bic r1, r1, #1 << 11 @ clear bit 11 of FSR - ldr r3, [r4] @ read aborted ARM instruction + do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 + ldreq r3, [r4] @ read aborted ARM instruction #ifdef CONFIG_CPU_ENDIAN_BE8 - rev r3, r3 + reveq r3, r3 #endif do_ldrd_abort tmp=ip, insn=r3 tst r3, #1 << 20 @ L = 0 -> write orreq r1, r1, #1 << 11 @ yes. -#endif b do_DataAbort diff --git a/trunk/arch/arm/mm/cache-l2x0.c b/trunk/arch/arm/mm/cache-l2x0.c index 2a8e380501e8..a53fd2aaa2f4 100644 --- a/trunk/arch/arm/mm/cache-l2x0.c +++ b/trunk/arch/arm/mm/cache-l2x0.c @@ -32,7 +32,6 @@ static void __iomem *l2x0_base; static DEFINE_RAW_SPINLOCK(l2x0_lock); static u32 l2x0_way_mask; /* Bitmask of active ways */ static u32 l2x0_size; -static unsigned long sync_reg_offset = L2X0_CACHE_SYNC; struct l2x0_regs l2x0_saved_regs; @@ -62,7 +61,12 @@ static inline void cache_sync(void) { void __iomem *base = l2x0_base; - writel_relaxed(0, base + sync_reg_offset); +#ifdef CONFIG_PL310_ERRATA_753970 + /* write to an unmmapped register */ + writel_relaxed(0, base + L2X0_DUMMY_REG); +#else + writel_relaxed(0, base + L2X0_CACHE_SYNC); +#endif cache_wait(base + L2X0_CACHE_SYNC, 1); } @@ -81,13 +85,10 @@ static inline void l2x0_inv_line(unsigned long addr) } #if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915) -static inline void debug_writel(unsigned long val) -{ - if (outer_cache.set_debug) - outer_cache.set_debug(val); -} -static void pl310_set_debug(unsigned long val) +#define debug_writel(val) outer_cache.set_debug(val) + +static void l2x0_set_debug(unsigned long val) { writel_relaxed(val, l2x0_base + L2X0_DEBUG_CTRL); } @@ -97,7 +98,7 @@ static inline void debug_writel(unsigned long val) { } -#define pl310_set_debug NULL +#define l2x0_set_debug NULL #endif #ifdef CONFIG_PL310_ERRATA_588369 @@ -330,11 +331,6 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) else ways = 8; type = "L310"; -#ifdef CONFIG_PL310_ERRATA_753970 - /* Unmapped register. */ - sync_reg_offset = L2X0_DUMMY_REG; -#endif - outer_cache.set_debug = pl310_set_debug; break; case L2X0_CACHE_ID_PART_L210: ways = (aux >> 13) & 0xf; @@ -383,6 +379,7 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) outer_cache.flush_all = l2x0_flush_all; outer_cache.inv_all = l2x0_inv_all; outer_cache.disable = l2x0_disable; + outer_cache.set_debug = l2x0_set_debug; printk(KERN_INFO "%s cache controller enabled\n", type); printk(KERN_INFO "l2x0: %d ways, CACHE_ID 0x%08x, AUX_CTRL 0x%08x, Cache size: %d B\n", diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index 8f5813bbffb5..595079fa9d1d 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -293,11 +293,11 @@ EXPORT_SYMBOL(pfn_valid); #endif #ifndef CONFIG_SPARSEMEM -static void __init arm_memory_present(void) +static void arm_memory_present(void) { } #else -static void __init arm_memory_present(void) +static void arm_memory_present(void) { struct memblock_region *reg; diff --git a/trunk/arch/arm/mm/mmu.c b/trunk/arch/arm/mm/mmu.c index 2c7cf2f9c837..b86f8933ff91 100644 --- a/trunk/arch/arm/mm/mmu.c +++ b/trunk/arch/arm/mm/mmu.c @@ -618,8 +618,8 @@ static void __init alloc_init_section(pud_t *pud, unsigned long addr, } } -static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, - unsigned long end, unsigned long phys, const struct mem_type *type) +static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end, + unsigned long phys, const struct mem_type *type) { pud_t *pud = pud_offset(pgd, addr); unsigned long next; diff --git a/trunk/arch/arm/plat-omap/dma.c b/trunk/arch/arm/plat-omap/dma.c index c58d896cd5c3..ecdb3da0dea9 100644 --- a/trunk/arch/arm/plat-omap/dma.c +++ b/trunk/arch/arm/plat-omap/dma.c @@ -916,13 +916,6 @@ void omap_start_dma(int lch) l |= OMAP_DMA_CCR_BUFFERING_DISABLE; l |= OMAP_DMA_CCR_EN; - /* - * As dma_write() uses IO accessors which are weakly ordered, there - * is no guarantee that data in coherent DMA memory will be visible - * to the DMA device. Add a memory barrier here to ensure that any - * such data is visible prior to enabling DMA. - */ - mb(); p->dma_write(l, CCR, lch); dma_chan[lch].flags |= OMAP_DMA_ACTIVE; @@ -972,13 +965,6 @@ void omap_stop_dma(int lch) p->dma_write(l, CCR, lch); } - /* - * Ensure that data transferred by DMA is visible to any access - * after DMA has been disabled. This is important for coherent - * DMA regions. - */ - mb(); - if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) { int next_lch, cur_lch = lch; char dma_chan_link_map[dma_lch_count]; diff --git a/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h b/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h index 3f26db4ee8e6..8070145ccb98 100644 --- a/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/trunk/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -305,7 +305,6 @@ struct omap_hwmod_sysc_fields { * @rev_offs: IP block revision register offset (from module base addr) * @sysc_offs: OCP_SYSCONFIG register offset (from module base addr) * @syss_offs: OCP_SYSSTATUS register offset (from module base addr) - * @srst_udelay: Delay needed after doing a softreset in usecs * @idlemodes: One or more of {SIDLE,MSTANDBY}_{OFF,FORCE,SMART} * @sysc_flags: SYS{C,S}_HAS* flags indicating SYSCONFIG bits supported * @clockact: the default value of the module CLOCKACTIVITY bits @@ -331,10 +330,9 @@ struct omap_hwmod_class_sysconfig { u16 sysc_offs; u16 syss_offs; u16 sysc_flags; - struct omap_hwmod_sysc_fields *sysc_fields; - u8 srst_udelay; u8 idlemodes; u8 clockact; + struct omap_hwmod_sysc_fields *sysc_fields; }; /** diff --git a/trunk/arch/arm/plat-omap/sram.c b/trunk/arch/arm/plat-omap/sram.c index f9a8c5341ee9..eec98afa0f83 100644 --- a/trunk/arch/arm/plat-omap/sram.c +++ b/trunk/arch/arm/plat-omap/sram.c @@ -348,6 +348,7 @@ u32 omap3_configure_core_dpll(u32 m2, u32 unlock_dll, u32 f, u32 inc, sdrc_actim_ctrl_b_1, sdrc_mr_1); } +#ifdef CONFIG_PM void omap3_sram_restore_context(void) { omap_sram_ceil = omap_sram_base + omap_sram_size; @@ -357,18 +358,17 @@ void omap3_sram_restore_context(void) omap3_sram_configure_core_dpll_sz); omap_push_sram_idle(); } +#endif /* CONFIG_PM */ + +#endif /* CONFIG_ARCH_OMAP3 */ static inline int omap34xx_sram_init(void) { +#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) omap3_sram_restore_context(); +#endif return 0; } -#else -static inline int omap34xx_sram_init(void) -{ - return 0; -} -#endif /* CONFIG_ARCH_OMAP3 */ static inline int am33xx_sram_init(void) { diff --git a/trunk/arch/arm/plat-samsung/include/plat/sdhci.h b/trunk/arch/arm/plat-samsung/include/plat/sdhci.h index e834c5ef437c..317e246ffc56 100644 --- a/trunk/arch/arm/plat-samsung/include/plat/sdhci.h +++ b/trunk/arch/arm/plat-samsung/include/plat/sdhci.h @@ -18,8 +18,6 @@ #ifndef __PLAT_S3C_SDHCI_H #define __PLAT_S3C_SDHCI_H __FILE__ -#include - struct platform_device; struct mmc_host; struct mmc_card; @@ -358,30 +356,4 @@ static inline void exynos4_default_sdhci3(void) { } #endif /* CONFIG_EXYNOS4_SETUP_SDHCI */ -static inline void s3c_sdhci_setname(int id, char *name) -{ - switch (id) { -#ifdef CONFIG_S3C_DEV_HSMMC - case 0: - s3c_device_hsmmc0.name = name; - break; -#endif -#ifdef CONFIG_S3C_DEV_HSMMC1 - case 1: - s3c_device_hsmmc1.name = name; - break; -#endif -#ifdef CONFIG_S3C_DEV_HSMMC2 - case 2: - s3c_device_hsmmc2.name = name; - break; -#endif -#ifdef CONFIG_S3C_DEV_HSMMC3 - case 3: - s3c_device_hsmmc3.name = name; - break; -#endif - } -} - #endif /* __PLAT_S3C_SDHCI_H */ diff --git a/trunk/arch/arm/vfp/vfpmodule.c b/trunk/arch/arm/vfp/vfpmodule.c index bc683b8219b5..858748eaa144 100644 --- a/trunk/arch/arm/vfp/vfpmodule.c +++ b/trunk/arch/arm/vfp/vfpmodule.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include @@ -530,103 +528,6 @@ void vfp_flush_hwstate(struct thread_info *thread) put_cpu(); } -/* - * Save the current VFP state into the provided structures and prepare - * for entry into a new function (signal handler). - */ -int vfp_preserve_user_clear_hwstate(struct user_vfp __user *ufp, - struct user_vfp_exc __user *ufp_exc) -{ - struct thread_info *thread = current_thread_info(); - struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; - int err = 0; - - /* Ensure that the saved hwstate is up-to-date. */ - vfp_sync_hwstate(thread); - - /* - * Copy the floating point registers. There can be unused - * registers see asm/hwcap.h for details. - */ - err |= __copy_to_user(&ufp->fpregs, &hwstate->fpregs, - sizeof(hwstate->fpregs)); - /* - * Copy the status and control register. - */ - __put_user_error(hwstate->fpscr, &ufp->fpscr, err); - - /* - * Copy the exception registers. - */ - __put_user_error(hwstate->fpexc, &ufp_exc->fpexc, err); - __put_user_error(hwstate->fpinst, &ufp_exc->fpinst, err); - __put_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err); - - if (err) - return -EFAULT; - - /* Ensure that VFP is disabled. */ - vfp_flush_hwstate(thread); - - /* - * As per the PCS, clear the length and stride bits for function - * entry. - */ - hwstate->fpscr &= ~(FPSCR_LENGTH_MASK | FPSCR_STRIDE_MASK); - - /* - * Disable VFP in the hwstate so that we can detect if it gets - * used. - */ - hwstate->fpexc &= ~FPEXC_EN; - return 0; -} - -/* Sanitise and restore the current VFP state from the provided structures. */ -int vfp_restore_user_hwstate(struct user_vfp __user *ufp, - struct user_vfp_exc __user *ufp_exc) -{ - struct thread_info *thread = current_thread_info(); - struct vfp_hard_struct *hwstate = &thread->vfpstate.hard; - unsigned long fpexc; - int err = 0; - - /* - * If VFP has been used, then disable it to avoid corrupting - * the new thread state. - */ - if (hwstate->fpexc & FPEXC_EN) - vfp_flush_hwstate(thread); - - /* - * Copy the floating point registers. There can be unused - * registers see asm/hwcap.h for details. - */ - err |= __copy_from_user(&hwstate->fpregs, &ufp->fpregs, - sizeof(hwstate->fpregs)); - /* - * Copy the status and control register. - */ - __get_user_error(hwstate->fpscr, &ufp->fpscr, err); - - /* - * Sanitise and restore the exception registers. - */ - __get_user_error(fpexc, &ufp_exc->fpexc, err); - - /* Ensure the VFP is enabled. */ - fpexc |= FPEXC_EN; - - /* Ensure FPINST2 is invalid and the exception flag is cleared. */ - fpexc &= ~(FPEXC_EX | FPEXC_FP2V); - hwstate->fpexc = fpexc; - - __get_user_error(hwstate->fpinst, &ufp_exc->fpinst, err); - __get_user_error(hwstate->fpinst2, &ufp_exc->fpinst2, err); - - return err ? -EFAULT : 0; -} - /* * VFP hardware can lose all context when a CPU goes offline. * As we will be running in SMP mode with CPU hotplug, we will save the diff --git a/trunk/arch/blackfin/mach-bf538/boards/ezkit.c b/trunk/arch/blackfin/mach-bf538/boards/ezkit.c index 85038f54354d..1633a6f306c0 100644 --- a/trunk/arch/blackfin/mach-bf538/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf538/boards/ezkit.c @@ -38,7 +38,7 @@ static struct platform_device rtc_device = { .name = "rtc-bfin", .id = -1, }; -#endif /* CONFIG_RTC_DRV_BFIN */ +#endif #if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) #ifdef CONFIG_SERIAL_BFIN_UART0 @@ -100,7 +100,7 @@ static struct platform_device bfin_uart0_device = { .platform_data = &bfin_uart0_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_UART0 */ +#endif #ifdef CONFIG_SERIAL_BFIN_UART1 static struct resource bfin_uart1_resources[] = { { @@ -148,7 +148,7 @@ static struct platform_device bfin_uart1_device = { .platform_data = &bfin_uart1_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_UART1 */ +#endif #ifdef CONFIG_SERIAL_BFIN_UART2 static struct resource bfin_uart2_resources[] = { { @@ -196,8 +196,8 @@ static struct platform_device bfin_uart2_device = { .platform_data = &bfin_uart2_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_UART2 */ -#endif /* CONFIG_SERIAL_BFIN */ +#endif +#endif #if defined(CONFIG_BFIN_SIR) || defined(CONFIG_BFIN_SIR_MODULE) #ifdef CONFIG_BFIN_SIR0 @@ -224,7 +224,7 @@ static struct platform_device bfin_sir0_device = { .num_resources = ARRAY_SIZE(bfin_sir0_resources), .resource = bfin_sir0_resources, }; -#endif /* CONFIG_BFIN_SIR0 */ +#endif #ifdef CONFIG_BFIN_SIR1 static struct resource bfin_sir1_resources[] = { { @@ -249,7 +249,7 @@ static struct platform_device bfin_sir1_device = { .num_resources = ARRAY_SIZE(bfin_sir1_resources), .resource = bfin_sir1_resources, }; -#endif /* CONFIG_BFIN_SIR1 */ +#endif #ifdef CONFIG_BFIN_SIR2 static struct resource bfin_sir2_resources[] = { { @@ -274,8 +274,8 @@ static struct platform_device bfin_sir2_device = { .num_resources = ARRAY_SIZE(bfin_sir2_resources), .resource = bfin_sir2_resources, }; -#endif /* CONFIG_BFIN_SIR2 */ -#endif /* CONFIG_BFIN_SIR */ +#endif +#endif #if defined(CONFIG_SERIAL_BFIN_SPORT) || defined(CONFIG_SERIAL_BFIN_SPORT_MODULE) #ifdef CONFIG_SERIAL_BFIN_SPORT0_UART @@ -311,7 +311,7 @@ static struct platform_device bfin_sport0_uart_device = { .platform_data = &bfin_sport0_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_SPORT0_UART */ +#endif #ifdef CONFIG_SERIAL_BFIN_SPORT1_UART static struct resource bfin_sport1_uart_resources[] = { { @@ -345,7 +345,7 @@ static struct platform_device bfin_sport1_uart_device = { .platform_data = &bfin_sport1_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_SPORT1_UART */ +#endif #ifdef CONFIG_SERIAL_BFIN_SPORT2_UART static struct resource bfin_sport2_uart_resources[] = { { @@ -379,7 +379,7 @@ static struct platform_device bfin_sport2_uart_device = { .platform_data = &bfin_sport2_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_SPORT2_UART */ +#endif #ifdef CONFIG_SERIAL_BFIN_SPORT3_UART static struct resource bfin_sport3_uart_resources[] = { { @@ -413,8 +413,8 @@ static struct platform_device bfin_sport3_uart_device = { .platform_data = &bfin_sport3_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_SERIAL_BFIN_SPORT3_UART */ -#endif /* CONFIG_SERIAL_BFIN_SPORT */ +#endif +#endif #if defined(CONFIG_CAN_BFIN) || defined(CONFIG_CAN_BFIN_MODULE) static unsigned short bfin_can_peripherals[] = { @@ -452,7 +452,7 @@ static struct platform_device bfin_can_device = { .platform_data = &bfin_can_peripherals, /* Passed to driver */ }, }; -#endif /* CONFIG_CAN_BFIN */ +#endif /* * USB-LAN EzExtender board @@ -488,7 +488,7 @@ static struct platform_device smc91x_device = { .platform_data = &smc91x_info, }, }; -#endif /* CONFIG_SMC91X */ +#endif #if defined(CONFIG_SPI_BFIN5XX) || defined(CONFIG_SPI_BFIN5XX_MODULE) /* all SPI peripherals info goes here */ @@ -518,8 +518,7 @@ static struct flash_platform_data bfin_spi_flash_data = { static struct bfin5xx_spi_chip spi_flash_chip_info = { .enable_dma = 0, /* use dma transfer with this chip*/ }; -#endif /* CONFIG_MTD_M25P80 */ -#endif /* CONFIG_SPI_BFIN5XX */ +#endif #if defined(CONFIG_TOUCHSCREEN_AD7879) || defined(CONFIG_TOUCHSCREEN_AD7879_MODULE) #include @@ -536,7 +535,7 @@ static const struct ad7879_platform_data bfin_ad7879_ts_info = { .gpio_export = 1, /* Export GPIO to gpiolib */ .gpio_base = -1, /* Dynamic allocation */ }; -#endif /* CONFIG_TOUCHSCREEN_AD7879 */ +#endif #if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) #include @@ -565,7 +564,7 @@ static struct platform_device bfin_lq035q1_device = { .platform_data = &bfin_lq035q1_data, }, }; -#endif /* CONFIG_FB_BFIN_LQ035Q1 */ +#endif static struct spi_board_info bf538_spi_board_info[] __initdata = { #if defined(CONFIG_MTD_M25P80) \ @@ -580,7 +579,7 @@ static struct spi_board_info bf538_spi_board_info[] __initdata = { .controller_data = &spi_flash_chip_info, .mode = SPI_MODE_3, }, -#endif /* CONFIG_MTD_M25P80 */ +#endif #if defined(CONFIG_TOUCHSCREEN_AD7879_SPI) || defined(CONFIG_TOUCHSCREEN_AD7879_SPI_MODULE) { .modalias = "ad7879", @@ -591,7 +590,7 @@ static struct spi_board_info bf538_spi_board_info[] __initdata = { .chip_select = 1, .mode = SPI_CPHA | SPI_CPOL, }, -#endif /* CONFIG_TOUCHSCREEN_AD7879_SPI */ +#endif #if defined(CONFIG_FB_BFIN_LQ035Q1) || defined(CONFIG_FB_BFIN_LQ035Q1_MODULE) { .modalias = "bfin-lq035q1-spi", @@ -600,7 +599,7 @@ static struct spi_board_info bf538_spi_board_info[] __initdata = { .chip_select = 2, .mode = SPI_CPHA | SPI_CPOL, }, -#endif /* CONFIG_FB_BFIN_LQ035Q1 */ +#endif #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) { .modalias = "spidev", @@ -608,7 +607,7 @@ static struct spi_board_info bf538_spi_board_info[] __initdata = { .bus_num = 0, .chip_select = 1, }, -#endif /* CONFIG_SPI_SPIDEV */ +#endif }; /* SPI (0) */ @@ -717,6 +716,8 @@ static struct platform_device bf538_spi_master2 = { }, }; +#endif /* spi master and devices */ + #if defined(CONFIG_I2C_BLACKFIN_TWI) || defined(CONFIG_I2C_BLACKFIN_TWI_MODULE) static struct resource bfin_twi0_resource[] = { [0] = { @@ -758,8 +759,8 @@ static struct platform_device i2c_bfin_twi1_device = { .num_resources = ARRAY_SIZE(bfin_twi1_resource), .resource = bfin_twi1_resource, }; -#endif /* CONFIG_BF542 */ -#endif /* CONFIG_I2C_BLACKFIN_TWI */ +#endif +#endif #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE) #include diff --git a/trunk/arch/hexagon/kernel/dma.c b/trunk/arch/hexagon/kernel/dma.c index 0f2367cc5493..37302218ca4a 100644 --- a/trunk/arch/hexagon/kernel/dma.c +++ b/trunk/arch/hexagon/kernel/dma.c @@ -22,7 +22,6 @@ #include #include #include -#include struct dma_map_ops *dma_ops; EXPORT_SYMBOL(dma_ops); diff --git a/trunk/arch/hexagon/kernel/process.c b/trunk/arch/hexagon/kernel/process.c index ff02821bfb7e..18c4f0b0f4ba 100644 --- a/trunk/arch/hexagon/kernel/process.c +++ b/trunk/arch/hexagon/kernel/process.c @@ -1,7 +1,7 @@ /* * Process creation support for Hexagon * - * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved. + * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -88,7 +88,7 @@ void (*idle_sleep)(void) = default_idle; void cpu_idle(void) { while (1) { - tick_nohz_idle_enter(); + tick_nohz_stop_sched_tick(1); local_irq_disable(); while (!need_resched()) { idle_sleep(); @@ -97,7 +97,7 @@ void cpu_idle(void) local_irq_disable(); } local_irq_enable(); - tick_nohz_idle_exit(); + tick_nohz_restart_sched_tick(); schedule(); } } diff --git a/trunk/arch/hexagon/kernel/ptrace.c b/trunk/arch/hexagon/kernel/ptrace.c index 96c3b2c4dbad..32342de1a79c 100644 --- a/trunk/arch/hexagon/kernel/ptrace.c +++ b/trunk/arch/hexagon/kernel/ptrace.c @@ -28,7 +28,6 @@ #include #include #include -#include #include diff --git a/trunk/arch/hexagon/kernel/smp.c b/trunk/arch/hexagon/kernel/smp.c index 1298141874a3..9b44a9e2d05a 100644 --- a/trunk/arch/hexagon/kernel/smp.c +++ b/trunk/arch/hexagon/kernel/smp.c @@ -1,7 +1,7 @@ /* * SMP support for Hexagon * - * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved. + * Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -28,7 +28,6 @@ #include #include #include -#include #include /* timer_interrupt */ #include @@ -178,12 +177,7 @@ void __cpuinit start_secondary(void) printk(KERN_INFO "%s cpu %d\n", __func__, current_thread_info()->cpu); - notify_cpu_starting(cpu); - - ipi_call_lock(); set_cpu_online(cpu, true); - ipi_call_unlock(); - local_irq_enable(); cpu_idle(); diff --git a/trunk/arch/hexagon/kernel/time.c b/trunk/arch/hexagon/kernel/time.c index 5d9b33b67935..6bee15c9c113 100644 --- a/trunk/arch/hexagon/kernel/time.c +++ b/trunk/arch/hexagon/kernel/time.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/hexagon/kernel/vdso.c b/trunk/arch/hexagon/kernel/vdso.c index 5d39f42f7085..f212a453b527 100644 --- a/trunk/arch/hexagon/kernel/vdso.c +++ b/trunk/arch/hexagon/kernel/vdso.c @@ -21,7 +21,6 @@ #include #include #include -#include #include diff --git a/trunk/arch/ia64/include/asm/futex.h b/trunk/arch/ia64/include/asm/futex.h index d2bf1fd5e44f..0ab82cc2dc8f 100644 --- a/trunk/arch/ia64/include/asm/futex.h +++ b/trunk/arch/ia64/include/asm/futex.h @@ -106,16 +106,15 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, return -EFAULT; { - register unsigned long r8 __asm ("r8"); + register unsigned long r8 __asm ("r8") = 0; unsigned long prev; __asm__ __volatile__( " mf;; \n" - " mov %0=r0 \n" - " mov ar.ccv=%4;; \n" - "[1:] cmpxchg4.acq %1=[%2],%3,ar.ccv \n" + " mov ar.ccv=%3;; \n" + "[1:] cmpxchg4.acq %0=[%1],%2,ar.ccv \n" " .xdata4 \"__ex_table\", 1b-., 2f-. \n" "[2:]" - : "=r" (r8), "=r" (prev) + : "=r" (prev) : "r" (uaddr), "r" (newval), "rO" ((long) (unsigned) oldval) : "memory"); diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index f00ba025375d..9d0fd7d5bb82 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -604,6 +604,12 @@ pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f) spin_unlock(&(x)->ctx_lock); } +static inline unsigned int +pfm_do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct) +{ + return do_munmap(mm, addr, len); +} + static inline unsigned long pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec) { @@ -1452,9 +1458,8 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu) * a PROTECT_CTX() section. */ static int -pfm_remove_smpl_mapping(void *vaddr, unsigned long size) +pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long size) { - struct task_struct *task = current; int r; /* sanity checks */ @@ -1468,8 +1473,13 @@ pfm_remove_smpl_mapping(void *vaddr, unsigned long size) /* * does the actual unmapping */ - r = vm_munmap((unsigned long)vaddr, size); + down_write(&task->mm->mmap_sem); + DPRINT(("down_write done smpl_vaddr=%p size=%lu\n", vaddr, size)); + + r = pfm_do_munmap(task->mm, (unsigned long)vaddr, size, 0); + + up_write(&task->mm->mmap_sem); if (r !=0) { printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size); } @@ -1935,7 +1945,7 @@ pfm_flush(struct file *filp, fl_owner_t id) * because some VM function reenables interrupts. * */ - if (smpl_buf_vaddr) pfm_remove_smpl_mapping(smpl_buf_vaddr, smpl_buf_size); + if (smpl_buf_vaddr) pfm_remove_smpl_mapping(current, smpl_buf_vaddr, smpl_buf_size); return 0; } diff --git a/trunk/arch/m68k/configs/m5275evb_defconfig b/trunk/arch/m68k/configs/m5275evb_defconfig index a1230e82bb1e..33c32aeca12b 100644 --- a/trunk/arch/m68k/configs/m5275evb_defconfig +++ b/trunk/arch/m68k/configs/m5275evb_defconfig @@ -49,6 +49,7 @@ CONFIG_BLK_DEV_RAM=y CONFIG_NETDEVICES=y CONFIG_NET_ETHERNET=y CONFIG_FEC=y +CONFIG_FEC2=y # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set CONFIG_PPP=y diff --git a/trunk/arch/m68k/platform/527x/config.c b/trunk/arch/m68k/platform/527x/config.c index f91a53294c35..7ed848c3b848 100644 --- a/trunk/arch/m68k/platform/527x/config.c +++ b/trunk/arch/m68k/platform/527x/config.c @@ -74,7 +74,9 @@ static void __init m527x_fec_init(void) writew(par | 0xf00, MCF_IPSBAR + 0x100082); v = readb(MCF_IPSBAR + 0x100078); writeb(v | 0xc0, MCF_IPSBAR + 0x100078); +#endif +#ifdef CONFIG_FEC2 /* Set multi-function pins to ethernet mode for fec1 */ par = readw(MCF_IPSBAR + 0x100082); writew(par | 0xa0, MCF_IPSBAR + 0x100082); diff --git a/trunk/arch/m68k/platform/68EZ328/Makefile b/trunk/arch/m68k/platform/68EZ328/Makefile index b44d799b1115..ee97735a242c 100644 --- a/trunk/arch/m68k/platform/68EZ328/Makefile +++ b/trunk/arch/m68k/platform/68EZ328/Makefile @@ -3,3 +3,9 @@ # obj-y := config.o + +extra-y := bootlogo.rh + +$(obj)/bootlogo.rh: $(src)/bootlogo.h + perl $(src)/../68328/bootlogo.pl < $(src)/bootlogo.h \ + > $(obj)/bootlogo.rh diff --git a/trunk/arch/m68k/platform/68VZ328/bootlogo.h b/trunk/arch/m68k/platform/68EZ328/bootlogo.h similarity index 99% rename from trunk/arch/m68k/platform/68VZ328/bootlogo.h rename to trunk/arch/m68k/platform/68EZ328/bootlogo.h index b38e2b255142..e842bdae5839 100644 --- a/trunk/arch/m68k/platform/68VZ328/bootlogo.h +++ b/trunk/arch/m68k/platform/68EZ328/bootlogo.h @@ -1,6 +1,6 @@ #define splash_width 640 #define splash_height 480 -unsigned char __attribute__ ((aligned(16))) bootlogo_bits[] = { +static unsigned char splash_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/trunk/arch/m68k/platform/68VZ328/Makefile b/trunk/arch/m68k/platform/68VZ328/Makefile index a49d75e65489..447ffa0fd7c7 100644 --- a/trunk/arch/m68k/platform/68VZ328/Makefile +++ b/trunk/arch/m68k/platform/68VZ328/Makefile @@ -3,9 +3,14 @@ # obj-y := config.o -extra-$(DRAGEN2):= screen.h +logo-$(UCDIMM) := bootlogo.rh +logo-$(DRAGEN2) := screen.h +extra-y := $(logo-y) + +$(obj)/bootlogo.rh: $(src)/../68EZ328/bootlogo.h + perl $(src)/bootlogo.pl < $(src)/../68328/bootlogo.h > $(obj)/bootlogo.rh $(obj)/screen.h: $(src)/screen.xbm $(src)/xbm2lcd.pl perl $(src)/xbm2lcd.pl < $(src)/screen.xbm > $(obj)/screen.h -clean-files := $(obj)/screen.h +clean-files := $(obj)/screen.h $(obj)/bootlogo.rh diff --git a/trunk/arch/m68k/platform/coldfire/device.c b/trunk/arch/m68k/platform/coldfire/device.c index 7af97362b95c..fa50c48292ff 100644 --- a/trunk/arch/m68k/platform/coldfire/device.c +++ b/trunk/arch/m68k/platform/coldfire/device.c @@ -114,7 +114,7 @@ static struct resource mcf_fec1_resources[] = { static struct platform_device mcf_fec1 = { .name = "fec", - .id = 1, + .id = 0, .num_resources = ARRAY_SIZE(mcf_fec1_resources), .resource = mcf_fec1_resources, }; diff --git a/trunk/arch/mips/ath79/dev-wmac.c b/trunk/arch/mips/ath79/dev-wmac.c index 9c717bf98ffe..e21507052066 100644 --- a/trunk/arch/mips/ath79/dev-wmac.c +++ b/trunk/arch/mips/ath79/dev-wmac.c @@ -58,8 +58,8 @@ static void __init ar913x_wmac_setup(void) static int ar933x_wmac_reset(void) { - ath79_device_reset_set(AR933X_RESET_WMAC); ath79_device_reset_clear(AR933X_RESET_WMAC); + ath79_device_reset_set(AR933X_RESET_WMAC); return 0; } diff --git a/trunk/arch/mips/include/asm/mach-jz4740/irq.h b/trunk/arch/mips/include/asm/mach-jz4740/irq.h index 5ad1a9c113c6..a865c983c70a 100644 --- a/trunk/arch/mips/include/asm/mach-jz4740/irq.h +++ b/trunk/arch/mips/include/asm/mach-jz4740/irq.h @@ -45,7 +45,7 @@ #define JZ4740_IRQ_LCD JZ4740_IRQ(30) /* 2nd-level interrupts */ -#define JZ4740_IRQ_DMA(x) (JZ4740_IRQ(32) + (x)) +#define JZ4740_IRQ_DMA(x) (JZ4740_IRQ(32) + (X)) #define JZ4740_IRQ_INTC_GPIO(x) (JZ4740_IRQ_GPIO0 - (x)) #define JZ4740_IRQ_GPIO(x) (JZ4740_IRQ(48) + (x)) diff --git a/trunk/arch/mips/include/asm/mmu_context.h b/trunk/arch/mips/include/asm/mmu_context.h index 9b02cfba7449..73c0d45798de 100644 --- a/trunk/arch/mips/include/asm/mmu_context.h +++ b/trunk/arch/mips/include/asm/mmu_context.h @@ -37,6 +37,12 @@ extern void tlbmiss_handler_setup_pgd(unsigned long pgd); write_c0_xcontext((unsigned long) smp_processor_id() << 51); \ } while (0) + +static inline unsigned long get_current_pgd(void) +{ + return PHYS_TO_XKSEG_CACHED((read_c0_context() >> 11) & ~0xfffUL); +} + #else /* CONFIG_MIPS_PGD_C0_CONTEXT: using pgd_current*/ /* diff --git a/trunk/arch/mips/kernel/signal.c b/trunk/arch/mips/kernel/signal.c index d5a338a1739c..185ca00c4c84 100644 --- a/trunk/arch/mips/kernel/signal.c +++ b/trunk/arch/mips/kernel/signal.c @@ -257,8 +257,11 @@ asmlinkage int sys_sigsuspend(nabi_no_regargs struct pt_regs regs) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); current->saved_sigmask = current->blocked; - set_current_blocked(&newset); + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -283,8 +286,11 @@ asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); current->saved_sigmask = current->blocked; - set_current_blocked(&newset); + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -356,7 +362,10 @@ asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs) goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); - set_current_blocked(&blocked); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = blocked; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); sig = restore_sigcontext(®s, &frame->sf_sc); if (sig < 0) @@ -392,7 +401,10 @@ asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); sig = restore_sigcontext(®s, &frame->rs_uc.uc_mcontext); if (sig < 0) @@ -568,7 +580,12 @@ static int handle_signal(unsigned long sig, siginfo_t *info, if (ret) return ret; - block_sigmask(ka, sig); + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked, sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); return ret; } diff --git a/trunk/arch/mips/kernel/signal32.c b/trunk/arch/mips/kernel/signal32.c index ac3b8d89aae5..06b5da392e24 100644 --- a/trunk/arch/mips/kernel/signal32.c +++ b/trunk/arch/mips/kernel/signal32.c @@ -290,8 +290,11 @@ asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); current->saved_sigmask = current->blocked; - set_current_blocked(&newset); + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -315,8 +318,11 @@ asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) return -EFAULT; sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); current->saved_sigmask = current->blocked; - set_current_blocked(&newset); + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -482,7 +488,10 @@ asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs) goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); - set_current_blocked(&blocked); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = blocked; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); sig = restore_sigcontext32(®s, &frame->sf_sc); if (sig < 0) @@ -520,7 +529,10 @@ asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); sig = restore_sigcontext32(®s, &frame->rs_uc.uc_mcontext); if (sig < 0) diff --git a/trunk/arch/mips/kernel/signal_n32.c b/trunk/arch/mips/kernel/signal_n32.c index 86eb4b04631c..ae29e894ab8d 100644 --- a/trunk/arch/mips/kernel/signal_n32.c +++ b/trunk/arch/mips/kernel/signal_n32.c @@ -93,8 +93,11 @@ asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) sigset_from_compat(&newset, &uset); sigdelsetmask(&newset, ~_BLOCKABLE); + spin_lock_irq(¤t->sighand->siglock); current->saved_sigmask = current->blocked; - set_current_blocked(&newset); + current->blocked = newset; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); current->state = TASK_INTERRUPTIBLE; schedule(); @@ -118,7 +121,10 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) goto badframe; sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); sig = restore_sigcontext(®s, &frame->rs_uc.uc_mcontext); if (sig < 0) diff --git a/trunk/arch/parisc/kernel/pdc_cons.c b/trunk/arch/parisc/kernel/pdc_cons.c index 0b3393381a81..4f004596a6e7 100644 --- a/trunk/arch/parisc/kernel/pdc_cons.c +++ b/trunk/arch/parisc/kernel/pdc_cons.c @@ -104,7 +104,7 @@ static int pdc_console_tty_open(struct tty_struct *tty, struct file *filp) static void pdc_console_tty_close(struct tty_struct *tty, struct file *filp) { - if (tty->count == 1) { + if (!tty->count) { del_timer_sync(&pdc_console_timer); tty_port_tty_set(&tty_port, NULL); } diff --git a/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi b/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi deleted file mode 100644 index 1cf0b77b1efe..000000000000 --- a/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi +++ /dev/null @@ -1,43 +0,0 @@ -/* - * PQ3 MPIC Message (Group B) device tree stub [ controller @ offset 0x42400 ] - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -message@42400 { - compatible = "fsl,mpic-v3.1-msgr"; - reg = <0x42400 0x200>; - interrupts = < - 0xb4 2 0 0 - 0xb5 2 0 0 - 0xb6 2 0 0 - 0xb7 2 0 0>; -}; diff --git a/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi b/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi index 71c30eb10056..fdedf7b1fe0f 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/pq3-mpic.dtsi @@ -53,16 +53,6 @@ timer@41100 { 3 0 3 0>; }; -message@41400 { - compatible = "fsl,mpic-v3.1-msgr"; - reg = <0x41400 0x200>; - interrupts = < - 0xb0 2 0 0 - 0xb1 2 0 0 - 0xb2 2 0 0 - 0xb3 2 0 0>; -}; - msi@41600 { compatible = "fsl,mpic-msi"; reg = <0x41600 0x80>; diff --git a/trunk/arch/powerpc/include/asm/irq.h b/trunk/arch/powerpc/include/asm/irq.h index 0e40843a1c6e..e648af92ced1 100644 --- a/trunk/arch/powerpc/include/asm/irq.h +++ b/trunk/arch/powerpc/include/asm/irq.h @@ -18,6 +18,10 @@ #include +/* Define a way to iterate across irqs. */ +#define for_each_irq(i) \ + for ((i) = 0; (i) < NR_IRQS; ++(i)) + extern atomic_t ppc_n_lost_interrupts; /* This number is used when no interrupt has been assigned */ diff --git a/trunk/arch/powerpc/include/asm/mpic.h b/trunk/arch/powerpc/include/asm/mpic.h index c9f698a994be..c65b9294376e 100644 --- a/trunk/arch/powerpc/include/asm/mpic.h +++ b/trunk/arch/powerpc/include/asm/mpic.h @@ -275,6 +275,9 @@ struct mpic unsigned int isu_mask; /* Number of sources */ unsigned int num_sources; + /* default senses array */ + unsigned char *senses; + unsigned int senses_count; /* vector numbers used for internal sources (ipi/timers) */ unsigned int ipi_vecs[4]; @@ -412,6 +415,21 @@ extern struct mpic *mpic_alloc(struct device_node *node, extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, phys_addr_t phys_addr); +/* Set default sense codes + * + * @mpic: controller + * @senses: array of sense codes + * @count: size of above array + * + * Optionally provide an array (indexed on hardware interrupt numbers + * for this MPIC) of default sense codes for the chip. Those are linux + * sense codes IRQ_TYPE_* + * + * The driver gets ownership of the pointer, don't dispose of it or + * anything like that. __init only. + */ +extern void mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count); + /* Initialize the controller. After this has been called, none of the above * should be called again for this mpic diff --git a/trunk/arch/powerpc/include/asm/mpic_msgr.h b/trunk/arch/powerpc/include/asm/mpic_msgr.h index 326d33ca55cd..3ec37dc9003e 100644 --- a/trunk/arch/powerpc/include/asm/mpic_msgr.h +++ b/trunk/arch/powerpc/include/asm/mpic_msgr.h @@ -13,7 +13,6 @@ #include #include -#include struct mpic_msgr { u32 __iomem *base; diff --git a/trunk/arch/powerpc/include/asm/reg_booke.h b/trunk/arch/powerpc/include/asm/reg_booke.h index 8a97aa7289d3..b86faa9107da 100644 --- a/trunk/arch/powerpc/include/asm/reg_booke.h +++ b/trunk/arch/powerpc/include/asm/reg_booke.h @@ -15,6 +15,11 @@ #ifndef __ASM_POWERPC_REG_BOOKE_H__ #define __ASM_POWERPC_REG_BOOKE_H__ +#ifdef CONFIG_BOOKE_WDT +extern u32 booke_wdt_enabled; +extern u32 booke_wdt_period; +#endif /* CONFIG_BOOKE_WDT */ + /* Machine State Register (MSR) Fields */ #define MSR_GS (1<<28) /* Guest state */ #define MSR_UCLE (1<<26) /* User-mode cache lock enable */ diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 43eb74fcedde..5ec1b2354ca6 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -330,10 +330,14 @@ void migrate_irqs(void) alloc_cpumask_var(&mask, GFP_KERNEL); - for_each_irq_desc(irq, desc) { + for_each_irq(irq) { struct irq_data *data; struct irq_chip *chip; + desc = irq_to_desc(irq); + if (!desc) + continue; + data = irq_desc_get_irq_data(desc); if (irqd_is_per_cpu(data)) continue; diff --git a/trunk/arch/powerpc/kernel/machine_kexec.c b/trunk/arch/powerpc/kernel/machine_kexec.c index 5df777794403..c957b1202bdc 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec.c +++ b/trunk/arch/powerpc/kernel/machine_kexec.c @@ -23,11 +23,14 @@ void machine_kexec_mask_interrupts(void) { unsigned int i; - struct irq_desc *desc; - for_each_irq_desc(i, desc) { + for_each_irq(i) { + struct irq_desc *desc = irq_to_desc(i); struct irq_chip *chip; + if (!desc) + continue; + chip = irq_desc_get_chip(desc); if (!chip) continue; diff --git a/trunk/arch/powerpc/kernel/setup_32.c b/trunk/arch/powerpc/kernel/setup_32.c index ec8a53fa9e8f..9825f29d1faf 100644 --- a/trunk/arch/powerpc/kernel/setup_32.c +++ b/trunk/arch/powerpc/kernel/setup_32.c @@ -150,9 +150,6 @@ notrace void __init machine_init(u64 dt_ptr) } #ifdef CONFIG_BOOKE_WDT -extern u32 booke_wdt_enabled; -extern u32 booke_wdt_period; - /* Checks wdt=x and wdt_period=xx command-line option */ notrace int __init early_parse_wdt(char *p) { diff --git a/trunk/arch/powerpc/net/bpf_jit.h b/trunk/arch/powerpc/net/bpf_jit.h index 5c3cf2d04e41..af1ab5e9a691 100644 --- a/trunk/arch/powerpc/net/bpf_jit.h +++ b/trunk/arch/powerpc/net/bpf_jit.h @@ -48,13 +48,7 @@ /* * Assembly helpers from arch/powerpc/net/bpf_jit.S: */ -#define DECLARE_LOAD_FUNC(func) \ - extern u8 func[], func##_negative_offset[], func##_positive_offset[] - -DECLARE_LOAD_FUNC(sk_load_word); -DECLARE_LOAD_FUNC(sk_load_half); -DECLARE_LOAD_FUNC(sk_load_byte); -DECLARE_LOAD_FUNC(sk_load_byte_msh); +extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[]; #define FUNCTION_DESCR_SIZE 24 diff --git a/trunk/arch/powerpc/net/bpf_jit_64.S b/trunk/arch/powerpc/net/bpf_jit_64.S index 55ba3855a97f..ff4506e85cce 100644 --- a/trunk/arch/powerpc/net/bpf_jit_64.S +++ b/trunk/arch/powerpc/net/bpf_jit_64.S @@ -31,13 +31,14 @@ * then branch directly to slow_path_XXX if required. (In fact, could * load a spare GPR with the address of slow_path_generic and pass size * as an argument, making the call site a mtlr, li and bllr.) + * + * Technically, the "is addr < 0" check is unnecessary & slowing down + * the ABS path, as it's statically checked on generation. */ .globl sk_load_word sk_load_word: cmpdi r_addr, 0 - blt bpf_slow_path_word_neg - .globl sk_load_word_positive_offset -sk_load_word_positive_offset: + blt bpf_error /* Are we accessing past headlen? */ subi r_scratch1, r_HL, 4 cmpd r_scratch1, r_addr @@ -50,9 +51,7 @@ sk_load_word_positive_offset: .globl sk_load_half sk_load_half: cmpdi r_addr, 0 - blt bpf_slow_path_half_neg - .globl sk_load_half_positive_offset -sk_load_half_positive_offset: + blt bpf_error subi r_scratch1, r_HL, 2 cmpd r_scratch1, r_addr blt bpf_slow_path_half @@ -62,9 +61,7 @@ sk_load_half_positive_offset: .globl sk_load_byte sk_load_byte: cmpdi r_addr, 0 - blt bpf_slow_path_byte_neg - .globl sk_load_byte_positive_offset -sk_load_byte_positive_offset: + blt bpf_error cmpd r_HL, r_addr ble bpf_slow_path_byte lbzx r_A, r_D, r_addr @@ -72,20 +69,22 @@ sk_load_byte_positive_offset: /* * BPF_S_LDX_B_MSH: ldxb 4*([offset]&0xf) - * r_addr is the offset value + * r_addr is the offset value, already known positive */ .globl sk_load_byte_msh sk_load_byte_msh: - cmpdi r_addr, 0 - blt bpf_slow_path_byte_msh_neg - .globl sk_load_byte_msh_positive_offset -sk_load_byte_msh_positive_offset: cmpd r_HL, r_addr ble bpf_slow_path_byte_msh lbzx r_X, r_D, r_addr rlwinm r_X, r_X, 2, 32-4-2, 31-2 blr +bpf_error: + /* Entered with cr0 = lt */ + li r3, 0 + /* Generated code will 'blt epilogue', returning 0. */ + blr + /* Call out to skb_copy_bits: * We'll need to back up our volatile regs first; we have * local variable space at r1+(BPF_PPC_STACK_BASIC). @@ -137,84 +136,3 @@ bpf_slow_path_byte_msh: lbz r_X, BPF_PPC_STACK_BASIC+(2*8)(r1) rlwinm r_X, r_X, 2, 32-4-2, 31-2 blr - -/* Call out to bpf_internal_load_pointer_neg_helper: - * We'll need to back up our volatile regs first; we have - * local variable space at r1+(BPF_PPC_STACK_BASIC). - * Allocate a new stack frame here to remain ABI-compliant in - * stashing LR. - */ -#define sk_negative_common(SIZE) \ - mflr r0; \ - std r0, 16(r1); \ - /* R3 goes in parameter space of caller's frame */ \ - std r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ - std r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ - std r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ - stdu r1, -BPF_PPC_SLOWPATH_FRAME(r1); \ - /* R3 = r_skb, as passed */ \ - mr r4, r_addr; \ - li r5, SIZE; \ - bl bpf_internal_load_pointer_neg_helper; \ - /* R3 != 0 on success */ \ - addi r1, r1, BPF_PPC_SLOWPATH_FRAME; \ - ld r0, 16(r1); \ - ld r_A, (BPF_PPC_STACK_BASIC+(0*8))(r1); \ - ld r_X, (BPF_PPC_STACK_BASIC+(1*8))(r1); \ - mtlr r0; \ - cmpldi r3, 0; \ - beq bpf_error_slow; /* cr0 = EQ */ \ - mr r_addr, r3; \ - ld r_skb, (BPF_PPC_STACKFRAME+48)(r1); \ - /* Great success! */ - -bpf_slow_path_word_neg: - lis r_scratch1,-32 /* SKF_LL_OFF */ - cmpd r_addr, r_scratch1 /* addr < SKF_* */ - blt bpf_error /* cr0 = LT */ - .globl sk_load_word_negative_offset -sk_load_word_negative_offset: - sk_negative_common(4) - lwz r_A, 0(r_addr) - blr - -bpf_slow_path_half_neg: - lis r_scratch1,-32 /* SKF_LL_OFF */ - cmpd r_addr, r_scratch1 /* addr < SKF_* */ - blt bpf_error /* cr0 = LT */ - .globl sk_load_half_negative_offset -sk_load_half_negative_offset: - sk_negative_common(2) - lhz r_A, 0(r_addr) - blr - -bpf_slow_path_byte_neg: - lis r_scratch1,-32 /* SKF_LL_OFF */ - cmpd r_addr, r_scratch1 /* addr < SKF_* */ - blt bpf_error /* cr0 = LT */ - .globl sk_load_byte_negative_offset -sk_load_byte_negative_offset: - sk_negative_common(1) - lbz r_A, 0(r_addr) - blr - -bpf_slow_path_byte_msh_neg: - lis r_scratch1,-32 /* SKF_LL_OFF */ - cmpd r_addr, r_scratch1 /* addr < SKF_* */ - blt bpf_error /* cr0 = LT */ - .globl sk_load_byte_msh_negative_offset -sk_load_byte_msh_negative_offset: - sk_negative_common(1) - lbz r_X, 0(r_addr) - rlwinm r_X, r_X, 2, 32-4-2, 31-2 - blr - -bpf_error_slow: - /* fabricate a cr0 = lt */ - li r_scratch1, -1 - cmpdi r_scratch1, 0 -bpf_error: - /* Entered with cr0 = lt */ - li r3, 0 - /* Generated code will 'blt epilogue', returning 0. */ - blr diff --git a/trunk/arch/powerpc/net/bpf_jit_comp.c b/trunk/arch/powerpc/net/bpf_jit_comp.c index 2dc8b1484845..73619d3aeb6c 100644 --- a/trunk/arch/powerpc/net/bpf_jit_comp.c +++ b/trunk/arch/powerpc/net/bpf_jit_comp.c @@ -127,9 +127,6 @@ static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) PPC_BLR(); } -#define CHOOSE_LOAD_FUNC(K, func) \ - ((int)K < 0 ? ((int)K >= SKF_LL_OFF ? func##_negative_offset : func) : func##_positive_offset) - /* Assemble the body code between the prologue & epilogue. */ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, struct codegen_context *ctx, @@ -394,16 +391,21 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, /*** Absolute loads from packet header/data ***/ case BPF_S_LD_W_ABS: - func = CHOOSE_LOAD_FUNC(K, sk_load_word); + func = sk_load_word; goto common_load; case BPF_S_LD_H_ABS: - func = CHOOSE_LOAD_FUNC(K, sk_load_half); + func = sk_load_half; goto common_load; case BPF_S_LD_B_ABS: - func = CHOOSE_LOAD_FUNC(K, sk_load_byte); + func = sk_load_byte; common_load: - /* Load from [K]. */ + /* + * Load from [K]. Reference with the (negative) + * SKF_NET_OFF/SKF_LL_OFF offsets is unsupported. + */ ctx->seen |= SEEN_DATAREF; + if ((int)K < 0) + return -ENOTSUPP; PPC_LI64(r_scratch1, func); PPC_MTLR(r_scratch1); PPC_LI32(r_addr, K); @@ -427,7 +429,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, common_load_ind: /* * Load from [X + K]. Negative offsets are tested for - * in the helper functions. + * in the helper functions, and result in a 'ret 0'. */ ctx->seen |= SEEN_DATAREF | SEEN_XREG; PPC_LI64(r_scratch1, func); @@ -441,7 +443,13 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image, break; case BPF_S_LDX_B_MSH: - func = CHOOSE_LOAD_FUNC(K, sk_load_byte_msh); + /* + * x86 version drops packet (RET 0) when K<0, whereas + * interpreter does allow K<0 (__load_pointer, special + * ancillary data). common_load returns ENOTSUPP if K<0, + * so we fall back to interpreter & filter works. + */ + func = sk_load_byte_msh; goto common_load; break; diff --git a/trunk/arch/powerpc/platforms/85xx/common.c b/trunk/arch/powerpc/platforms/85xx/common.c index 67dac22b4363..9fef5302adc1 100644 --- a/trunk/arch/powerpc/platforms/85xx/common.c +++ b/trunk/arch/powerpc/platforms/85xx/common.c @@ -21,12 +21,6 @@ static struct of_device_id __initdata mpc85xx_common_ids[] = { { .compatible = "fsl,qe", }, { .compatible = "fsl,cpm2", }, { .compatible = "fsl,srio", }, - /* So that the DMA channel nodes can be probed individually: */ - { .compatible = "fsl,eloplus-dma", }, - /* For the PMC driver */ - { .compatible = "fsl,mpc8548-guts", }, - /* Probably unnecessary? */ - { .compatible = "gpio-leds", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c index d208ebccb91c..9a6f04406e0d 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -399,6 +399,12 @@ static int __init board_fixups(void) machine_arch_initcall(mpc8568_mds, board_fixups); machine_arch_initcall(mpc8569_mds, board_fixups); +static struct of_device_id mpc85xx_ids[] = { + { .compatible = "fsl,mpc8548-guts", }, + { .compatible = "gpio-leds", }, + {}, +}; + static int __init mpc85xx_publish_devices(void) { if (machine_is(mpc8568_mds)) @@ -406,7 +412,10 @@ static int __init mpc85xx_publish_devices(void) if (machine_is(mpc8569_mds)) simple_gpiochip_init("fsl,mpc8569mds-bcsr-gpio"); - return mpc85xx_common_publish_devices(); + mpc85xx_common_publish_devices(); + of_platform_bus_probe(NULL, mpc85xx_ids, NULL); + + return 0; } machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); diff --git a/trunk/arch/powerpc/platforms/85xx/p1022_ds.c b/trunk/arch/powerpc/platforms/85xx/p1022_ds.c index f700c81a1321..e74b7cde9aee 100644 --- a/trunk/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/p1022_ds.c @@ -460,7 +460,18 @@ static void __init p1022_ds_setup_arch(void) pr_info("Freescale P1022 DS reference board\n"); } -machine_device_initcall(p1022_ds, mpc85xx_common_publish_devices); +static struct of_device_id __initdata p1022_ds_ids[] = { + /* So that the DMA channel nodes can be probed individually: */ + { .compatible = "fsl,eloplus-dma", }, + {}, +}; + +static int __init p1022_ds_publish_devices(void) +{ + mpc85xx_common_publish_devices(); + return of_platform_bus_probe(NULL, p1022_ds_ids, NULL); +} +machine_device_initcall(p1022_ds, p1022_ds_publish_devices); machine_arch_initcall(p1022_ds, swiotlb_setup_bus_notifier); diff --git a/trunk/arch/powerpc/platforms/cell/axon_msi.c b/trunk/arch/powerpc/platforms/cell/axon_msi.c index 85825b5401e5..d09f3e8e6867 100644 --- a/trunk/arch/powerpc/platforms/cell/axon_msi.c +++ b/trunk/arch/powerpc/platforms/cell/axon_msi.c @@ -114,7 +114,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc) pr_devel("axon_msi: woff %x roff %x msi %x\n", write_offset, msic->read_offset, msi); - if (msi < nr_irqs && irq_get_chip_data(msi) == msic) { + if (msi < NR_IRQS && irq_get_chip_data(msi) == msic) { generic_handle_irq(msi); msic->fifo_virt[idx] = cpu_to_le32(0xffffffff); } else { @@ -276,6 +276,9 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (rc) return rc; + /* We rely on being able to stash a virq in a u16 */ + BUILD_BUG_ON(NR_IRQS > 65536); + list_for_each_entry(entry, &dev->msi_list, list) { virq = irq_create_direct_mapping(msic->irq_domain); if (virq == NO_IRQ) { @@ -389,8 +392,7 @@ static int axon_msi_probe(struct platform_device *device) } memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES); - /* We rely on being able to stash a virq in a u16, so limit irqs to < 65536 */ - msic->irq_domain = irq_domain_add_nomap(dn, 65536, &msic_host_ops, msic); + msic->irq_domain = irq_domain_add_nomap(dn, 0, &msic_host_ops, msic); if (!msic->irq_domain) { printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n", dn->full_name); diff --git a/trunk/arch/powerpc/platforms/cell/beat_interrupt.c b/trunk/arch/powerpc/platforms/cell/beat_interrupt.c index 8c6dc42ecf65..f9a48af335cb 100644 --- a/trunk/arch/powerpc/platforms/cell/beat_interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/beat_interrupt.c @@ -248,6 +248,6 @@ void beatic_deinit_IRQ(void) { int i; - for (i = 1; i < nr_irqs; i++) + for (i = 1; i < NR_IRQS; i++) beat_destruct_irq_plug(i); } diff --git a/trunk/arch/powerpc/platforms/powermac/low_i2c.c b/trunk/arch/powerpc/platforms/powermac/low_i2c.c index 03685a329d7d..996c5ff7824b 100644 --- a/trunk/arch/powerpc/platforms/powermac/low_i2c.c +++ b/trunk/arch/powerpc/platforms/powermac/low_i2c.c @@ -366,20 +366,11 @@ static void kw_i2c_timeout(unsigned long data) unsigned long flags; spin_lock_irqsave(&host->lock, flags); - - /* - * If the timer is pending, that means we raced with the - * irq, in which case we just return - */ - if (timer_pending(&host->timeout_timer)) - goto skip; - kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr)); if (host->state != state_idle) { host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT; add_timer(&host->timeout_timer); } - skip: spin_unlock_irqrestore(&host->lock, flags); } diff --git a/trunk/arch/powerpc/platforms/powermac/pic.c b/trunk/arch/powerpc/platforms/powermac/pic.c index c4e630576ff2..66ad93de1d55 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.c +++ b/trunk/arch/powerpc/platforms/powermac/pic.c @@ -57,9 +57,9 @@ static int max_real_irqs; static DEFINE_RAW_SPINLOCK(pmac_pic_lock); -/* The max irq number this driver deals with is 128; see max_irqs */ -static DECLARE_BITMAP(ppc_lost_interrupts, 128); -static DECLARE_BITMAP(ppc_cached_irq_mask, 128); +#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) +static unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; +static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; static int pmac_irq_cascade = -1; static struct irq_domain *pmac_pic_host; diff --git a/trunk/arch/powerpc/platforms/pseries/Kconfig b/trunk/arch/powerpc/platforms/pseries/Kconfig index 178a5f300bc9..aadbe4f6d537 100644 --- a/trunk/arch/powerpc/platforms/pseries/Kconfig +++ b/trunk/arch/powerpc/platforms/pseries/Kconfig @@ -30,9 +30,9 @@ config PPC_SPLPAR two or more partitions. config EEH - bool + bool "PCI Extended Error Handling (EEH)" if EXPERT depends on PPC_PSERIES && PCI - default y + default y if !EXPERT config PSERIES_MSI bool diff --git a/trunk/arch/powerpc/platforms/pseries/eeh.c b/trunk/arch/powerpc/platforms/pseries/eeh.c index a75e37dc41aa..309d38ef7322 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh.c @@ -1076,7 +1076,7 @@ static void eeh_add_device_late(struct pci_dev *dev) pr_debug("EEH: Adding device %s\n", pci_name(dev)); dn = pci_device_to_OF_node(dev); - edev = of_node_to_eeh_dev(dn); + edev = pci_dev_to_eeh_dev(dev); if (edev->pdev == dev) { pr_debug("EEH: Already referenced !\n"); return; diff --git a/trunk/arch/powerpc/sysdev/cpm2_pic.c b/trunk/arch/powerpc/sysdev/cpm2_pic.c index 10386b676d87..d3be961e2ae7 100644 --- a/trunk/arch/powerpc/sysdev/cpm2_pic.c +++ b/trunk/arch/powerpc/sysdev/cpm2_pic.c @@ -51,7 +51,8 @@ static intctl_cpm2_t __iomem *cpm2_intctl; static struct irq_domain *cpm2_pic_host; -static unsigned long ppc_cached_irq_mask[2]; /* 2 32-bit registers */ +#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) +static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; static const u_char irq_to_siureg[] = { 1, 1, 1, 1, 1, 1, 1, 1, diff --git a/trunk/arch/powerpc/sysdev/mpc8xx_pic.c b/trunk/arch/powerpc/sysdev/mpc8xx_pic.c index b724622c3a0b..d5f5416be310 100644 --- a/trunk/arch/powerpc/sysdev/mpc8xx_pic.c +++ b/trunk/arch/powerpc/sysdev/mpc8xx_pic.c @@ -18,45 +18,69 @@ extern int cpm_get_irq(struct pt_regs *regs); static struct irq_domain *mpc8xx_pic_host; -static unsigned long mpc8xx_cached_irq_mask; +#define NR_MASK_WORDS ((NR_IRQS + 31) / 32) +static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; static sysconf8xx_t __iomem *siu_reg; -static inline unsigned long mpc8xx_irqd_to_bit(struct irq_data *d) -{ - return 0x80000000 >> irqd_to_hwirq(d); -} +int cpm_get_irq(struct pt_regs *regs); static void mpc8xx_unmask_irq(struct irq_data *d) { - mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); - out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); + int bit, word; + unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); + + bit = irq_nr & 0x1f; + word = irq_nr >> 5; + + ppc_cached_irq_mask[word] |= (1 << (31-bit)); + out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); } static void mpc8xx_mask_irq(struct irq_data *d) { - mpc8xx_cached_irq_mask &= ~mpc8xx_irqd_to_bit(d); - out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); + int bit, word; + unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); + + bit = irq_nr & 0x1f; + word = irq_nr >> 5; + + ppc_cached_irq_mask[word] &= ~(1 << (31-bit)); + out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); } static void mpc8xx_ack(struct irq_data *d) { - out_be32(&siu_reg->sc_sipend, mpc8xx_irqd_to_bit(d)); + int bit; + unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); + + bit = irq_nr & 0x1f; + out_be32(&siu_reg->sc_sipend, 1 << (31-bit)); } static void mpc8xx_end_irq(struct irq_data *d) { - mpc8xx_cached_irq_mask |= mpc8xx_irqd_to_bit(d); - out_be32(&siu_reg->sc_simask, mpc8xx_cached_irq_mask); + int bit, word; + unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d); + + bit = irq_nr & 0x1f; + word = irq_nr >> 5; + + ppc_cached_irq_mask[word] |= (1 << (31-bit)); + out_be32(&siu_reg->sc_simask, ppc_cached_irq_mask[word]); } static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type) { - /* only external IRQ senses are programmable */ - if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !(irqd_to_hwirq(d) & 1)) { + if (flow_type & IRQ_TYPE_EDGE_FALLING) { + irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d); unsigned int siel = in_be32(&siu_reg->sc_siel); - siel |= mpc8xx_irqd_to_bit(d); - out_be32(&siu_reg->sc_siel, siel); - __irq_set_handler_locked(d->irq, handle_edge_irq); + + /* only external IRQ senses are programmable */ + if ((hw & 1) == 0) { + siel |= (0x80000000 >> hw); + out_be32(&siu_reg->sc_siel, siel); + __irq_set_handler_locked(d->irq, handle_edge_irq); + } } return 0; } @@ -108,9 +132,6 @@ static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct, IRQ_TYPE_EDGE_FALLING, }; - if (intspec[0] > 0x1f) - return 0; - *out_hwirq = intspec[0]; if (intsize > 1 && intspec[1] < 4) *out_flags = map_pic_senses[intspec[1]]; diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index 395af1347749..9ac71ebd2c40 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -604,14 +604,18 @@ static struct mpic *mpic_find(unsigned int irq) } /* Determine if the linux irq is an IPI */ -static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int src) +static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq) { + unsigned int src = virq_to_hw(irq); + return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]); } /* Determine if the linux irq is a timer */ -static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int src) +static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int irq) { + unsigned int src = virq_to_hw(irq); + return (src >= mpic->timer_vecs[0] && src <= mpic->timer_vecs[7]); } @@ -872,45 +876,21 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type) if (src >= mpic->num_sources) return -EINVAL; - vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); - - /* We don't support "none" type */ if (flow_type == IRQ_TYPE_NONE) - flow_type = IRQ_TYPE_DEFAULT; - - /* Default: read HW settings */ - if (flow_type == IRQ_TYPE_DEFAULT) { - switch(vold & (MPIC_INFO(VECPRI_POLARITY_MASK) | - MPIC_INFO(VECPRI_SENSE_MASK))) { - case MPIC_INFO(VECPRI_SENSE_EDGE) | - MPIC_INFO(VECPRI_POLARITY_POSITIVE): - flow_type = IRQ_TYPE_EDGE_RISING; - break; - case MPIC_INFO(VECPRI_SENSE_EDGE) | - MPIC_INFO(VECPRI_POLARITY_NEGATIVE): - flow_type = IRQ_TYPE_EDGE_FALLING; - break; - case MPIC_INFO(VECPRI_SENSE_LEVEL) | - MPIC_INFO(VECPRI_POLARITY_POSITIVE): - flow_type = IRQ_TYPE_LEVEL_HIGH; - break; - case MPIC_INFO(VECPRI_SENSE_LEVEL) | - MPIC_INFO(VECPRI_POLARITY_NEGATIVE): - flow_type = IRQ_TYPE_LEVEL_LOW; - break; - } - } + if (mpic->senses && src < mpic->senses_count) + flow_type = mpic->senses[src]; + if (flow_type == IRQ_TYPE_NONE) + flow_type = IRQ_TYPE_LEVEL_LOW; - /* Apply to irq desc */ irqd_set_trigger_type(d, flow_type); - /* Apply to HW */ if (mpic_is_ht_interrupt(mpic, src)) vecpri = MPIC_VECPRI_POLARITY_POSITIVE | MPIC_VECPRI_SENSE_EDGE; else vecpri = mpic_type_to_vecpri(mpic, flow_type); + vold = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); vnew = vold & ~(MPIC_INFO(VECPRI_POLARITY_MASK) | MPIC_INFO(VECPRI_SENSE_MASK)); vnew |= vecpri; @@ -1046,7 +1026,7 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq, irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq); /* Set default irq type */ - irq_set_irq_type(virq, IRQ_TYPE_DEFAULT); + irq_set_irq_type(virq, IRQ_TYPE_NONE); /* If the MPIC was reset, then all vectors have already been * initialized. Otherwise, a per source lazy initialization @@ -1437,6 +1417,12 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, mpic->num_sources = isu_first + mpic->isu_size; } +void __init mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count) +{ + mpic->senses = senses; + mpic->senses_count = count; +} + void __init mpic_init(struct mpic *mpic) { int i, cpu; @@ -1569,12 +1555,12 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri) return; raw_spin_lock_irqsave(&mpic_lock, flags); - if (mpic_is_ipi(mpic, src)) { + if (mpic_is_ipi(mpic, irq)) { reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) & ~MPIC_VECPRI_PRIORITY_MASK; mpic_ipi_write(src - mpic->ipi_vecs[0], reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT)); - } else if (mpic_is_tm(mpic, src)) { + } else if (mpic_is_tm(mpic, irq)) { reg = mpic_tm_read(src - mpic->timer_vecs[0]) & ~MPIC_VECPRI_PRIORITY_MASK; mpic_tm_write(src - mpic->timer_vecs[0], diff --git a/trunk/arch/powerpc/sysdev/mpic_msgr.c b/trunk/arch/powerpc/sysdev/mpic_msgr.c index 483d8fa72e8b..6e7fa386e76a 100644 --- a/trunk/arch/powerpc/sysdev/mpic_msgr.c +++ b/trunk/arch/powerpc/sysdev/mpic_msgr.c @@ -27,7 +27,6 @@ static struct mpic_msgr **mpic_msgrs; static unsigned int mpic_msgr_count; -static DEFINE_RAW_SPINLOCK(msgrs_lock); static inline void _mpic_msgr_mer_write(struct mpic_msgr *msgr, u32 value) { @@ -57,11 +56,12 @@ struct mpic_msgr *mpic_msgr_get(unsigned int reg_num) if (reg_num >= mpic_msgr_count) return ERR_PTR(-ENODEV); - raw_spin_lock_irqsave(&msgrs_lock, flags); - msgr = mpic_msgrs[reg_num]; - if (msgr->in_use == MSGR_FREE) + raw_spin_lock_irqsave(&msgr->lock, flags); + if (mpic_msgrs[reg_num]->in_use == MSGR_FREE) { + msgr = mpic_msgrs[reg_num]; msgr->in_use = MSGR_INUSE; - raw_spin_unlock_irqrestore(&msgrs_lock, flags); + } + raw_spin_unlock_irqrestore(&msgr->lock, flags); return msgr; } @@ -228,7 +228,7 @@ static __devinit int mpic_msgr_probe(struct platform_device *dev) reg_number = block_number * MPIC_MSGR_REGISTERS_PER_BLOCK + i; msgr->base = msgr_block_addr + i * MPIC_MSGR_STRIDE; - msgr->mer = (u32 *)((u8 *)msgr->base + MPIC_MSGR_MER_OFFSET); + msgr->mer = msgr->base + MPIC_MSGR_MER_OFFSET; msgr->in_use = MSGR_FREE; msgr->num = i; raw_spin_lock_init(&msgr->lock); diff --git a/trunk/arch/powerpc/sysdev/scom.c b/trunk/arch/powerpc/sysdev/scom.c index 702256a1ca11..49a3ece1c6b3 100644 --- a/trunk/arch/powerpc/sysdev/scom.c +++ b/trunk/arch/powerpc/sysdev/scom.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/powerpc/sysdev/xics/xics-common.c b/trunk/arch/powerpc/sysdev/xics/xics-common.c index cd1d18db92c6..ea5e204e3450 100644 --- a/trunk/arch/powerpc/sysdev/xics/xics-common.c +++ b/trunk/arch/powerpc/sysdev/xics/xics-common.c @@ -188,7 +188,6 @@ void xics_migrate_irqs_away(void) { int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); unsigned int irq, virq; - struct irq_desc *desc; /* If we used to be the default server, move to the new "boot_cpuid" */ if (hw_cpu == xics_default_server) @@ -203,7 +202,8 @@ void xics_migrate_irqs_away(void) /* Allow IPIs again... */ icp_ops->set_priority(DEFAULT_PRIORITY); - for_each_irq_desc(virq, desc) { + for_each_irq(virq) { + struct irq_desc *desc; struct irq_chip *chip; long server; unsigned long flags; @@ -212,8 +212,9 @@ void xics_migrate_irqs_away(void) /* We can't set affinity on ISA interrupts */ if (virq < NUM_ISA_INTERRUPTS) continue; + desc = irq_to_desc(virq); /* We only need to migrate enabled IRQS */ - if (!desc->action) + if (!desc || !desc->action) continue; if (desc->irq_data.domain != xics_host) continue; diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index 9015060919a0..2b7c0fbe578e 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -90,6 +90,7 @@ config S390 select HAVE_KERNEL_XZ select HAVE_ARCH_MUTEX_CPU_RELAX select HAVE_ARCH_JUMP_LABEL if !MARCH_G5 + select HAVE_RCU_TABLE_FREE if SMP select ARCH_SAVE_PAGE_KEYS if HIBERNATION select HAVE_MEMBLOCK select HAVE_MEMBLOCK_NODE_MAP diff --git a/trunk/arch/s390/defconfig b/trunk/arch/s390/defconfig index 1957a9dd256d..6cf8e26b3137 100644 --- a/trunk/arch/s390/defconfig +++ b/trunk/arch/s390/defconfig @@ -1,12 +1,8 @@ CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y -CONFIG_FHANDLE=y -CONFIG_TASKSTATS=y -CONFIG_TASK_DELAY_ACCT=y -CONFIG_TASK_XACCT=y -CONFIG_TASK_IO_ACCOUNTING=y CONFIG_AUDIT=y +CONFIG_RCU_TRACE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CGROUPS=y @@ -18,22 +14,16 @@ CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y CONFIG_CGROUP_SCHED=y CONFIG_RT_GROUP_SCHED=y CONFIG_BLK_CGROUP=y -CONFIG_NAMESPACES=y CONFIG_BLK_DEV_INITRD=y -CONFIG_RD_BZIP2=y -CONFIG_RD_LZMA=y -CONFIG_RD_XZ=y -CONFIG_RD_LZO=y -CONFIG_EXPERT=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set # CONFIG_COMPAT_BRK is not set +CONFIG_SLAB=y CONFIG_PROFILING=y CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y -CONFIG_PARTITION_ADVANCED=y -CONFIG_IBM_PARTITION=y CONFIG_DEFAULT_DEADLINE=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -44,15 +34,18 @@ CONFIG_KSM=y CONFIG_BINFMT_MISC=m CONFIG_CMM=m CONFIG_HZ_100=y -CONFIG_CRASH_DUMP=y +CONFIG_KEXEC=y +CONFIG_PM=y CONFIG_HIBERNATION=y CONFIG_PACKET=y CONFIG_UNIX=y CONFIG_NET_KEY=y +CONFIG_AFIUCV=m CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_INET_LRO is not set CONFIG_IPV6=y +CONFIG_NET_SCTPPROBE=m CONFIG_L2TP=m CONFIG_L2TP_DEBUGFS=m CONFIG_VLAN_8021Q=y @@ -91,14 +84,15 @@ CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_ZFCP=y +CONFIG_ZFCP_DIF=y CONFIG_NETDEVICES=y -CONFIG_BONDING=m CONFIG_DUMMY=m +CONFIG_BONDING=m CONFIG_EQUALIZER=m CONFIG_TUN=m +CONFIG_NET_ETHERNET=y CONFIG_VIRTIO_NET=y CONFIG_RAW_DRIVER=m -CONFIG_VIRTIO_BALLOON=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set @@ -109,21 +103,27 @@ CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_PARTITION_ADVANCED=y +CONFIG_IBM_PARTITION=y +CONFIG_DLM=m CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_KERNEL=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y CONFIG_PROVE_RCU=y CONFIG_LOCK_STAT=y CONFIG_DEBUG_LOCKDEP=y +CONFIG_DEBUG_SPINLOCK_SLEEP=y CONFIG_DEBUG_LIST=y CONFIG_DEBUG_NOTIFIERS=y -CONFIG_RCU_TRACE=y +# CONFIG_RCU_CPU_STALL_DETECTOR is not set CONFIG_KPROBES_SANITY_TEST=y CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y CONFIG_CPU_NOTIFIER_ERROR_INJECT=m CONFIG_LATENCYTOP=y +CONFIG_SYSCTL_SYSCALL_CHECK=y CONFIG_DEBUG_PAGEALLOC=y -CONFIG_BLK_DEV_IO_TRACE=y +# CONFIG_FTRACE is not set # CONFIG_STRICT_DEVMEM is not set CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m @@ -173,3 +173,4 @@ CONFIG_CRYPTO_SHA512_S390=m CONFIG_CRYPTO_DES_S390=m CONFIG_CRYPTO_AES_S390=m CONFIG_CRC7=m +CONFIG_VIRTIO_BALLOON=y diff --git a/trunk/arch/s390/include/asm/facility.h b/trunk/arch/s390/include/asm/facility.h index 2ee66a65f2d4..1e5b27edc0c9 100644 --- a/trunk/arch/s390/include/asm/facility.h +++ b/trunk/arch/s390/include/asm/facility.h @@ -38,11 +38,12 @@ static inline void stfle(u64 *stfle_fac_list, int size) unsigned long nr; preempt_disable(); + S390_lowcore.stfl_fac_list = 0; asm volatile( " .insn s,0xb2b10000,0(0)\n" /* stfl */ "0:\n" EX_TABLE(0b, 0b) - : "+m" (S390_lowcore.stfl_fac_list)); + : "=m" (S390_lowcore.stfl_fac_list)); nr = 4; /* bytes stored by stfl */ memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); if (S390_lowcore.stfl_fac_list & 0x01000000) { diff --git a/trunk/arch/s390/include/asm/pgalloc.h b/trunk/arch/s390/include/asm/pgalloc.h index 78e3041919de..8eef9b5b3cf4 100644 --- a/trunk/arch/s390/include/asm/pgalloc.h +++ b/trunk/arch/s390/include/asm/pgalloc.h @@ -22,7 +22,10 @@ void crst_table_free(struct mm_struct *, unsigned long *); unsigned long *page_table_alloc(struct mm_struct *, unsigned long); void page_table_free(struct mm_struct *, unsigned long *); +#ifdef CONFIG_HAVE_RCU_TABLE_FREE void page_table_free_rcu(struct mmu_gather *, unsigned long *); +void __tlb_remove_table(void *_table); +#endif static inline void clear_table(unsigned long *s, unsigned long val, size_t n) { diff --git a/trunk/arch/s390/include/asm/swab.h b/trunk/arch/s390/include/asm/swab.h index a3e4ebb32090..6bdee21c077e 100644 --- a/trunk/arch/s390/include/asm/swab.h +++ b/trunk/arch/s390/include/asm/swab.h @@ -77,7 +77,7 @@ static inline __u16 __arch_swab16p(const __u16 *x) asm volatile( #ifndef __s390x__ - " icm %0,2,%O1+1(%R1)\n" + " icm %0,2,%O+1(%R1)\n" " ic %0,%1\n" : "=&d" (result) : "Q" (*x) : "cc"); #else /* __s390x__ */ diff --git a/trunk/arch/s390/include/asm/tlb.h b/trunk/arch/s390/include/asm/tlb.h index 775a5eea8f9e..c687a2c83462 100644 --- a/trunk/arch/s390/include/asm/tlb.h +++ b/trunk/arch/s390/include/asm/tlb.h @@ -30,10 +30,14 @@ struct mmu_gather { struct mm_struct *mm; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE struct mmu_table_batch *batch; +#endif unsigned int fullmm; + unsigned int need_flush; }; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE struct mmu_table_batch { struct rcu_head rcu; unsigned int nr; @@ -45,6 +49,7 @@ struct mmu_table_batch { extern void tlb_table_flush(struct mmu_gather *tlb); extern void tlb_remove_table(struct mmu_gather *tlb, void *table); +#endif static inline void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, @@ -52,20 +57,29 @@ static inline void tlb_gather_mmu(struct mmu_gather *tlb, { tlb->mm = mm; tlb->fullmm = full_mm_flush; + tlb->need_flush = 0; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE tlb->batch = NULL; +#endif if (tlb->fullmm) __tlb_flush_mm(mm); } static inline void tlb_flush_mmu(struct mmu_gather *tlb) { + if (!tlb->need_flush) + return; + tlb->need_flush = 0; + __tlb_flush_mm(tlb->mm); +#ifdef CONFIG_HAVE_RCU_TABLE_FREE tlb_table_flush(tlb); +#endif } static inline void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) { - tlb_table_flush(tlb); + tlb_flush_mmu(tlb); } /* @@ -91,8 +105,10 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long address) { +#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return page_table_free_rcu(tlb, (unsigned long *) pte); +#endif page_table_free(tlb->mm, (unsigned long *) pte); } @@ -109,8 +125,10 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, #ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 31)) return; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return tlb_remove_table(tlb, pmd); +#endif crst_table_free(tlb->mm, (unsigned long *) pmd); #endif } @@ -128,8 +146,10 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud, #ifdef __s390x__ if (tlb->mm->context.asce_limit <= (1UL << 42)) return; +#ifdef CONFIG_HAVE_RCU_TABLE_FREE if (!tlb->fullmm) return tlb_remove_table(tlb, pud); +#endif crst_table_free(tlb->mm, (unsigned long *) pud); #endif } diff --git a/trunk/arch/s390/kernel/head.S b/trunk/arch/s390/kernel/head.S index adccd908ebc7..c27a0727f930 100644 --- a/trunk/arch/s390/kernel/head.S +++ b/trunk/arch/s390/kernel/head.S @@ -474,9 +474,9 @@ ENTRY(startup_kdump) stck __LC_LAST_UPDATE_CLOCK spt 5f-.LPG0(%r13) mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13) - xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST #ifndef CONFIG_MARCH_G5 # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10} + xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST .insn s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list tm __LC_STFL_FAC_LIST,0x01 # stfle available ? jz 0f diff --git a/trunk/arch/s390/kernel/irq.c b/trunk/arch/s390/kernel/irq.c index 8a22c27219dd..1c2cdd59ccd0 100644 --- a/trunk/arch/s390/kernel/irq.c +++ b/trunk/arch/s390/kernel/irq.c @@ -118,10 +118,9 @@ asmlinkage void do_softirq(void) "a" (__do_softirq) : "0", "1", "2", "3", "4", "5", "14", "cc", "memory" ); - } else { + } else /* We are already on the async stack. */ __do_softirq(); - } } local_irq_restore(flags); @@ -193,12 +192,11 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler) int index = ext_hash(code); spin_lock_irqsave(&ext_int_hash_lock, flags); - list_for_each_entry_rcu(p, &ext_int_hash[index], entry) { + list_for_each_entry_rcu(p, &ext_int_hash[index], entry) if (p->code == code && p->handler == handler) { list_del_rcu(&p->entry); kfree_rcu(p, rcu); } - } spin_unlock_irqrestore(&ext_int_hash_lock, flags); return 0; } @@ -213,10 +211,9 @@ void __irq_entry do_extint(struct pt_regs *regs, struct ext_code ext_code, old_regs = set_irq_regs(regs); irq_enter(); - if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) { + if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator) /* Serve timer interrupts first. */ clock_comparator_work(); - } kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; if (ext_code.code != 0x1004) __get_cpu_var(s390_idle).nohz_delay = 1; diff --git a/trunk/arch/s390/kernel/perf_cpum_cf.c b/trunk/arch/s390/kernel/perf_cpum_cf.c index cb019f429e88..46405086479c 100644 --- a/trunk/arch/s390/kernel/perf_cpum_cf.c +++ b/trunk/arch/s390/kernel/perf_cpum_cf.c @@ -178,7 +178,7 @@ static void cpumf_pmu_enable(struct pmu *pmu) err = lcctl(cpuhw->state); if (err) { pr_err("Enabling the performance measuring unit " - "failed with rc=%x\n", err); + "failed with rc=%lx\n", err); return; } @@ -203,7 +203,7 @@ static void cpumf_pmu_disable(struct pmu *pmu) err = lcctl(inactive); if (err) { pr_err("Disabling the performance measuring unit " - "failed with rc=%x\n", err); + "failed with rc=%lx\n", err); return; } diff --git a/trunk/arch/s390/mm/maccess.c b/trunk/arch/s390/mm/maccess.c index e1335dc2b1b7..7bb15fcca75e 100644 --- a/trunk/arch/s390/mm/maccess.c +++ b/trunk/arch/s390/mm/maccess.c @@ -61,14 +61,21 @@ long probe_kernel_write(void *dst, const void *src, size_t size) return copied < 0 ? -EFAULT : 0; } -static int __memcpy_real(void *dest, void *src, size_t count) +/* + * Copy memory in real mode (kernel to kernel) + */ +int memcpy_real(void *dest, void *src, size_t count) { register unsigned long _dest asm("2") = (unsigned long) dest; register unsigned long _len1 asm("3") = (unsigned long) count; register unsigned long _src asm("4") = (unsigned long) src; register unsigned long _len2 asm("5") = (unsigned long) count; + unsigned long flags; int rc = -EFAULT; + if (!count) + return 0; + flags = __arch_local_irq_stnsm(0xf8UL); asm volatile ( "0: mvcle %1,%2,0x0\n" "1: jo 0b\n" @@ -79,23 +86,7 @@ static int __memcpy_real(void *dest, void *src, size_t count) "+d" (_len2), "=m" (*((long *) dest)) : "m" (*((long *) src)) : "cc", "memory"); - return rc; -} - -/* - * Copy memory in real mode (kernel to kernel) - */ -int memcpy_real(void *dest, void *src, size_t count) -{ - unsigned long flags; - int rc; - - if (!count) - return 0; - local_irq_save(flags); - __arch_local_irq_stnsm(0xfbUL); - rc = __memcpy_real(dest, src, count); - local_irq_restore(flags); + arch_local_irq_restore(flags); return rc; } diff --git a/trunk/arch/s390/mm/pgtable.c b/trunk/arch/s390/mm/pgtable.c index 6e765bf00670..373adf69b01c 100644 --- a/trunk/arch/s390/mm/pgtable.c +++ b/trunk/arch/s390/mm/pgtable.c @@ -678,6 +678,8 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) } } +#ifdef CONFIG_HAVE_RCU_TABLE_FREE + static void __page_table_free_rcu(void *table, unsigned bit) { struct page *page; @@ -731,66 +733,7 @@ void __tlb_remove_table(void *_table) free_pages((unsigned long) table, ALLOC_ORDER); } -static void tlb_remove_table_smp_sync(void *arg) -{ - /* Simply deliver the interrupt */ -} - -static void tlb_remove_table_one(void *table) -{ - /* - * This isn't an RCU grace period and hence the page-tables cannot be - * assumed to be actually RCU-freed. - * - * It is however sufficient for software page-table walkers that rely - * on IRQ disabling. See the comment near struct mmu_table_batch. - */ - smp_call_function(tlb_remove_table_smp_sync, NULL, 1); - __tlb_remove_table(table); -} - -static void tlb_remove_table_rcu(struct rcu_head *head) -{ - struct mmu_table_batch *batch; - int i; - - batch = container_of(head, struct mmu_table_batch, rcu); - - for (i = 0; i < batch->nr; i++) - __tlb_remove_table(batch->tables[i]); - - free_page((unsigned long)batch); -} - -void tlb_table_flush(struct mmu_gather *tlb) -{ - struct mmu_table_batch **batch = &tlb->batch; - - if (*batch) { - __tlb_flush_mm(tlb->mm); - call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu); - *batch = NULL; - } -} - -void tlb_remove_table(struct mmu_gather *tlb, void *table) -{ - struct mmu_table_batch **batch = &tlb->batch; - - if (*batch == NULL) { - *batch = (struct mmu_table_batch *) - __get_free_page(GFP_NOWAIT | __GFP_NOWARN); - if (*batch == NULL) { - __tlb_flush_mm(tlb->mm); - tlb_remove_table_one(table); - return; - } - (*batch)->nr = 0; - } - (*batch)->tables[(*batch)->nr++] = table; - if ((*batch)->nr == MAX_TABLE_BATCH) - tlb_table_flush(tlb); -} +#endif /* * switch on pgstes for its userspace process (for kvm) diff --git a/trunk/arch/sh/include/asm/atomic.h b/trunk/arch/sh/include/asm/atomic.h index f4c1c20bcdf6..37f2f4a55231 100644 --- a/trunk/arch/sh/include/asm/atomic.h +++ b/trunk/arch/sh/include/asm/atomic.h @@ -11,7 +11,7 @@ #include #include -#define ATOMIC_INIT(i) { (i) } +#define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) #define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic_set(v,i) ((v)->counter = (i)) diff --git a/trunk/arch/sh/mm/fault_32.c b/trunk/arch/sh/mm/fault_32.c index e99b104d967a..324eef93c900 100644 --- a/trunk/arch/sh/mm/fault_32.c +++ b/trunk/arch/sh/mm/fault_32.c @@ -86,7 +86,7 @@ static noinline int vmalloc_fault(unsigned long address) pte_t *pte_k; /* Make sure we are in vmalloc/module/P3 area: */ - if (!(address >= P3SEG && address < P3_ADDR_MAX)) + if (!(address >= VMALLOC_START && address < P3_ADDR_MAX)) return -1; /* diff --git a/trunk/arch/sparc/kernel/leon_smp.c b/trunk/arch/sparc/kernel/leon_smp.c index 160cac9c4036..1210fde18740 100644 --- a/trunk/arch/sparc/kernel/leon_smp.c +++ b/trunk/arch/sparc/kernel/leon_smp.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -79,8 +78,6 @@ void __cpuinit leon_callin(void) local_flush_tlb_all(); leon_configure_cache_smp(); - notify_cpu_starting(cpuid); - /* Get our local ticker going. */ smp_setup_percpu_timer(); diff --git a/trunk/arch/sparc/kernel/sys_sparc_64.c b/trunk/arch/sparc/kernel/sys_sparc_64.c index 3ee51f189a55..232df9949530 100644 --- a/trunk/arch/sparc/kernel/sys_sparc_64.c +++ b/trunk/arch/sparc/kernel/sys_sparc_64.c @@ -566,10 +566,15 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, SYSCALL_DEFINE2(64_munmap, unsigned long, addr, size_t, len) { + long ret; + if (invalid_64bit_range(addr, len)) return -EINVAL; - return vm_munmap(addr, len); + down_write(¤t->mm->mmap_sem); + ret = do_munmap(current->mm, addr, len); + up_write(¤t->mm->mmap_sem); + return ret; } extern unsigned long do_mremap(unsigned long addr, diff --git a/trunk/arch/tile/include/asm/pci.h b/trunk/arch/tile/include/asm/pci.h index 32e6cbe8dff3..5d5a635530bd 100644 --- a/trunk/arch/tile/include/asm/pci.h +++ b/trunk/arch/tile/include/asm/pci.h @@ -47,8 +47,8 @@ struct pci_controller { */ #define PCI_DMA_BUS_IS_PHYS 1 -int __init tile_pci_init(void); -int __init pcibios_init(void); +int __devinit tile_pci_init(void); +int __devinit pcibios_init(void); static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} diff --git a/trunk/arch/tile/kernel/pci.c b/trunk/arch/tile/kernel/pci.c index b56d12bf5900..a1bb59eecc18 100644 --- a/trunk/arch/tile/kernel/pci.c +++ b/trunk/arch/tile/kernel/pci.c @@ -141,7 +141,7 @@ static int __devinit tile_init_irqs(int controller_id, * * Returns the number of controllers discovered. */ -int __init tile_pci_init(void) +int __devinit tile_pci_init(void) { int i; @@ -287,7 +287,7 @@ static void __devinit fixup_read_and_payload_sizes(void) * The controllers have been set up by the time we get here, by a call to * tile_pci_init. */ -int __init pcibios_init(void) +int __devinit pcibios_init(void) { int i; diff --git a/trunk/arch/tile/kernel/single_step.c b/trunk/arch/tile/kernel/single_step.c index 89529c9f0605..9efbc1391b3c 100644 --- a/trunk/arch/tile/kernel/single_step.c +++ b/trunk/arch/tile/kernel/single_step.c @@ -346,10 +346,12 @@ void single_step_once(struct pt_regs *regs) } /* allocate a cache line of writable, executable memory */ - buffer = (void __user *) vm_mmap(NULL, 0, 64, + down_write(¤t->mm->mmap_sem); + buffer = (void __user *) do_mmap(NULL, 0, 64, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0); + up_write(¤t->mm->mmap_sem); if (IS_ERR((void __force *)buffer)) { kfree(state); diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index c9866b0b77d8..1d14cc6b79ad 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -81,7 +81,7 @@ config X86 select CLKEVT_I8253 select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_IOMAP - select DCACHE_WORD_ACCESS + select DCACHE_WORD_ACCESS if !DEBUG_PAGEALLOC config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS) diff --git a/trunk/arch/x86/boot/compressed/head_32.S b/trunk/arch/x86/boot/compressed/head_32.S index c85e3ac99bba..a0559930a180 100644 --- a/trunk/arch/x86/boot/compressed/head_32.S +++ b/trunk/arch/x86/boot/compressed/head_32.S @@ -33,9 +33,6 @@ __HEAD ENTRY(startup_32) #ifdef CONFIG_EFI_STUB - jmp preferred_addr - - .balign 0x10 /* * We don't need the return address, so set up the stack so * efi_main() can find its arugments. @@ -44,17 +41,12 @@ ENTRY(startup_32) call efi_main cmpl $0, %eax + je preferred_addr movl %eax, %esi - jne 2f + call 1f 1: - /* EFI init failed, so hang. */ - hlt - jmp 1b -2: - call 3f -3: popl %eax - subl $3b, %eax + subl $1b, %eax subl BP_pref_address(%esi), %eax add BP_code32_start(%esi), %eax leal preferred_addr(%eax), %eax diff --git a/trunk/arch/x86/boot/compressed/head_64.S b/trunk/arch/x86/boot/compressed/head_64.S index 87e03a13d8e3..558d76ce23bc 100644 --- a/trunk/arch/x86/boot/compressed/head_64.S +++ b/trunk/arch/x86/boot/compressed/head_64.S @@ -200,28 +200,18 @@ ENTRY(startup_64) * entire text+data+bss and hopefully all of memory. */ #ifdef CONFIG_EFI_STUB - /* - * The entry point for the PE/COFF executable is 0x210, so only - * legacy boot loaders will execute this jmp. - */ - jmp preferred_addr - - .org 0x210 + pushq %rsi mov %rcx, %rdi mov %rdx, %rsi call efi_main - movq %rax,%rsi + popq %rsi cmpq $0,%rax - jne 2f + je preferred_addr + movq %rax,%rsi + call 1f 1: - /* EFI init failed, so hang. */ - hlt - jmp 1b -2: - call 3f -3: popq %rax - subq $3b, %rax + subq $1b, %rax subq BP_pref_address(%rsi), %rax add BP_code32_start(%esi), %eax leaq preferred_addr(%rax), %rax diff --git a/trunk/arch/x86/boot/compressed/relocs.c b/trunk/arch/x86/boot/compressed/relocs.c index fb7117a4ade1..d3c0b0277666 100644 --- a/trunk/arch/x86/boot/compressed/relocs.c +++ b/trunk/arch/x86/boot/compressed/relocs.c @@ -403,11 +403,13 @@ static void print_absolute_symbols(void) for (i = 0; i < ehdr.e_shnum; i++) { struct section *sec = &secs[i]; char *sym_strtab; + Elf32_Sym *sh_symtab; int j; if (sec->shdr.sh_type != SHT_SYMTAB) { continue; } + sh_symtab = sec->symtab; sym_strtab = sec->link->strtab; for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Sym); j++) { Elf32_Sym *sym; diff --git a/trunk/arch/x86/boot/tools/build.c b/trunk/arch/x86/boot/tools/build.c index 24443a332083..ed549767a231 100644 --- a/trunk/arch/x86/boot/tools/build.c +++ b/trunk/arch/x86/boot/tools/build.c @@ -205,13 +205,8 @@ int main(int argc, char ** argv) put_unaligned_le32(file_sz, &buf[pe_header + 0x50]); #ifdef CONFIG_X86_32 - /* - * Address of entry point. - * - * The EFI stub entry point is +16 bytes from the start of - * the .text section. - */ - put_unaligned_le32(i + 16, &buf[pe_header + 0x28]); + /* Address of entry point */ + put_unaligned_le32(i, &buf[pe_header + 0x28]); /* .text size */ put_unaligned_le32(file_sz, &buf[pe_header + 0xb0]); @@ -222,11 +217,9 @@ int main(int argc, char ** argv) /* * Address of entry point. startup_32 is at the beginning and * the 64-bit entry point (startup_64) is always 512 bytes - * after. The EFI stub entry point is 16 bytes after that, as - * the first instruction allows legacy loaders to jump over - * the EFI stub initialisation + * after. */ - put_unaligned_le32(i + 528, &buf[pe_header + 0x28]); + put_unaligned_le32(i + 512, &buf[pe_header + 0x28]); /* .text size */ put_unaligned_le32(file_sz, &buf[pe_header + 0xc0]); diff --git a/trunk/arch/x86/ia32/ia32_aout.c b/trunk/arch/x86/ia32/ia32_aout.c index 07b3a68d2d29..d511d951a052 100644 --- a/trunk/arch/x86/ia32/ia32_aout.c +++ b/trunk/arch/x86/ia32/ia32_aout.c @@ -119,7 +119,9 @@ static void set_brk(unsigned long start, unsigned long end) end = PAGE_ALIGN(end); if (end <= start) return; - vm_brk(start, end - start); + down_write(¤t->mm->mmap_sem); + do_brk(start, end - start); + up_write(¤t->mm->mmap_sem); } #ifdef CORE_DUMP @@ -294,7 +296,8 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) /* OK, This is the point of no return */ set_personality(PER_LINUX); - set_personality_ia32(false); + set_thread_flag(TIF_IA32); + current->mm->context.ia32_compat = 1; setup_new_exec(bprm); @@ -329,7 +332,9 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) pos = 32; map_size = ex.a_text+ex.a_data; - error = vm_brk(text_addr & PAGE_MASK, map_size); + down_write(¤t->mm->mmap_sem); + error = do_brk(text_addr & PAGE_MASK, map_size); + up_write(¤t->mm->mmap_sem); if (error != (text_addr & PAGE_MASK)) { send_sig(SIGKILL, current, 0); @@ -368,7 +373,9 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) { loff_t pos = fd_offset; - vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + down_write(¤t->mm->mmap_sem); + do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + up_write(¤t->mm->mmap_sem); bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); @@ -378,22 +385,26 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) goto beyond_if; } - error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE | MAP_32BIT, fd_offset); + up_write(¤t->mm->mmap_sem); if (error != N_TXTADDR(ex)) { send_sig(SIGKILL, current, 0); return error; } - error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE | MAP_32BIT, fd_offset + ex.a_text); + up_write(¤t->mm->mmap_sem); if (error != N_DATADDR(ex)) { send_sig(SIGKILL, current, 0); return error; @@ -465,7 +476,9 @@ static int load_aout_library(struct file *file) error_time = jiffies; } #endif - vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + down_write(¤t->mm->mmap_sem); + do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + up_write(¤t->mm->mmap_sem); file->f_op->read(file, (char __user *)start_addr, ex.a_text + ex.a_data, &pos); @@ -477,10 +490,12 @@ static int load_aout_library(struct file *file) goto out; } /* Now use mmap to map the library into memory. */ - error = vm_mmap(file, start_addr, ex.a_text + ex.a_data, + down_write(¤t->mm->mmap_sem); + error = do_mmap(file, start_addr, ex.a_text + ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT, N_TXTOFF(ex)); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr) goto out; @@ -488,7 +503,9 @@ static int load_aout_library(struct file *file) len = PAGE_ALIGN(ex.a_text + ex.a_data); bss = ex.a_text + ex.a_data + ex.a_bss; if (bss > len) { - error = vm_brk(start_addr + len, bss - len); + down_write(¤t->mm->mmap_sem); + error = do_brk(start_addr + len, bss - len); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr + len) goto out; diff --git a/trunk/arch/x86/include/asm/posix_types.h b/trunk/arch/x86/include/asm/posix_types.h index 7ef7c3020e5c..3427b7798dbc 100644 --- a/trunk/arch/x86/include/asm/posix_types.h +++ b/trunk/arch/x86/include/asm/posix_types.h @@ -7,9 +7,9 @@ #else # ifdef __i386__ # include "posix_types_32.h" -# elif defined(__ILP32__) -# include "posix_types_x32.h" -# else +# elif defined(__LP64__) # include "posix_types_64.h" +# else +# include "posix_types_x32.h" # endif #endif diff --git a/trunk/arch/x86/include/asm/sigcontext.h b/trunk/arch/x86/include/asm/sigcontext.h index 5ca71c065eef..4a085383af27 100644 --- a/trunk/arch/x86/include/asm/sigcontext.h +++ b/trunk/arch/x86/include/asm/sigcontext.h @@ -257,7 +257,7 @@ struct sigcontext { __u64 oldmask; __u64 cr2; struct _fpstate __user *fpstate; /* zero when no FPU context */ -#ifdef __ILP32__ +#ifndef __LP64__ __u32 __fpstate_pad; #endif __u64 reserved1[8]; diff --git a/trunk/arch/x86/include/asm/siginfo.h b/trunk/arch/x86/include/asm/siginfo.h index 34c47b3341c0..fc1aa5535646 100644 --- a/trunk/arch/x86/include/asm/siginfo.h +++ b/trunk/arch/x86/include/asm/siginfo.h @@ -2,13 +2,7 @@ #define _ASM_X86_SIGINFO_H #ifdef __x86_64__ -# ifdef __ILP32__ /* x32 */ -typedef long long __kernel_si_clock_t __attribute__((aligned(4))); -# define __ARCH_SI_CLOCK_T __kernel_si_clock_t -# define __ARCH_SI_ATTRIBUTES __attribute__((aligned(8))) -# else /* x86-64 */ -# define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) -# endif +# define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) #endif #include diff --git a/trunk/arch/x86/include/asm/unistd.h b/trunk/arch/x86/include/asm/unistd.h index 4437001d8e3d..37cdc9d99bb1 100644 --- a/trunk/arch/x86/include/asm/unistd.h +++ b/trunk/arch/x86/include/asm/unistd.h @@ -63,10 +63,10 @@ #else # ifdef __i386__ # include -# elif defined(__ILP32__) -# include -# else +# elif defined(__LP64__) # include +# else +# include # endif #endif diff --git a/trunk/arch/x86/include/asm/word-at-a-time.h b/trunk/arch/x86/include/asm/word-at-a-time.h index e58f03b206c3..6fe6767b7124 100644 --- a/trunk/arch/x86/include/asm/word-at-a-time.h +++ b/trunk/arch/x86/include/asm/word-at-a-time.h @@ -43,37 +43,4 @@ static inline unsigned long has_zero(unsigned long a) return ((a - REPEAT_BYTE(0x01)) & ~a) & REPEAT_BYTE(0x80); } -/* - * Load an unaligned word from kernel space. - * - * In the (very unlikely) case of the word being a page-crosser - * and the next page not being mapped, take the exception and - * return zeroes in the non-existing part. - */ -static inline unsigned long load_unaligned_zeropad(const void *addr) -{ - unsigned long ret, dummy; - - asm( - "1:\tmov %2,%0\n" - "2:\n" - ".section .fixup,\"ax\"\n" - "3:\t" - "lea %2,%1\n\t" - "and %3,%1\n\t" - "mov (%1),%0\n\t" - "leal %2,%%ecx\n\t" - "andl %4,%%ecx\n\t" - "shll $3,%%ecx\n\t" - "shr %%cl,%0\n\t" - "jmp 2b\n" - ".previous\n" - _ASM_EXTABLE(1b, 3b) - :"=&r" (ret),"=&c" (dummy) - :"m" (*(unsigned long *)addr), - "i" (-sizeof(unsigned long)), - "i" (sizeof(unsigned long)-1)); - return ret; -} - #endif /* _ASM_WORD_AT_A_TIME_H */ diff --git a/trunk/arch/x86/include/asm/x86_init.h b/trunk/arch/x86/include/asm/x86_init.h index 764b66a4cf89..baaca8defec8 100644 --- a/trunk/arch/x86/include/asm/x86_init.h +++ b/trunk/arch/x86/include/asm/x86_init.h @@ -195,5 +195,6 @@ extern struct x86_msi_ops x86_msi; extern void x86_init_noop(void); extern void x86_init_uint_noop(unsigned int unused); +extern void x86_default_fixup_cpu_id(struct cpuinfo_x86 *c, int node); #endif diff --git a/trunk/arch/x86/kernel/acpi/sleep.c b/trunk/arch/x86/kernel/acpi/sleep.c index 146a49c763a4..103b6ab368d3 100644 --- a/trunk/arch/x86/kernel/acpi/sleep.c +++ b/trunk/arch/x86/kernel/acpi/sleep.c @@ -24,10 +24,6 @@ unsigned long acpi_realmode_flags; static char temp_stack[4096]; #endif -asmlinkage void acpi_enter_s3(void) -{ - acpi_enter_sleep_state(3, wake_sleep_flags); -} /** * acpi_suspend_lowlevel - save kernel state * diff --git a/trunk/arch/x86/kernel/acpi/sleep.h b/trunk/arch/x86/kernel/acpi/sleep.h index d68677a2a010..416d4be13fef 100644 --- a/trunk/arch/x86/kernel/acpi/sleep.h +++ b/trunk/arch/x86/kernel/acpi/sleep.h @@ -3,16 +3,12 @@ */ #include -#include extern unsigned long saved_video_mode; extern long saved_magic; extern int wakeup_pmode_return; -extern u8 wake_sleep_flags; -extern asmlinkage void acpi_enter_s3(void); - extern unsigned long acpi_copy_wakeup_routine(unsigned long); extern void wakeup_long64(void); diff --git a/trunk/arch/x86/kernel/acpi/wakeup_32.S b/trunk/arch/x86/kernel/acpi/wakeup_32.S index 72610839f03b..13ab720573e3 100644 --- a/trunk/arch/x86/kernel/acpi/wakeup_32.S +++ b/trunk/arch/x86/kernel/acpi/wakeup_32.S @@ -74,7 +74,9 @@ restore_registers: ENTRY(do_suspend_lowlevel) call save_processor_state call save_registers - call acpi_enter_s3 + pushl $3 + call acpi_enter_sleep_state + addl $4, %esp # In case of S3 failure, we'll emerge here. Jump # to ret_point to recover diff --git a/trunk/arch/x86/kernel/acpi/wakeup_64.S b/trunk/arch/x86/kernel/acpi/wakeup_64.S index 014d1d28c397..8ea5164cbd04 100644 --- a/trunk/arch/x86/kernel/acpi/wakeup_64.S +++ b/trunk/arch/x86/kernel/acpi/wakeup_64.S @@ -71,7 +71,9 @@ ENTRY(do_suspend_lowlevel) movq %rsi, saved_rsi addq $8, %rsp - call acpi_enter_s3 + movl $3, %edi + xorl %eax, %eax + call acpi_enter_sleep_state /* in case something went wrong, restore the machine status and go on */ jmp resume_point diff --git a/trunk/arch/x86/kernel/apic/apic.c b/trunk/arch/x86/kernel/apic/apic.c index edc24480469f..11544d8f1e97 100644 --- a/trunk/arch/x86/kernel/apic/apic.c +++ b/trunk/arch/x86/kernel/apic/apic.c @@ -1637,11 +1637,9 @@ static int __init apic_verify(void) mp_lapic_addr = APIC_DEFAULT_PHYS_BASE; /* The BIOS may have set up the APIC at some other address */ - if (boot_cpu_data.x86 >= 6) { - rdmsr(MSR_IA32_APICBASE, l, h); - if (l & MSR_IA32_APICBASE_ENABLE) - mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; - } + rdmsr(MSR_IA32_APICBASE, l, h); + if (l & MSR_IA32_APICBASE_ENABLE) + mp_lapic_addr = l & MSR_IA32_APICBASE_BASE; pr_info("Found and enabled local APIC!\n"); return 0; @@ -1659,15 +1657,13 @@ int __init apic_force_enable(unsigned long addr) * MSR. This can only be done in software for Intel P6 or later * and AMD K7 (Model > 1) or later. */ - if (boot_cpu_data.x86 >= 6) { - rdmsr(MSR_IA32_APICBASE, l, h); - if (!(l & MSR_IA32_APICBASE_ENABLE)) { - pr_info("Local APIC disabled by BIOS -- reenabling.\n"); - l &= ~MSR_IA32_APICBASE_BASE; - l |= MSR_IA32_APICBASE_ENABLE | addr; - wrmsr(MSR_IA32_APICBASE, l, h); - enabled_via_apicbase = 1; - } + rdmsr(MSR_IA32_APICBASE, l, h); + if (!(l & MSR_IA32_APICBASE_ENABLE)) { + pr_info("Local APIC disabled by BIOS -- reenabling.\n"); + l &= ~MSR_IA32_APICBASE_BASE; + l |= MSR_IA32_APICBASE_ENABLE | addr; + wrmsr(MSR_IA32_APICBASE, l, h); + enabled_via_apicbase = 1; } return apic_verify(); } @@ -2213,12 +2209,10 @@ static void lapic_resume(void) * FIXME! This will be wrong if we ever support suspend on * SMP! We'll need to do this as part of the CPU restore! */ - if (boot_cpu_data.x86 >= 6) { - rdmsr(MSR_IA32_APICBASE, l, h); - l &= ~MSR_IA32_APICBASE_BASE; - l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; - wrmsr(MSR_IA32_APICBASE, l, h); - } + rdmsr(MSR_IA32_APICBASE, l, h); + l &= ~MSR_IA32_APICBASE_BASE; + l |= MSR_IA32_APICBASE_ENABLE | mp_lapic_addr; + wrmsr(MSR_IA32_APICBASE, l, h); } maxlvt = lapic_get_maxlvt(); diff --git a/trunk/arch/x86/kernel/apic/apic_numachip.c b/trunk/arch/x86/kernel/apic/apic_numachip.c index 23e75422e013..899803e03214 100644 --- a/trunk/arch/x86/kernel/apic/apic_numachip.c +++ b/trunk/arch/x86/kernel/apic/apic_numachip.c @@ -207,11 +207,8 @@ static void __init map_csrs(void) static void fixup_cpu_id(struct cpuinfo_x86 *c, int node) { - - if (c->phys_proc_id != node) { - c->phys_proc_id = node; - per_cpu(cpu_llc_id, smp_processor_id()) = node; - } + c->phys_proc_id = node; + per_cpu(cpu_llc_id, smp_processor_id()) = node; } static int __init numachip_system_init(void) diff --git a/trunk/arch/x86/kernel/apic/x2apic_phys.c b/trunk/arch/x86/kernel/apic/x2apic_phys.c index 991e315f4227..8a778db45e3a 100644 --- a/trunk/arch/x86/kernel/apic/x2apic_phys.c +++ b/trunk/arch/x86/kernel/apic/x2apic_phys.c @@ -24,12 +24,6 @@ static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id) { if (x2apic_phys) return x2apic_enabled(); - else if ((acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) && - (acpi_gbl_FADT.flags & ACPI_FADT_APIC_PHYSICAL) && - x2apic_enabled()) { - printk(KERN_DEBUG "System requires x2apic physical mode\n"); - return 1; - } else return 0; } diff --git a/trunk/arch/x86/kernel/cpu/amd.c b/trunk/arch/x86/kernel/cpu/amd.c index 146bb6218eec..0a44b90602b0 100644 --- a/trunk/arch/x86/kernel/cpu/amd.c +++ b/trunk/arch/x86/kernel/cpu/amd.c @@ -26,8 +26,7 @@ * contact AMD for precise details and a CPU swap. * * See http://www.multimania.com/poulot/k6bug.html - * and section 2.6.2 of "AMD-K6 Processor Revision Guide - Model 6" - * (Publication # 21266 Issue Date: August 1998) + * http://www.amd.com/K6/k6docs/revgd.html * * The following test is erm.. interesting. AMD neglected to up * the chip setting when fixing the bug but they also tweaked some @@ -95,6 +94,7 @@ static void __cpuinit init_amd_k6(struct cpuinfo_x86 *c) "system stability may be impaired when more than 32 MB are used.\n"); else printk(KERN_CONT "probably OK (after B9730xxxx).\n"); + printk(KERN_INFO "Please see http://membres.lycos.fr/poulot/k6bug.html\n"); } /* K6 with old style WHCR */ @@ -353,11 +353,10 @@ static void __cpuinit srat_detect_node(struct cpuinfo_x86 *c) node = per_cpu(cpu_llc_id, cpu); /* - * On multi-fabric platform (e.g. Numascale NumaChip) a - * platform-specific handler needs to be called to fixup some - * IDs of the CPU. + * If core numbers are inconsistent, it's likely a multi-fabric platform, + * so invoke platform-specific handler */ - if (x86_cpuinit.fixup_cpu_id) + if (c->phys_proc_id != node) x86_cpuinit.fixup_cpu_id(c, node); if (!node_online(node)) { @@ -580,24 +579,6 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) } } - /* re-enable TopologyExtensions if switched off by BIOS */ - if ((c->x86 == 0x15) && - (c->x86_model >= 0x10) && (c->x86_model <= 0x1f) && - !cpu_has(c, X86_FEATURE_TOPOEXT)) { - u64 val; - - if (!rdmsrl_amd_safe(0xc0011005, &val)) { - val |= 1ULL << 54; - wrmsrl_amd_safe(0xc0011005, val); - rdmsrl(0xc0011005, val); - if (val & (1ULL << 54)) { - set_cpu_cap(c, X86_FEATURE_TOPOEXT); - printk(KERN_INFO FW_INFO "CPU: Re-enabling " - "disabled Topology Extensions Support\n"); - } - } - } - cpu_detect_cache_sizes(c); /* Multi core CPU? */ diff --git a/trunk/arch/x86/kernel/cpu/common.c b/trunk/arch/x86/kernel/cpu/common.c index cf79302198a6..67e258362a3d 100644 --- a/trunk/arch/x86/kernel/cpu/common.c +++ b/trunk/arch/x86/kernel/cpu/common.c @@ -1162,6 +1162,15 @@ static void dbg_restore_debug_regs(void) #define dbg_restore_debug_regs() #endif /* ! CONFIG_KGDB */ +/* + * Prints an error where the NUMA and configured core-number mismatch and the + * platform didn't override this to fix it up + */ +void __cpuinit x86_default_fixup_cpu_id(struct cpuinfo_x86 *c, int node) +{ + pr_err("NUMA core number %d differs from configured core number %d\n", node, c->phys_proc_id); +} + /* * cpu_init() initializes state that is per-CPU. Some data is already * initialized (naturally) in the bootstrap process, such as the GDT diff --git a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c index b8f3653dddbc..73d08ed98a64 100644 --- a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -433,14 +433,14 @@ int amd_set_l3_disable_slot(struct amd_northbridge *nb, int cpu, unsigned slot, /* check if @slot is already used or the index is already disabled */ ret = amd_get_l3_disable_slot(nb, slot); if (ret >= 0) - return -EEXIST; + return -EINVAL; if (index > nb->l3_cache.indices) return -EINVAL; /* check whether the other slot has disabled the same index already */ if (index == amd_get_l3_disable_slot(nb, !slot)) - return -EEXIST; + return -EINVAL; amd_l3_disable_index(nb, cpu, slot, index); @@ -468,8 +468,8 @@ static ssize_t store_cache_disable(struct _cpuid4_info *this_leaf, err = amd_set_l3_disable_slot(this_leaf->base.nb, cpu, slot, val); if (err) { if (err == -EEXIST) - pr_warning("L3 slot %d in use/index already disabled!\n", - slot); + printk(KERN_WARNING "L3 disable slot %d in use!\n", + slot); return err; } return count; diff --git a/trunk/arch/x86/kernel/i387.c b/trunk/arch/x86/kernel/i387.c index 2d6e6498c176..7734bcbb5a3a 100644 --- a/trunk/arch/x86/kernel/i387.c +++ b/trunk/arch/x86/kernel/i387.c @@ -235,7 +235,6 @@ int init_fpu(struct task_struct *tsk) if (tsk_used_math(tsk)) { if (HAVE_HWFP && tsk == current) unlazy_fpu(tsk); - tsk->thread.fpu.last_cpu = ~0; return 0; } diff --git a/trunk/arch/x86/kernel/microcode_amd.c b/trunk/arch/x86/kernel/microcode_amd.c index 8a2ce8fd41c0..73465aab28f8 100644 --- a/trunk/arch/x86/kernel/microcode_amd.c +++ b/trunk/arch/x86/kernel/microcode_amd.c @@ -82,6 +82,11 @@ static int collect_cpu_info_amd(int cpu, struct cpu_signature *csig) { struct cpuinfo_x86 *c = &cpu_data(cpu); + if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { + pr_warning("CPU%d: family %d not supported\n", cpu, c->x86); + return -1; + } + csig->rev = c->microcode; pr_info("CPU%d: patch_level=0x%08x\n", cpu, csig->rev); @@ -375,13 +380,6 @@ static struct microcode_ops microcode_amd_ops = { struct microcode_ops * __init init_amd_microcode(void) { - struct cpuinfo_x86 *c = &cpu_data(0); - - if (c->x86_vendor != X86_VENDOR_AMD || c->x86 < 0x10) { - pr_warning("AMD CPU family 0x%x not supported\n", c->x86); - return NULL; - } - patch = (void *)get_zeroed_page(GFP_KERNEL); if (!patch) return NULL; diff --git a/trunk/arch/x86/kernel/microcode_core.c b/trunk/arch/x86/kernel/microcode_core.c index c9bda6d6035c..87a0f8688301 100644 --- a/trunk/arch/x86/kernel/microcode_core.c +++ b/trunk/arch/x86/kernel/microcode_core.c @@ -419,8 +419,10 @@ static int mc_device_add(struct device *dev, struct subsys_interface *sif) if (err) return err; - if (microcode_init_cpu(cpu) == UCODE_ERROR) + if (microcode_init_cpu(cpu) == UCODE_ERROR) { + sysfs_remove_group(&dev->kobj, &mc_attr_group); return -EINVAL; + } return err; } @@ -526,11 +528,11 @@ static int __init microcode_init(void) microcode_ops = init_intel_microcode(); else if (c->x86_vendor == X86_VENDOR_AMD) microcode_ops = init_amd_microcode(); - else - pr_err("no support for this CPU vendor\n"); - if (!microcode_ops) + if (!microcode_ops) { + pr_err("no support for this CPU vendor\n"); return -ENODEV; + } microcode_pdev = platform_device_register_simple("microcode", -1, NULL, 0); diff --git a/trunk/arch/x86/kernel/x86_init.c b/trunk/arch/x86/kernel/x86_init.c index 9cf71d0b2d37..e9f265fd79ae 100644 --- a/trunk/arch/x86/kernel/x86_init.c +++ b/trunk/arch/x86/kernel/x86_init.c @@ -93,6 +93,7 @@ struct x86_init_ops x86_init __initdata = { struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = { .early_percpu_clock_init = x86_init_noop, .setup_percpu_clockev = setup_secondary_APIC_clock, + .fixup_cpu_id = x86_default_fixup_cpu_id, }; static void default_nmi_init(void) { }; diff --git a/trunk/arch/x86/kvm/pmu.c b/trunk/arch/x86/kvm/pmu.c index 2e88438ffd83..173df38dbda5 100644 --- a/trunk/arch/x86/kvm/pmu.c +++ b/trunk/arch/x86/kvm/pmu.c @@ -459,17 +459,17 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu) pmu->available_event_types = ~entry->ebx & ((1ull << bitmap_len) - 1); if (pmu->version == 1) { - pmu->nr_arch_fixed_counters = 0; - } else { - pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), - X86_PMC_MAX_FIXED); - pmu->counter_bitmask[KVM_PMC_FIXED] = - ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; + pmu->global_ctrl = (1 << pmu->nr_arch_gp_counters) - 1; + return; } - pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) | - (((1ull << pmu->nr_arch_fixed_counters) - 1) << X86_PMC_IDX_FIXED); - pmu->global_ctrl_mask = ~pmu->global_ctrl; + pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), + X86_PMC_MAX_FIXED); + pmu->counter_bitmask[KVM_PMC_FIXED] = + ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; + pmu->global_ctrl_mask = ~(((1 << pmu->nr_arch_gp_counters) - 1) + | (((1ull << pmu->nr_arch_fixed_counters) - 1) + << X86_PMC_IDX_FIXED)); } void kvm_pmu_init(struct kvm_vcpu *vcpu) diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index 4ff0ab9bc3c8..ad85adfef843 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -2210,12 +2210,9 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) msr = find_msr_entry(vmx, msr_index); if (msr) { msr->data = data; - if (msr - vmx->guest_msrs < vmx->save_nmsrs) { - preempt_disable(); + if (msr - vmx->guest_msrs < vmx->save_nmsrs) kvm_set_shared_msr(msr->index, msr->data, msr->mask); - preempt_enable(); - } break; } ret = kvm_set_msr_common(vcpu, msr_index, data); diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 91a5e989abcf..4044ce0bf7c1 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -6336,11 +6336,13 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, if (npages && !old.rmap) { unsigned long userspace_addr; - userspace_addr = vm_mmap(NULL, 0, + down_write(¤t->mm->mmap_sem); + userspace_addr = do_mmap(NULL, 0, npages * PAGE_SIZE, PROT_READ | PROT_WRITE, map_flags, 0); + up_write(¤t->mm->mmap_sem); if (IS_ERR((void *)userspace_addr)) return PTR_ERR((void *)userspace_addr); @@ -6364,8 +6366,10 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, if (!user_alloc && !old.user_alloc && old.rmap && !npages) { int ret; - ret = vm_munmap(old.userspace_addr, + down_write(¤t->mm->mmap_sem); + ret = do_munmap(current->mm, old.userspace_addr, old.npages * PAGE_SIZE); + up_write(¤t->mm->mmap_sem); if (ret < 0) printk(KERN_WARNING "kvm_vm_ioctl_set_memory_region: " diff --git a/trunk/arch/x86/lib/insn.c b/trunk/arch/x86/lib/insn.c index b1e6c4b2e8eb..25feb1ae71c5 100644 --- a/trunk/arch/x86/lib/insn.c +++ b/trunk/arch/x86/lib/insn.c @@ -379,8 +379,8 @@ void insn_get_displacement(struct insn *insn) return; } -/* Decode moffset16/32/64. Return 0 if failed */ -static int __get_moffset(struct insn *insn) +/* Decode moffset16/32/64 */ +static void __get_moffset(struct insn *insn) { switch (insn->addr_bytes) { case 2: @@ -397,19 +397,15 @@ static int __get_moffset(struct insn *insn) insn->moffset2.value = get_next(int, insn); insn->moffset2.nbytes = 4; break; - default: /* opnd_bytes must be modified manually */ - goto err_out; } insn->moffset1.got = insn->moffset2.got = 1; - return 1; - err_out: - return 0; + return; } -/* Decode imm v32(Iz). Return 0 if failed */ -static int __get_immv32(struct insn *insn) +/* Decode imm v32(Iz) */ +static void __get_immv32(struct insn *insn) { switch (insn->opnd_bytes) { case 2: @@ -421,18 +417,14 @@ static int __get_immv32(struct insn *insn) insn->immediate.value = get_next(int, insn); insn->immediate.nbytes = 4; break; - default: /* opnd_bytes must be modified manually */ - goto err_out; } - return 1; - err_out: - return 0; + return; } -/* Decode imm v64(Iv/Ov), Return 0 if failed */ -static int __get_immv(struct insn *insn) +/* Decode imm v64(Iv/Ov) */ +static void __get_immv(struct insn *insn) { switch (insn->opnd_bytes) { case 2: @@ -449,18 +441,15 @@ static int __get_immv(struct insn *insn) insn->immediate2.value = get_next(int, insn); insn->immediate2.nbytes = 4; break; - default: /* opnd_bytes must be modified manually */ - goto err_out; } insn->immediate1.got = insn->immediate2.got = 1; - return 1; err_out: - return 0; + return; } /* Decode ptr16:16/32(Ap) */ -static int __get_immptr(struct insn *insn) +static void __get_immptr(struct insn *insn) { switch (insn->opnd_bytes) { case 2: @@ -473,17 +462,14 @@ static int __get_immptr(struct insn *insn) break; case 8: /* ptr16:64 is not exist (no segment) */ - return 0; - default: /* opnd_bytes must be modified manually */ - goto err_out; + return; } insn->immediate2.value = get_next(unsigned short, insn); insn->immediate2.nbytes = 2; insn->immediate1.got = insn->immediate2.got = 1; - return 1; err_out: - return 0; + return; } /** @@ -503,8 +489,7 @@ void insn_get_immediate(struct insn *insn) insn_get_displacement(insn); if (inat_has_moffset(insn->attr)) { - if (!__get_moffset(insn)) - goto err_out; + __get_moffset(insn); goto done; } @@ -532,20 +517,16 @@ void insn_get_immediate(struct insn *insn) insn->immediate2.nbytes = 4; break; case INAT_IMM_PTR: - if (!__get_immptr(insn)) - goto err_out; + __get_immptr(insn); break; case INAT_IMM_VWORD32: - if (!__get_immv32(insn)) - goto err_out; + __get_immv32(insn); break; case INAT_IMM_VWORD: - if (!__get_immv(insn)) - goto err_out; + __get_immv(insn); break; default: - /* Here, insn must have an immediate, but failed */ - goto err_out; + break; } if (inat_has_second_immediate(insn->attr)) { insn->immediate2.value = get_next(char, insn); diff --git a/trunk/arch/x86/platform/geode/net5501.c b/trunk/arch/x86/platform/geode/net5501.c index 646e3b5b4bb6..66d377e334f7 100644 --- a/trunk/arch/x86/platform/geode/net5501.c +++ b/trunk/arch/x86/platform/geode/net5501.c @@ -63,7 +63,7 @@ static struct gpio_led net5501_leds[] = { .name = "net5501:1", .gpio = 6, .default_trigger = "default-on", - .active_low = 0, + .active_low = 1, }, }; diff --git a/trunk/arch/x86/platform/mrst/mrst.c b/trunk/arch/x86/platform/mrst/mrst.c index e31bcd8f2eee..e0a37233c0af 100644 --- a/trunk/arch/x86/platform/mrst/mrst.c +++ b/trunk/arch/x86/platform/mrst/mrst.c @@ -805,7 +805,7 @@ void intel_scu_devices_create(void) } else i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1); } - intel_scu_notifier_post(SCU_AVAILABLE, NULL); + intel_scu_notifier_post(SCU_AVAILABLE, 0L); } EXPORT_SYMBOL_GPL(intel_scu_devices_create); @@ -814,7 +814,7 @@ void intel_scu_devices_destroy(void) { int i; - intel_scu_notifier_post(SCU_DOWN, NULL); + intel_scu_notifier_post(SCU_DOWN, 0L); for (i = 0; i < ipc_next_dev; i++) platform_device_del(ipc_devs[i]); diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index a8f8844b8d32..4f51bebac02c 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -261,8 +261,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, static bool __init xen_check_mwait(void) { -#if defined(CONFIG_ACPI) && !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) && \ - !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE) +#ifdef CONFIG_ACPI struct xen_platform_op op = { .cmd = XENPF_set_processor_pminfo, .u.set_pminfo.id = -1, @@ -350,6 +349,7 @@ static void __init xen_init_cpuid_mask(void) /* Xen will set CR4.OSXSAVE if supported and not disabled by force */ if ((cx & xsave_mask) != xsave_mask) cpuid_leaf1_ecx_mask &= ~xsave_mask; /* disable XSAVE & OSXSAVE */ + if (xen_check_mwait()) cpuid_leaf1_ecx_set_mask = (1 << (X86_FEATURE_MWAIT % 32)); } diff --git a/trunk/arch/x86/xen/smp.c b/trunk/arch/x86/xen/smp.c index 0503c0c493a9..5fac6919b957 100644 --- a/trunk/arch/x86/xen/smp.c +++ b/trunk/arch/x86/xen/smp.c @@ -178,7 +178,6 @@ static void __init xen_fill_possible_map(void) static void __init xen_filter_cpu_maps(void) { int i, rc; - unsigned int subtract = 0; if (!xen_initial_domain()) return; @@ -193,22 +192,8 @@ static void __init xen_filter_cpu_maps(void) } else { set_cpu_possible(i, false); set_cpu_present(i, false); - subtract++; } } -#ifdef CONFIG_HOTPLUG_CPU - /* This is akin to using 'nr_cpus' on the Linux command line. - * Which is OK as when we use 'dom0_max_vcpus=X' we can only - * have up to X, while nr_cpu_ids is greater than X. This - * normally is not a problem, except when CPU hotplugging - * is involved and then there might be more than X CPUs - * in the guest - which will not work as there is no - * hypercall to expand the max number of VCPUs an already - * running guest has. So cap it up to X. */ - if (subtract) - nr_cpu_ids = nr_cpu_ids - subtract; -#endif - } static void __init xen_smp_prepare_boot_cpu(void) diff --git a/trunk/arch/x86/xen/xen-asm.S b/trunk/arch/x86/xen/xen-asm.S index 3e45aa000718..79d7362ad6d1 100644 --- a/trunk/arch/x86/xen/xen-asm.S +++ b/trunk/arch/x86/xen/xen-asm.S @@ -96,7 +96,7 @@ ENTRY(xen_restore_fl_direct) /* check for unmasked and pending */ cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending - jnz 1f + jz 1f 2: call check_events 1: ENDPATCH(xen_restore_fl_direct) diff --git a/trunk/arch/xtensa/include/asm/hardirq.h b/trunk/arch/xtensa/include/asm/hardirq.h index 91695a135498..26664cef8f11 100644 --- a/trunk/arch/xtensa/include/asm/hardirq.h +++ b/trunk/arch/xtensa/include/asm/hardirq.h @@ -11,6 +11,9 @@ #ifndef _XTENSA_HARDIRQ_H #define _XTENSA_HARDIRQ_H +void ack_bad_irq(unsigned int irq); +#define ack_bad_irq ack_bad_irq + #include #endif /* _XTENSA_HARDIRQ_H */ diff --git a/trunk/arch/xtensa/include/asm/io.h b/trunk/arch/xtensa/include/asm/io.h index 4beb43c087d3..d04cd3a625fa 100644 --- a/trunk/arch/xtensa/include/asm/io.h +++ b/trunk/arch/xtensa/include/asm/io.h @@ -14,7 +14,6 @@ #ifdef __KERNEL__ #include #include -#include #include #include diff --git a/trunk/arch/xtensa/kernel/signal.c b/trunk/arch/xtensa/kernel/signal.c index d78869a00b11..b69b000349fc 100644 --- a/trunk/arch/xtensa/kernel/signal.c +++ b/trunk/arch/xtensa/kernel/signal.c @@ -496,7 +496,6 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) signr = get_signal_to_deliver(&info, &ka, regs, NULL); if (signr > 0) { - int ret; /* Are we from a system call? */ diff --git a/trunk/crypto/sha512_generic.c b/trunk/crypto/sha512_generic.c index dd30f40af9f5..107f6f7be5e1 100644 --- a/trunk/crypto/sha512_generic.c +++ b/trunk/crypto/sha512_generic.c @@ -174,7 +174,7 @@ sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len) index = sctx->count[0] & 0x7f; /* Update number of bytes */ - if ((sctx->count[0] += len) < len) + if (!(sctx->count[0] += len)) sctx->count[1]++; part_len = 128 - index; diff --git a/trunk/drivers/acpi/acpica/hwxface.c b/trunk/drivers/acpi/acpica/hwxface.c index a716fede4f25..ab513a972c95 100644 --- a/trunk/drivers/acpi/acpica/hwxface.c +++ b/trunk/drivers/acpi/acpica/hwxface.c @@ -74,8 +74,7 @@ acpi_status acpi_reset(void) /* Check if the reset register is supported */ - if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || - !reset_reg->address) { + if (!reset_reg->address) { return_ACPI_STATUS(AE_NOT_EXIST); } diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index c3881b2eb8b2..ba14fb93c929 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -607,7 +607,8 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, acpi_irq_handler = handler; acpi_irq_context = context; - if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { + if (request_threaded_irq(irq, NULL, acpi_irq, IRQF_SHARED, "acpi", + acpi_irq)) { printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); acpi_irq_handler = NULL; return AE_NOT_ACQUIRED; diff --git a/trunk/drivers/acpi/power.c b/trunk/drivers/acpi/power.c index 330bb4d75852..7049a7d27c4f 100644 --- a/trunk/drivers/acpi/power.c +++ b/trunk/drivers/acpi/power.c @@ -631,7 +631,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state) * We know a device's inferred power state when all the resources * required for a given D-state are 'on'. */ - for (i = ACPI_STATE_D0; i < ACPI_STATE_D3_HOT; i++) { + for (i = ACPI_STATE_D0; i < ACPI_STATE_D3; i++) { list = &device->power.states[i].resources; if (list->count < 1) continue; diff --git a/trunk/drivers/acpi/reboot.c b/trunk/drivers/acpi/reboot.c index a6c77e8b37bd..c1d612435939 100644 --- a/trunk/drivers/acpi/reboot.c +++ b/trunk/drivers/acpi/reboot.c @@ -23,8 +23,7 @@ void acpi_reboot(void) /* Is the reset register supported? The spec says we should be * checking the bit width and bit offset, but Windows ignores * these fields */ - if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) - return; + /* Ignore also acpi_gbl_FADT.flags.ACPI_FADT_RESET_REGISTER */ reset_value = acpi_gbl_FADT.reset_value; diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index 7417267e88fa..767e2dcb9616 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -869,7 +869,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) /* * Enumerate supported power management states */ - for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) { + for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3; i++) { struct acpi_device_power_state *ps = &device->power.states[i]; char object_name[5] = { '_', 'P', 'R', '0' + i, '\0' }; @@ -884,18 +884,21 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) acpi_bus_add_power_resource(ps->resources.handles[j]); } + /* The exist of _PR3 indicates D3Cold support */ + if (i == ACPI_STATE_D3) { + status = acpi_get_handle(device->handle, object_name, &handle); + if (ACPI_SUCCESS(status)) + device->power.states[ACPI_STATE_D3_COLD].flags.valid = 1; + } + /* Evaluate "_PSx" to see if we can do explicit sets */ object_name[2] = 'S'; status = acpi_get_handle(device->handle, object_name, &handle); if (ACPI_SUCCESS(status)) ps->flags.explicit_set = 1; - /* - * State is valid if there are means to put the device into it. - * D3hot is only valid if _PR3 present. - */ - if (ps->resources.count || - (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT)) + /* State is valid if we have some power control */ + if (ps->resources.count || ps->flags.explicit_set) ps->flags.valid = 1; ps->power = -1; /* Unknown - driver assigned */ diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c index eb6fd233764b..1d661b5c3287 100644 --- a/trunk/drivers/acpi/sleep.c +++ b/trunk/drivers/acpi/sleep.c @@ -28,33 +28,23 @@ #include "internal.h" #include "sleep.h" -u8 wake_sleep_flags = ACPI_NO_OPTIONAL_METHODS; static unsigned int gts, bfs; -static int set_param_wake_flag(const char *val, struct kernel_param *kp) +module_param(gts, uint, 0644); +module_param(bfs, uint, 0644); +MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); +MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); + +static u8 wake_sleep_flags(void) { - int ret = param_set_int(val, kp); + u8 flags = ACPI_NO_OPTIONAL_METHODS; - if (ret) - return ret; + if (gts) + flags |= ACPI_EXECUTE_GTS; + if (bfs) + flags |= ACPI_EXECUTE_BFS; - if (kp->arg == (const char *)>s) { - if (gts) - wake_sleep_flags |= ACPI_EXECUTE_GTS; - else - wake_sleep_flags &= ~ACPI_EXECUTE_GTS; - } - if (kp->arg == (const char *)&bfs) { - if (bfs) - wake_sleep_flags |= ACPI_EXECUTE_BFS; - else - wake_sleep_flags &= ~ACPI_EXECUTE_BFS; - } - return ret; + return flags; } -module_param_call(gts, set_param_wake_flag, param_get_int, >s, 0644); -module_param_call(bfs, set_param_wake_flag, param_get_int, &bfs, 0644); -MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); -MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); static u8 sleep_states[ACPI_S_STATE_COUNT]; @@ -273,6 +263,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) { acpi_status status = AE_OK; u32 acpi_state = acpi_target_sleep_state; + u8 flags = wake_sleep_flags(); int error; ACPI_FLUSH_CPU_CACHE(); @@ -280,7 +271,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) switch (acpi_state) { case ACPI_STATE_S1: barrier(); - status = acpi_enter_sleep_state(acpi_state, wake_sleep_flags); + status = acpi_enter_sleep_state(acpi_state, flags); break; case ACPI_STATE_S3: @@ -295,7 +286,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); /* Reprogram control registers and execute _BFS */ - acpi_leave_sleep_state_prep(acpi_state, wake_sleep_flags); + acpi_leave_sleep_state_prep(acpi_state, flags); /* ACPI 3.0 specs (P62) says that it's the responsibility * of the OSPM to clear the status bit [ implying that the @@ -559,27 +550,30 @@ static int acpi_hibernation_begin(void) static int acpi_hibernation_enter(void) { + u8 flags = wake_sleep_flags(); acpi_status status = AE_OK; ACPI_FLUSH_CPU_CACHE(); /* This shouldn't return. If it returns, we have a problem */ - status = acpi_enter_sleep_state(ACPI_STATE_S4, wake_sleep_flags); + status = acpi_enter_sleep_state(ACPI_STATE_S4, flags); /* Reprogram control registers and execute _BFS */ - acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags); + acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags); return ACPI_SUCCESS(status) ? 0 : -EFAULT; } static void acpi_hibernation_leave(void) { + u8 flags = wake_sleep_flags(); + /* * If ACPI is not enabled by the BIOS and the boot kernel, we need to * enable it here. */ acpi_enable(); /* Reprogram control registers and execute _BFS */ - acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags); + acpi_leave_sleep_state_prep(ACPI_STATE_S4, flags); /* Check the hardware signature */ if (facs && s4_hardware_signature != facs->hardware_signature) { printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " @@ -834,10 +828,12 @@ static void acpi_power_off_prepare(void) static void acpi_power_off(void) { + u8 flags = wake_sleep_flags(); + /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ printk(KERN_DEBUG "%s called\n", __func__); local_irq_disable(); - acpi_enter_sleep_state(ACPI_STATE_S5, wake_sleep_flags); + acpi_enter_sleep_state(ACPI_STATE_S5, flags); } /* diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index ebaf67e4b2bc..79a1e9dd56d9 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -394,8 +394,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ { PCI_DEVICE(0x1b4b, 0x9125), .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ - { PCI_DEVICE(0x1b4b, 0x917a), - .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ { PCI_DEVICE(0x1b4b, 0x91a3), .driver_data = board_ahci_yes_fbs }, diff --git a/trunk/drivers/ata/ahci_platform.c b/trunk/drivers/ata/ahci_platform.c index 9e419e1c2006..0c86c77764bc 100644 --- a/trunk/drivers/ata/ahci_platform.c +++ b/trunk/drivers/ata/ahci_platform.c @@ -280,7 +280,6 @@ static struct dev_pm_ops ahci_pm_ops = { static const struct of_device_id ahci_of_match[] = { { .compatible = "calxeda,hb-ahci", }, - { .compatible = "snps,spear-ahci", }, {}, }; MODULE_DEVICE_TABLE(of, ahci_of_match); diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index 7857e8fd0a3e..68013f96729f 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -329,8 +329,6 @@ static const struct pci_device_id piix_pci_tbl[] = { { 0x8086, 0x8c08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, /* SATA Controller IDE (Lynx Point) */ { 0x8086, 0x8c09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, - /* SATA Controller IDE (DH89xxCC) */ - { 0x8086, 0x2326, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, { } /* terminate list */ }; diff --git a/trunk/drivers/ata/libata-core.c b/trunk/drivers/ata/libata-core.c index 23763a1ec570..e0bda9ff89cd 100644 --- a/trunk/drivers/ata/libata-core.c +++ b/trunk/drivers/ata/libata-core.c @@ -95,7 +95,7 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev); static void ata_dev_xfermask(struct ata_device *dev); static unsigned long ata_dev_blacklisted(const struct ata_device *dev); -atomic_t ata_print_id = ATOMIC_INIT(0); +unsigned int ata_print_id = 1; struct ata_force_param { const char *name; @@ -6029,7 +6029,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) /* give ports names and add SCSI hosts */ for (i = 0; i < host->n_ports; i++) - host->ports[i]->print_id = atomic_inc_return(&ata_print_id); + host->ports[i]->print_id = ata_print_id++; /* Create associated sysfs transport objects */ diff --git a/trunk/drivers/ata/libata-eh.c b/trunk/drivers/ata/libata-eh.c index d1fbd59ead16..c61316e9d2f7 100644 --- a/trunk/drivers/ata/libata-eh.c +++ b/trunk/drivers/ata/libata-eh.c @@ -3501,8 +3501,7 @@ static int ata_count_probe_trials_cb(struct ata_ering_entry *ent, void *void_arg u64 now = get_jiffies_64(); int *trials = void_arg; - if ((ent->eflags & ATA_EFLAG_OLD_ER) || - (ent->timestamp < now - min(now, interval))) + if (ent->timestamp < now - min(now, interval)) return -1; (*trials)++; diff --git a/trunk/drivers/ata/libata-scsi.c b/trunk/drivers/ata/libata-scsi.c index 22226350cd0c..1ee00c8b5b04 100644 --- a/trunk/drivers/ata/libata-scsi.c +++ b/trunk/drivers/ata/libata-scsi.c @@ -3399,8 +3399,7 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) */ shost->max_host_blocked = 1; - rc = scsi_add_host_with_dma(ap->scsi_host, - &ap->tdev, ap->host->dev); + rc = scsi_add_host(ap->scsi_host, &ap->tdev); if (rc) goto err_add; } @@ -3839,25 +3838,18 @@ void ata_sas_port_stop(struct ata_port *ap) } EXPORT_SYMBOL_GPL(ata_sas_port_stop); -/** - * ata_sas_async_probe - simply schedule probing and return - * @ap: Port to probe - * - * For batch scheduling of probe for sas attached ata devices, assumes - * the port has already been through ata_sas_port_init() - */ -void ata_sas_async_probe(struct ata_port *ap) +int ata_sas_async_port_init(struct ata_port *ap) { - __ata_port_probe(ap); -} -EXPORT_SYMBOL_GPL(ata_sas_async_probe); + int rc = ap->ops->port_start(ap); -int ata_sas_sync_probe(struct ata_port *ap) -{ - return ata_port_probe(ap); -} -EXPORT_SYMBOL_GPL(ata_sas_sync_probe); + if (!rc) { + ap->print_id = ata_print_id++; + __ata_port_probe(ap); + } + return rc; +} +EXPORT_SYMBOL_GPL(ata_sas_async_port_init); /** * ata_sas_port_init - Initialize a SATA device @@ -3874,10 +3866,12 @@ int ata_sas_port_init(struct ata_port *ap) { int rc = ap->ops->port_start(ap); - if (rc) - return rc; - ap->print_id = atomic_inc_return(&ata_print_id); - return 0; + if (!rc) { + ap->print_id = ata_print_id++; + rc = ata_port_probe(ap); + } + + return rc; } EXPORT_SYMBOL_GPL(ata_sas_port_init); diff --git a/trunk/drivers/ata/libata-transport.c b/trunk/drivers/ata/libata-transport.c index c34190485377..74aaee30e264 100644 --- a/trunk/drivers/ata/libata-transport.c +++ b/trunk/drivers/ata/libata-transport.c @@ -294,7 +294,6 @@ int ata_tport_add(struct device *parent, device_enable_async_suspend(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); - pm_runtime_forbid(dev); transport_add_device(dev); transport_configure_device(dev); diff --git a/trunk/drivers/ata/libata.h b/trunk/drivers/ata/libata.h index 9d0fd0b71852..2e26fcaf635b 100644 --- a/trunk/drivers/ata/libata.h +++ b/trunk/drivers/ata/libata.h @@ -53,7 +53,7 @@ enum { ATA_DNXFER_QUIET = (1 << 31), }; -extern atomic_t ata_print_id; +extern unsigned int ata_print_id; extern int atapi_passthru16; extern int libata_fua; extern int libata_noacpi; diff --git a/trunk/drivers/ata/pata_arasan_cf.c b/trunk/drivers/ata/pata_arasan_cf.c index 3239517f4d90..fc2db2a89a6b 100644 --- a/trunk/drivers/ata/pata_arasan_cf.c +++ b/trunk/drivers/ata/pata_arasan_cf.c @@ -943,9 +943,9 @@ static int arasan_cf_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(arasan_cf_pm_ops, arasan_cf_suspend, arasan_cf_resume); +#endif static struct platform_driver arasan_cf_driver = { .probe = arasan_cf_probe, @@ -953,7 +953,9 @@ static struct platform_driver arasan_cf_driver = { .driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, +#ifdef CONFIG_PM .pm = &arasan_cf_pm_ops, +#endif }, }; diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index 7336d4a7ab31..38950ea8398a 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -4025,8 +4025,7 @@ static int mv_platform_probe(struct platform_device *pdev) struct ata_host *host; struct mv_host_priv *hpriv; struct resource *res; - int n_ports = 0; - int rc; + int n_ports, rc; ata_print_version_once(&pdev->dev, DRV_VERSION); diff --git a/trunk/drivers/bcma/sprom.c b/trunk/drivers/bcma/sprom.c index 3e2a6002aae6..cdcf75c0954f 100644 --- a/trunk/drivers/bcma/sprom.c +++ b/trunk/drivers/bcma/sprom.c @@ -404,19 +404,16 @@ int bcma_sprom_get(struct bcma_bus *bus) return -EOPNOTSUPP; if (!bcma_sprom_ext_available(bus)) { - bool sprom_onchip; - /* * External SPROM takes precedence so check * on-chip OTP only when no external SPROM * is present. */ - sprom_onchip = bcma_sprom_onchip_available(bus); - if (sprom_onchip) { + if (bcma_sprom_onchip_available(bus)) { /* determine offset */ offset = bcma_sprom_onchip_offset(bus); } - if (!offset || !sprom_onchip) { + if (!offset) { /* * Maybe there is no SPROM on the device? * Now we ask the arch code if there is some sprom diff --git a/trunk/drivers/block/virtio_blk.c b/trunk/drivers/block/virtio_blk.c index 0d39f2f4294a..0e4ef3de9d5d 100644 --- a/trunk/drivers/block/virtio_blk.c +++ b/trunk/drivers/block/virtio_blk.c @@ -375,34 +375,6 @@ static int init_vq(struct virtio_blk *vblk) return err; } -/* - * Legacy naming scheme used for virtio devices. We are stuck with it for - * virtio blk but don't ever use it for any new driver. - */ -static int virtblk_name_format(char *prefix, int index, char *buf, int buflen) -{ - const int base = 'z' - 'a' + 1; - char *begin = buf + strlen(prefix); - char *end = buf + buflen; - char *p; - int unit; - - p = end - 1; - *p = '\0'; - unit = base; - do { - if (p == begin) - return -EINVAL; - *--p = 'a' + (index % unit); - index = (index / unit) - 1; - } while (index >= 0); - - memmove(begin, p, end - p); - memcpy(buf, prefix, strlen(prefix)); - - return 0; -} - static int __devinit virtblk_probe(struct virtio_device *vdev) { struct virtio_blk *vblk; @@ -471,7 +443,18 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) q->queuedata = vblk; - virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN); + if (index < 26) { + sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); + } else if (index < (26 + 1) * 26) { + sprintf(vblk->disk->disk_name, "vd%c%c", + 'a' + index / 26 - 1, 'a' + index % 26); + } else { + const unsigned int m1 = (index / 26 - 1) / 26 - 1; + const unsigned int m2 = (index / 26 - 1) % 26; + const unsigned int m3 = index % 26; + sprintf(vblk->disk->disk_name, "vd%c%c%c", + 'a' + m1, 'a' + m2, 'a' + m3); + } vblk->disk->major = major; vblk->disk->first_minor = index_to_minor(index); diff --git a/trunk/drivers/block/xen-blkback/xenbus.c b/trunk/drivers/block/xen-blkback/xenbus.c index 4f66171c6683..89860f34a7ec 100644 --- a/trunk/drivers/block/xen-blkback/xenbus.c +++ b/trunk/drivers/block/xen-blkback/xenbus.c @@ -416,7 +416,7 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info "discard-secure", "%d", blkif->vbd.discard_secure); if (err) { - dev_warn(&dev->dev, "writing discard-secure (%d)", err); + dev_warn(dev-dev, "writing discard-secure (%d)", err); return; } } diff --git a/trunk/drivers/bluetooth/ath3k.c b/trunk/drivers/bluetooth/ath3k.c index 57fd867553d7..ae9edca7b56d 100644 --- a/trunk/drivers/bluetooth/ath3k.c +++ b/trunk/drivers/bluetooth/ath3k.c @@ -75,8 +75,6 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x0CF3, 0x311D) }, { USB_DEVICE(0x13d3, 0x3375) }, { USB_DEVICE(0x04CA, 0x3005) }, - { USB_DEVICE(0x13d3, 0x3362) }, - { USB_DEVICE(0x0CF3, 0xE004) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, @@ -96,8 +94,6 @@ static struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { } /* Terminating entry */ }; diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c index 9217121362e1..3311b812a0c6 100644 --- a/trunk/drivers/bluetooth/btusb.c +++ b/trunk/drivers/bluetooth/btusb.c @@ -101,16 +101,12 @@ static struct usb_device_id btusb_table[] = { { USB_DEVICE(0x0c10, 0x0000) }, /* Broadcom BCM20702A0 */ - { USB_DEVICE(0x0489, 0xe042) }, { USB_DEVICE(0x0a5c, 0x21e3) }, { USB_DEVICE(0x0a5c, 0x21e6) }, { USB_DEVICE(0x0a5c, 0x21e8) }, { USB_DEVICE(0x0a5c, 0x21f3) }, { USB_DEVICE(0x413c, 0x8197) }, - /* Foxconn - Hon Hai */ - { USB_DEVICE(0x0489, 0xe033) }, - { } /* Terminating entry */ }; @@ -137,8 +133,6 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, diff --git a/trunk/drivers/crypto/ixp4xx_crypto.c b/trunk/drivers/crypto/ixp4xx_crypto.c index 8f3f74ce8c7f..0053d7ebb5ca 100644 --- a/trunk/drivers/crypto/ixp4xx_crypto.c +++ b/trunk/drivers/crypto/ixp4xx_crypto.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/crypto/talitos.c b/trunk/drivers/crypto/talitos.c index 921039e56f87..dc641c796526 100644 --- a/trunk/drivers/crypto/talitos.c +++ b/trunk/drivers/crypto/talitos.c @@ -124,9 +124,6 @@ struct talitos_private { void __iomem *reg; int irq[2]; - /* SEC global registers lock */ - spinlock_t reg_lock ____cacheline_aligned; - /* SEC version geometry (from device tree node) */ unsigned int num_channels; unsigned int chfifo_len; @@ -415,7 +412,6 @@ static void talitos_done_##name(unsigned long data) \ { \ struct device *dev = (struct device *)data; \ struct talitos_private *priv = dev_get_drvdata(dev); \ - unsigned long flags; \ \ if (ch_done_mask & 1) \ flush_channel(dev, 0, 0, 0); \ @@ -431,10 +427,8 @@ static void talitos_done_##name(unsigned long data) \ out: \ /* At this point, all completed channels have been processed */ \ /* Unmask done interrupts for channels completed later on. */ \ - spin_lock_irqsave(&priv->reg_lock, flags); \ setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \ - spin_unlock_irqrestore(&priv->reg_lock, flags); \ } DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE) DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE) @@ -625,28 +619,22 @@ static irqreturn_t talitos_interrupt_##name(int irq, void *data) \ struct device *dev = data; \ struct talitos_private *priv = dev_get_drvdata(dev); \ u32 isr, isr_lo; \ - unsigned long flags; \ \ - spin_lock_irqsave(&priv->reg_lock, flags); \ isr = in_be32(priv->reg + TALITOS_ISR); \ isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \ /* Acknowledge interrupt */ \ out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \ out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \ \ - if (unlikely(isr & ch_err_mask || isr_lo)) { \ - spin_unlock_irqrestore(&priv->reg_lock, flags); \ - talitos_error(dev, isr & ch_err_mask, isr_lo); \ - } \ - else { \ + if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo)) \ + talitos_error(dev, isr, isr_lo); \ + else \ if (likely(isr & ch_done_mask)) { \ /* mask further done interrupts. */ \ clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ /* done_task will unmask done interrupts at exit */ \ tasklet_schedule(&priv->done_task[tlet]); \ } \ - spin_unlock_irqrestore(&priv->reg_lock, flags); \ - } \ \ return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \ IRQ_NONE; \ @@ -2731,8 +2719,6 @@ static int talitos_probe(struct platform_device *ofdev) priv->ofdev = ofdev; - spin_lock_init(&priv->reg_lock); - err = talitos_probe_irq(ofdev); if (err) goto err_out; diff --git a/trunk/drivers/dma/Kconfig b/trunk/drivers/dma/Kconfig index ef378b5b17e4..cf9da362d64f 100644 --- a/trunk/drivers/dma/Kconfig +++ b/trunk/drivers/dma/Kconfig @@ -91,10 +91,11 @@ config DW_DMAC config AT_HDMAC tristate "Atmel AHB DMA support" - depends on ARCH_AT91 + depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 select DMA_ENGINE help - Support the Atmel AHB DMA controller. + Support the Atmel AHB DMA controller. This can be integrated in + chips such as the Atmel AT91SAM9RL. config FSL_DMA tristate "Freescale Elo and Elo Plus DMA support" diff --git a/trunk/drivers/dma/amba-pl08x.c b/trunk/drivers/dma/amba-pl08x.c index 3d704abd7912..c301a8ec31aa 100644 --- a/trunk/drivers/dma/amba-pl08x.c +++ b/trunk/drivers/dma/amba-pl08x.c @@ -1429,7 +1429,6 @@ static int pl08x_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, * signal */ release_phy_channel(plchan); - plchan->phychan_hold = 0; } /* Dequeue jobs and free LLIs */ if (plchan->at) { diff --git a/trunk/drivers/dma/at_hdmac.c b/trunk/drivers/dma/at_hdmac.c index 445fdf811695..7aa58d204892 100644 --- a/trunk/drivers/dma/at_hdmac.c +++ b/trunk/drivers/dma/at_hdmac.c @@ -221,6 +221,10 @@ static void atc_dostart(struct at_dma_chan *atchan, struct at_desc *first) vdbg_dump_regs(atchan); + /* clear any pending interrupt */ + while (dma_readl(atdma, EBCISR)) + cpu_relax(); + channel_writel(atchan, SADDR, 0); channel_writel(atchan, DADDR, 0); channel_writel(atchan, CTRLA, 0); diff --git a/trunk/drivers/dma/imx-dma.c b/trunk/drivers/dma/imx-dma.c index bb787d8e1529..a45b5d2a5987 100644 --- a/trunk/drivers/dma/imx-dma.c +++ b/trunk/drivers/dma/imx-dma.c @@ -571,14 +571,11 @@ static void imxdma_tasklet(unsigned long data) if (desc->desc.callback) desc->desc.callback(desc->desc.callback_param); - /* If we are dealing with a cyclic descriptor keep it on ld_active - * and dont mark the descripor as complete. - * Only in non-cyclic cases it would be marked as complete - */ + dma_cookie_complete(&desc->desc); + + /* If we are dealing with a cyclic descriptor keep it on ld_active */ if (imxdma_chan_is_doing_cyclic(imxdmac)) goto out; - else - dma_cookie_complete(&desc->desc); /* Free 2D slot if it was an interleaved transfer */ if (imxdmac->enabled_2d) { diff --git a/trunk/drivers/dma/mxs-dma.c b/trunk/drivers/dma/mxs-dma.c index 655d4ce6ed0d..c81ef7e10e08 100644 --- a/trunk/drivers/dma/mxs-dma.c +++ b/trunk/drivers/dma/mxs-dma.c @@ -201,6 +201,10 @@ static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan) static dma_cookie_t mxs_dma_tx_submit(struct dma_async_tx_descriptor *tx) { + struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(tx->chan); + + mxs_dma_enable_chan(mxs_chan); + return dma_cookie_assign(tx); } @@ -554,9 +558,9 @@ static enum dma_status mxs_dma_tx_status(struct dma_chan *chan, static void mxs_dma_issue_pending(struct dma_chan *chan) { - struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan); - - mxs_dma_enable_chan(mxs_chan); + /* + * Nothing to do. We only have a single descriptor. + */ } static int __init mxs_dma_init(struct mxs_dma_engine *mxs_dma) diff --git a/trunk/drivers/dma/pl330.c b/trunk/drivers/dma/pl330.c index 2ee6e23930ad..282caf118be8 100644 --- a/trunk/drivers/dma/pl330.c +++ b/trunk/drivers/dma/pl330.c @@ -2225,9 +2225,12 @@ static inline void free_desc_list(struct list_head *list) { struct dma_pl330_dmac *pdmac; struct dma_pl330_desc *desc; - struct dma_pl330_chan *pch = NULL; + struct dma_pl330_chan *pch; unsigned long flags; + if (list_empty(list)) + return; + /* Finish off the work list */ list_for_each_entry(desc, list, node) { dma_async_tx_callback callback; @@ -2244,10 +2247,6 @@ static inline void free_desc_list(struct list_head *list) desc->pchan = NULL; } - /* pch will be unset if list was empty */ - if (!pch) - return; - pdmac = pch->dmac; spin_lock_irqsave(&pdmac->pool_lock, flags); @@ -2258,9 +2257,12 @@ static inline void free_desc_list(struct list_head *list) static inline void handle_cyclic_desc_list(struct list_head *list) { struct dma_pl330_desc *desc; - struct dma_pl330_chan *pch = NULL; + struct dma_pl330_chan *pch; unsigned long flags; + if (list_empty(list)) + return; + list_for_each_entry(desc, list, node) { dma_async_tx_callback callback; @@ -2272,10 +2274,6 @@ static inline void handle_cyclic_desc_list(struct list_head *list) callback(desc->txd.callback_param); } - /* pch will be unset if list was empty */ - if (!pch) - return; - spin_lock_irqsave(&pch->lock, flags); list_splice_tail_init(list, &pch->work_list); spin_unlock_irqrestore(&pch->lock, flags); @@ -2928,11 +2926,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) INIT_LIST_HEAD(&pd->channels); /* Initialize channel parameters */ - if (pdat) - num_chan = max_t(int, pdat->nr_valid_peri, pi->pcfg.num_chan); - else - num_chan = max_t(int, pi->pcfg.num_peri, pi->pcfg.num_chan); - + num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri, + (u8)pi->pcfg.num_chan); pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); for (i = 0; i < num_chan; i++) { diff --git a/trunk/drivers/dma/ste_dma40.c b/trunk/drivers/dma/ste_dma40.c index 2ed1ac3513f3..bdd41d4bfa8d 100644 --- a/trunk/drivers/dma/ste_dma40.c +++ b/trunk/drivers/dma/ste_dma40.c @@ -18,7 +18,6 @@ #include #include #include -#include #include @@ -69,22 +68,6 @@ enum d40_command { D40_DMA_SUSPENDED = 3 }; -/* - * enum d40_events - The different Event Enables for the event lines. - * - * @D40_DEACTIVATE_EVENTLINE: De-activate Event line, stopping the logical chan. - * @D40_ACTIVATE_EVENTLINE: Activate the Event line, to start a logical chan. - * @D40_SUSPEND_REQ_EVENTLINE: Requesting for suspending a event line. - * @D40_ROUND_EVENTLINE: Status check for event line. - */ - -enum d40_events { - D40_DEACTIVATE_EVENTLINE = 0, - D40_ACTIVATE_EVENTLINE = 1, - D40_SUSPEND_REQ_EVENTLINE = 2, - D40_ROUND_EVENTLINE = 3 -}; - /* * These are the registers that has to be saved and later restored * when the DMA hw is powered off. @@ -887,8 +870,8 @@ static void d40_save_restore_registers(struct d40_base *base, bool save) } #endif -static int __d40_execute_command_phy(struct d40_chan *d40c, - enum d40_command command) +static int d40_channel_execute_command(struct d40_chan *d40c, + enum d40_command command) { u32 status; int i; @@ -897,12 +880,6 @@ static int __d40_execute_command_phy(struct d40_chan *d40c, unsigned long flags; u32 wmask; - if (command == D40_DMA_STOP) { - ret = __d40_execute_command_phy(d40c, D40_DMA_SUSPEND_REQ); - if (ret) - return ret; - } - spin_lock_irqsave(&d40c->base->execmd_lock, flags); if (d40c->phy_chan->num % 2 == 0) @@ -996,109 +973,67 @@ static void d40_term_all(struct d40_chan *d40c) } d40c->pending_tx = 0; + d40c->busy = false; } -static void __d40_config_set_event(struct d40_chan *d40c, - enum d40_events event_type, u32 event, - int reg) +static void __d40_config_set_event(struct d40_chan *d40c, bool enable, + u32 event, int reg) { void __iomem *addr = chan_base(d40c) + reg; int tries; - u32 status; - - switch (event_type) { - - case D40_DEACTIVATE_EVENTLINE: + if (!enable) { writel((D40_DEACTIVATE_EVENTLINE << D40_EVENTLINE_POS(event)) | ~D40_EVENTLINE_MASK(event), addr); - break; - - case D40_SUSPEND_REQ_EVENTLINE: - status = (readl(addr) & D40_EVENTLINE_MASK(event)) >> - D40_EVENTLINE_POS(event); - - if (status == D40_DEACTIVATE_EVENTLINE || - status == D40_SUSPEND_REQ_EVENTLINE) - break; - - writel((D40_SUSPEND_REQ_EVENTLINE << D40_EVENTLINE_POS(event)) - | ~D40_EVENTLINE_MASK(event), addr); - - for (tries = 0 ; tries < D40_SUSPEND_MAX_IT; tries++) { - - status = (readl(addr) & D40_EVENTLINE_MASK(event)) >> - D40_EVENTLINE_POS(event); - - cpu_relax(); - /* - * Reduce the number of bus accesses while - * waiting for the DMA to suspend. - */ - udelay(3); - - if (status == D40_DEACTIVATE_EVENTLINE) - break; - } - - if (tries == D40_SUSPEND_MAX_IT) { - chan_err(d40c, - "unable to stop the event_line chl %d (log: %d)" - "status %x\n", d40c->phy_chan->num, - d40c->log_num, status); - } - break; + return; + } - case D40_ACTIVATE_EVENTLINE: /* * The hardware sometimes doesn't register the enable when src and dst * event lines are active on the same logical channel. Retry to ensure * it does. Usually only one retry is sufficient. */ - tries = 100; - while (--tries) { - writel((D40_ACTIVATE_EVENTLINE << - D40_EVENTLINE_POS(event)) | - ~D40_EVENTLINE_MASK(event), addr); - - if (readl(addr) & D40_EVENTLINE_MASK(event)) - break; - } - - if (tries != 99) - dev_dbg(chan2dev(d40c), - "[%s] workaround enable S%cLNK (%d tries)\n", - __func__, reg == D40_CHAN_REG_SSLNK ? 'S' : 'D', - 100 - tries); + tries = 100; + while (--tries) { + writel((D40_ACTIVATE_EVENTLINE << D40_EVENTLINE_POS(event)) + | ~D40_EVENTLINE_MASK(event), addr); - WARN_ON(!tries); - break; + if (readl(addr) & D40_EVENTLINE_MASK(event)) + break; + } - case D40_ROUND_EVENTLINE: - BUG(); - break; + if (tries != 99) + dev_dbg(chan2dev(d40c), + "[%s] workaround enable S%cLNK (%d tries)\n", + __func__, reg == D40_CHAN_REG_SSLNK ? 'S' : 'D', + 100 - tries); - } + WARN_ON(!tries); } -static void d40_config_set_event(struct d40_chan *d40c, - enum d40_events event_type) +static void d40_config_set_event(struct d40_chan *d40c, bool do_enable) { + unsigned long flags; + + spin_lock_irqsave(&d40c->phy_chan->lock, flags); + /* Enable event line connected to device (or memcpy) */ if ((d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_MEM) || (d40c->dma_cfg.dir == STEDMA40_PERIPH_TO_PERIPH)) { u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.src_dev_type); - __d40_config_set_event(d40c, event_type, event, + __d40_config_set_event(d40c, do_enable, event, D40_CHAN_REG_SSLNK); } if (d40c->dma_cfg.dir != STEDMA40_PERIPH_TO_MEM) { u32 event = D40_TYPE_TO_EVENT(d40c->dma_cfg.dst_dev_type); - __d40_config_set_event(d40c, event_type, event, + __d40_config_set_event(d40c, do_enable, event, D40_CHAN_REG_SDLNK); } + + spin_unlock_irqrestore(&d40c->phy_chan->lock, flags); } static u32 d40_chan_has_events(struct d40_chan *d40c) @@ -1112,64 +1047,6 @@ static u32 d40_chan_has_events(struct d40_chan *d40c) return val; } -static int -__d40_execute_command_log(struct d40_chan *d40c, enum d40_command command) -{ - unsigned long flags; - int ret = 0; - u32 active_status; - void __iomem *active_reg; - - if (d40c->phy_chan->num % 2 == 0) - active_reg = d40c->base->virtbase + D40_DREG_ACTIVE; - else - active_reg = d40c->base->virtbase + D40_DREG_ACTIVO; - - - spin_lock_irqsave(&d40c->phy_chan->lock, flags); - - switch (command) { - case D40_DMA_STOP: - case D40_DMA_SUSPEND_REQ: - - active_status = (readl(active_reg) & - D40_CHAN_POS_MASK(d40c->phy_chan->num)) >> - D40_CHAN_POS(d40c->phy_chan->num); - - if (active_status == D40_DMA_RUN) - d40_config_set_event(d40c, D40_SUSPEND_REQ_EVENTLINE); - else - d40_config_set_event(d40c, D40_DEACTIVATE_EVENTLINE); - - if (!d40_chan_has_events(d40c) && (command == D40_DMA_STOP)) - ret = __d40_execute_command_phy(d40c, command); - - break; - - case D40_DMA_RUN: - - d40_config_set_event(d40c, D40_ACTIVATE_EVENTLINE); - ret = __d40_execute_command_phy(d40c, command); - break; - - case D40_DMA_SUSPENDED: - BUG(); - break; - } - - spin_unlock_irqrestore(&d40c->phy_chan->lock, flags); - return ret; -} - -static int d40_channel_execute_command(struct d40_chan *d40c, - enum d40_command command) -{ - if (chan_is_logical(d40c)) - return __d40_execute_command_log(d40c, command); - else - return __d40_execute_command_phy(d40c, command); -} - static u32 d40_get_prmo(struct d40_chan *d40c) { static const unsigned int phy_map[] = { @@ -1272,7 +1149,15 @@ static int d40_pause(struct d40_chan *d40c) spin_lock_irqsave(&d40c->lock, flags); res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); - + if (res == 0) { + if (chan_is_logical(d40c)) { + d40_config_set_event(d40c, false); + /* Resume the other logical channels if any */ + if (d40_chan_has_events(d40c)) + res = d40_channel_execute_command(d40c, + D40_DMA_RUN); + } + } pm_runtime_mark_last_busy(d40c->base->dev); pm_runtime_put_autosuspend(d40c->base->dev); spin_unlock_irqrestore(&d40c->lock, flags); @@ -1289,17 +1174,45 @@ static int d40_resume(struct d40_chan *d40c) spin_lock_irqsave(&d40c->lock, flags); pm_runtime_get_sync(d40c->base->dev); + if (d40c->base->rev == 0) + if (chan_is_logical(d40c)) { + res = d40_channel_execute_command(d40c, + D40_DMA_SUSPEND_REQ); + goto no_suspend; + } /* If bytes left to transfer or linked tx resume job */ - if (d40_residue(d40c) || d40_tx_is_linked(d40c)) + if (d40_residue(d40c) || d40_tx_is_linked(d40c)) { + + if (chan_is_logical(d40c)) + d40_config_set_event(d40c, true); + res = d40_channel_execute_command(d40c, D40_DMA_RUN); + } +no_suspend: pm_runtime_mark_last_busy(d40c->base->dev); pm_runtime_put_autosuspend(d40c->base->dev); spin_unlock_irqrestore(&d40c->lock, flags); return res; } +static int d40_terminate_all(struct d40_chan *chan) +{ + unsigned long flags; + int ret = 0; + + ret = d40_pause(chan); + if (!ret && chan_is_physical(chan)) + ret = d40_channel_execute_command(chan, D40_DMA_STOP); + + spin_lock_irqsave(&chan->lock, flags); + d40_term_all(chan); + spin_unlock_irqrestore(&chan->lock, flags); + + return ret; +} + static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx) { struct d40_chan *d40c = container_of(tx->chan, @@ -1319,6 +1232,20 @@ static dma_cookie_t d40_tx_submit(struct dma_async_tx_descriptor *tx) static int d40_start(struct d40_chan *d40c) { + if (d40c->base->rev == 0) { + int err; + + if (chan_is_logical(d40c)) { + err = d40_channel_execute_command(d40c, + D40_DMA_SUSPEND_REQ); + if (err) + return err; + } + } + + if (chan_is_logical(d40c)) + d40_config_set_event(d40c, true); + return d40_channel_execute_command(d40c, D40_DMA_RUN); } @@ -1331,10 +1258,10 @@ static struct d40_desc *d40_queue_start(struct d40_chan *d40c) d40d = d40_first_queued(d40c); if (d40d != NULL) { - if (!d40c->busy) { + if (!d40c->busy) d40c->busy = true; - pm_runtime_get_sync(d40c->base->dev); - } + + pm_runtime_get_sync(d40c->base->dev); /* Remove from queue */ d40_desc_remove(d40d); @@ -1461,8 +1388,8 @@ static void dma_tasklet(unsigned long data) return; -err: - /* Rescue manouver if receiving double interrupts */ + err: + /* Rescue manoeuvre if receiving double interrupts */ if (d40c->pending_tx > 0) d40c->pending_tx--; spin_unlock_irqrestore(&d40c->lock, flags); @@ -1843,6 +1770,7 @@ static int d40_config_memcpy(struct d40_chan *d40c) return 0; } + static int d40_free_dma(struct d40_chan *d40c) { @@ -1878,18 +1806,43 @@ static int d40_free_dma(struct d40_chan *d40c) } pm_runtime_get_sync(d40c->base->dev); - res = d40_channel_execute_command(d40c, D40_DMA_STOP); + res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); if (res) { - chan_err(d40c, "stop failed\n"); + chan_err(d40c, "suspend failed\n"); goto out; } - d40_alloc_mask_free(phy, is_src, chan_is_logical(d40c) ? event : 0); + if (chan_is_logical(d40c)) { + /* Release logical channel, deactivate the event line */ - if (chan_is_logical(d40c)) + d40_config_set_event(d40c, false); d40c->base->lookup_log_chans[d40c->log_num] = NULL; - else - d40c->base->lookup_phy_chans[phy->num] = NULL; + + /* + * Check if there are more logical allocation + * on this phy channel. + */ + if (!d40_alloc_mask_free(phy, is_src, event)) { + /* Resume the other logical channels if any */ + if (d40_chan_has_events(d40c)) { + res = d40_channel_execute_command(d40c, + D40_DMA_RUN); + if (res) + chan_err(d40c, + "Executing RUN command\n"); + } + goto out; + } + } else { + (void) d40_alloc_mask_free(phy, is_src, 0); + } + + /* Release physical channel */ + res = d40_channel_execute_command(d40c, D40_DMA_STOP); + if (res) { + chan_err(d40c, "Failed to stop channel\n"); + goto out; + } if (d40c->busy) { pm_runtime_mark_last_busy(d40c->base->dev); @@ -1899,6 +1852,7 @@ static int d40_free_dma(struct d40_chan *d40c) d40c->busy = false; d40c->phy_chan = NULL; d40c->configured = false; + d40c->base->lookup_phy_chans[phy->num] = NULL; out: pm_runtime_mark_last_busy(d40c->base->dev); @@ -2116,7 +2070,7 @@ d40_prep_sg(struct dma_chan *dchan, struct scatterlist *sg_src, if (sg_next(&sg_src[sg_len - 1]) == sg_src) desc->cyclic = true; - if (direction != DMA_TRANS_NONE) { + if (direction != DMA_NONE) { dma_addr_t dev_addr = d40_get_dev_addr(chan, direction); if (direction == DMA_DEV_TO_MEM) @@ -2417,31 +2371,6 @@ static void d40_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&d40c->lock, flags); } -static void d40_terminate_all(struct dma_chan *chan) -{ - unsigned long flags; - struct d40_chan *d40c = container_of(chan, struct d40_chan, chan); - int ret; - - spin_lock_irqsave(&d40c->lock, flags); - - pm_runtime_get_sync(d40c->base->dev); - ret = d40_channel_execute_command(d40c, D40_DMA_STOP); - if (ret) - chan_err(d40c, "Failed to stop channel\n"); - - d40_term_all(d40c); - pm_runtime_mark_last_busy(d40c->base->dev); - pm_runtime_put_autosuspend(d40c->base->dev); - if (d40c->busy) { - pm_runtime_mark_last_busy(d40c->base->dev); - pm_runtime_put_autosuspend(d40c->base->dev); - } - d40c->busy = false; - - spin_unlock_irqrestore(&d40c->lock, flags); -} - static int dma40_config_to_halfchannel(struct d40_chan *d40c, struct stedma40_half_channel_info *info, @@ -2622,8 +2551,7 @@ static int d40_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, switch (cmd) { case DMA_TERMINATE_ALL: - d40_terminate_all(chan); - return 0; + return d40_terminate_all(d40c); case DMA_PAUSE: return d40_pause(d40c); case DMA_RESUME: @@ -2980,12 +2908,6 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) dev_info(&pdev->dev, "hardware revision: %d @ 0x%x\n", rev, res->start); - if (rev < 2) { - d40_err(&pdev->dev, "hardware revision: %d is not supported", - rev); - goto failure; - } - plat_data = pdev->dev.platform_data; /* Count the number of logical channels in use */ @@ -3076,7 +2998,6 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) if (base) { kfree(base->lcla_pool.alloc_map); - kfree(base->reg_val_backup_chan); kfree(base->lookup_log_chans); kfree(base->lookup_phy_chans); kfree(base->phy_res); diff --git a/trunk/drivers/dma/ste_dma40_ll.h b/trunk/drivers/dma/ste_dma40_ll.h index 51e8e5396e9b..8d3d490968a3 100644 --- a/trunk/drivers/dma/ste_dma40_ll.h +++ b/trunk/drivers/dma/ste_dma40_ll.h @@ -62,6 +62,8 @@ #define D40_SREG_ELEM_LOG_LIDX_MASK (0xFF << D40_SREG_ELEM_LOG_LIDX_POS) /* Link register */ +#define D40_DEACTIVATE_EVENTLINE 0x0 +#define D40_ACTIVATE_EVENTLINE 0x1 #define D40_EVENTLINE_POS(i) (2 * i) #define D40_EVENTLINE_MASK(i) (0x3 << D40_EVENTLINE_POS(i)) diff --git a/trunk/drivers/firmware/efivars.c b/trunk/drivers/firmware/efivars.c index 47408e802ab6..d25599f2a3f8 100644 --- a/trunk/drivers/firmware/efivars.c +++ b/trunk/drivers/firmware/efivars.c @@ -191,190 +191,6 @@ utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len) } } -static bool -validate_device_path(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - struct efi_generic_dev_path *node; - int offset = 0; - - node = (struct efi_generic_dev_path *)buffer; - - if (len < sizeof(*node)) - return false; - - while (offset <= len - sizeof(*node) && - node->length >= sizeof(*node) && - node->length <= len - offset) { - offset += node->length; - - if ((node->type == EFI_DEV_END_PATH || - node->type == EFI_DEV_END_PATH2) && - node->sub_type == EFI_DEV_END_ENTIRE) - return true; - - node = (struct efi_generic_dev_path *)(buffer + offset); - } - - /* - * If we're here then either node->length pointed past the end - * of the buffer or we reached the end of the buffer without - * finding a device path end node. - */ - return false; -} - -static bool -validate_boot_order(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - /* An array of 16-bit integers */ - if ((len % 2) != 0) - return false; - - return true; -} - -static bool -validate_load_option(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - u16 filepathlength; - int i, desclength = 0, namelen; - - namelen = utf16_strnlen(var->VariableName, sizeof(var->VariableName)); - - /* Either "Boot" or "Driver" followed by four digits of hex */ - for (i = match; i < match+4; i++) { - if (var->VariableName[i] > 127 || - hex_to_bin(var->VariableName[i] & 0xff) < 0) - return true; - } - - /* Reject it if there's 4 digits of hex and then further content */ - if (namelen > match + 4) - return false; - - /* A valid entry must be at least 8 bytes */ - if (len < 8) - return false; - - filepathlength = buffer[4] | buffer[5] << 8; - - /* - * There's no stored length for the description, so it has to be - * found by hand - */ - desclength = utf16_strsize((efi_char16_t *)(buffer + 6), len - 6) + 2; - - /* Each boot entry must have a descriptor */ - if (!desclength) - return false; - - /* - * If the sum of the length of the description, the claimed filepath - * length and the original header are greater than the length of the - * variable, it's malformed - */ - if ((desclength + filepathlength + 6) > len) - return false; - - /* - * And, finally, check the filepath - */ - return validate_device_path(var, match, buffer + desclength + 6, - filepathlength); -} - -static bool -validate_uint16(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - /* A single 16-bit integer */ - if (len != 2) - return false; - - return true; -} - -static bool -validate_ascii_string(struct efi_variable *var, int match, u8 *buffer, - unsigned long len) -{ - int i; - - for (i = 0; i < len; i++) { - if (buffer[i] > 127) - return false; - - if (buffer[i] == 0) - return true; - } - - return false; -} - -struct variable_validate { - char *name; - bool (*validate)(struct efi_variable *var, int match, u8 *data, - unsigned long len); -}; - -static const struct variable_validate variable_validate[] = { - { "BootNext", validate_uint16 }, - { "BootOrder", validate_boot_order }, - { "DriverOrder", validate_boot_order }, - { "Boot*", validate_load_option }, - { "Driver*", validate_load_option }, - { "ConIn", validate_device_path }, - { "ConInDev", validate_device_path }, - { "ConOut", validate_device_path }, - { "ConOutDev", validate_device_path }, - { "ErrOut", validate_device_path }, - { "ErrOutDev", validate_device_path }, - { "Timeout", validate_uint16 }, - { "Lang", validate_ascii_string }, - { "PlatformLang", validate_ascii_string }, - { "", NULL }, -}; - -static bool -validate_var(struct efi_variable *var, u8 *data, unsigned long len) -{ - int i; - u16 *unicode_name = var->VariableName; - - for (i = 0; variable_validate[i].validate != NULL; i++) { - const char *name = variable_validate[i].name; - int match; - - for (match = 0; ; match++) { - char c = name[match]; - u16 u = unicode_name[match]; - - /* All special variables are plain ascii */ - if (u > 127) - return true; - - /* Wildcard in the matching name means we've matched */ - if (c == '*') - return variable_validate[i].validate(var, - match, data, len); - - /* Case sensitive match */ - if (c != u) - break; - - /* Reached the end of the string while matching */ - if (!c) - return variable_validate[i].validate(var, - match, data, len); - } - } - - return true; -} - static efi_status_t get_var_data_locked(struct efivars *efivars, struct efi_variable *var) { @@ -508,12 +324,6 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) return -EINVAL; } - if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || - validate_var(new_var, new_var->Data, new_var->DataSize) == false) { - printk(KERN_ERR "efivars: Malformed variable content\n"); - return -EINVAL; - } - spin_lock(&efivars->lock); status = efivars->ops->set_variable(new_var->VariableName, &new_var->VendorGuid, @@ -816,12 +626,6 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if ((new_var->Attributes & ~EFI_VARIABLE_MASK) != 0 || - validate_var(new_var, new_var->Data, new_var->DataSize) == false) { - printk(KERN_ERR "efivars: Malformed variable content\n"); - return -EINVAL; - } - spin_lock(&efivars->lock); /* diff --git a/trunk/drivers/gpio/gpio-pxa.c b/trunk/drivers/gpio/gpio-pxa.c index fc3ace3fd4cb..5689ce62fd81 100644 --- a/trunk/drivers/gpio/gpio-pxa.c +++ b/trunk/drivers/gpio/gpio-pxa.c @@ -64,7 +64,6 @@ struct pxa_gpio_chip { unsigned long irq_mask; unsigned long irq_edge_rise; unsigned long irq_edge_fall; - int (*set_wake)(unsigned int gpio, unsigned int on); #ifdef CONFIG_PM unsigned long saved_gplr; @@ -270,8 +269,7 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) (value ? GPSR_OFFSET : GPCR_OFFSET)); } -static int __devinit pxa_init_gpio_chip(int gpio_end, - int (*set_wake)(unsigned int, unsigned int)) +static int __devinit pxa_init_gpio_chip(int gpio_end) { int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1; struct pxa_gpio_chip *chips; @@ -287,7 +285,6 @@ static int __devinit pxa_init_gpio_chip(int gpio_end, sprintf(chips[i].label, "gpio-%d", i); chips[i].regbase = gpio_reg_base + BANK_OFF(i); - chips[i].set_wake = set_wake; c->base = gpio; c->label = chips[i].label; @@ -415,17 +412,6 @@ static void pxa_mask_muxed_gpio(struct irq_data *d) writel_relaxed(gfer, c->regbase + GFER_OFFSET); } -static int pxa_gpio_set_wake(struct irq_data *d, unsigned int on) -{ - int gpio = pxa_irq_to_gpio(d->irq); - struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); - - if (c->set_wake) - return c->set_wake(gpio, on); - else - return 0; -} - static void pxa_unmask_muxed_gpio(struct irq_data *d) { int gpio = pxa_irq_to_gpio(d->irq); @@ -441,7 +427,6 @@ static struct irq_chip pxa_muxed_gpio_chip = { .irq_mask = pxa_mask_muxed_gpio, .irq_unmask = pxa_unmask_muxed_gpio, .irq_set_type = pxa_gpio_irq_type, - .irq_set_wake = pxa_gpio_set_wake, }; static int pxa_gpio_nums(void) @@ -486,7 +471,6 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) struct pxa_gpio_chip *c; struct resource *res; struct clk *clk; - struct pxa_gpio_platform_data *info; int gpio, irq, ret; int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; @@ -532,8 +516,7 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) } /* Initialize GPIO chips */ - info = dev_get_platdata(&pdev->dev); - pxa_init_gpio_chip(pxa_last_gpio, info ? info->gpio_set_wake : NULL); + pxa_init_gpio_chip(pxa_last_gpio); /* clear all GPIO edge detects */ for_each_gpio_chip(gpio, c) { diff --git a/trunk/drivers/gpu/drm/drm_bufs.c b/trunk/drivers/gpu/drm/drm_bufs.c index 348b367debeb..30372f7b2d45 100644 --- a/trunk/drivers/gpu/drm/drm_bufs.c +++ b/trunk/drivers/gpu/drm/drm_bufs.c @@ -1510,8 +1510,8 @@ int drm_freebufs(struct drm_device *dev, void *data, * \param arg pointer to a drm_buf_map structure. * \return zero on success or a negative number on failure. * - * Maps the AGP, SG or PCI buffer region with vm_mmap(), and copies information - * about each buffer into user space. For PCI buffers, it calls vm_mmap() with + * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information + * about each buffer into user space. For PCI buffers, it calls do_mmap() with * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls * drm_mmap_dma(). */ @@ -1553,14 +1553,18 @@ int drm_mapbufs(struct drm_device *dev, void *data, retcode = -EINVAL; goto done; } - virtual = vm_mmap(file_priv->filp, 0, map->size, + down_write(¤t->mm->mmap_sem); + virtual = do_mmap(file_priv->filp, 0, map->size, PROT_READ | PROT_WRITE, MAP_SHARED, token); + up_write(¤t->mm->mmap_sem); } else { - virtual = vm_mmap(file_priv->filp, 0, dma->byte_count, + down_write(¤t->mm->mmap_sem); + virtual = do_mmap(file_priv->filp, 0, dma->byte_count, PROT_READ | PROT_WRITE, MAP_SHARED, 0); + up_write(¤t->mm->mmap_sem); } if (virtual > -1024UL) { /* Real error */ diff --git a/trunk/drivers/gpu/drm/drm_crtc.c b/trunk/drivers/gpu/drm/drm_crtc.c index ee63a123235c..a9ca1b80fc28 100644 --- a/trunk/drivers/gpu/drm/drm_crtc.c +++ b/trunk/drivers/gpu/drm/drm_crtc.c @@ -2104,7 +2104,7 @@ int drm_mode_addfb(struct drm_device *dev, fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r); if (IS_ERR(fb)) { - DRM_DEBUG_KMS("could not create framebuffer\n"); + DRM_ERROR("could not create framebuffer\n"); ret = PTR_ERR(fb); goto out; } @@ -2193,7 +2193,7 @@ static int framebuffer_check(struct drm_mode_fb_cmd2 *r) ret = format_check(r); if (ret) { - DRM_DEBUG_KMS("bad framebuffer format 0x%08x\n", r->pixel_format); + DRM_ERROR("bad framebuffer format 0x%08x\n", r->pixel_format); return ret; } @@ -2202,12 +2202,12 @@ static int framebuffer_check(struct drm_mode_fb_cmd2 *r) num_planes = drm_format_num_planes(r->pixel_format); if (r->width == 0 || r->width % hsub) { - DRM_DEBUG_KMS("bad framebuffer width %u\n", r->height); + DRM_ERROR("bad framebuffer width %u\n", r->height); return -EINVAL; } if (r->height == 0 || r->height % vsub) { - DRM_DEBUG_KMS("bad framebuffer height %u\n", r->height); + DRM_ERROR("bad framebuffer height %u\n", r->height); return -EINVAL; } @@ -2215,12 +2215,12 @@ static int framebuffer_check(struct drm_mode_fb_cmd2 *r) unsigned int width = r->width / (i != 0 ? hsub : 1); if (!r->handles[i]) { - DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i); + DRM_ERROR("no buffer object handle for plane %d\n", i); return -EINVAL; } if (r->pitches[i] < drm_format_plane_cpp(r->pixel_format, i) * width) { - DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i); + DRM_ERROR("bad pitch %u for plane %d\n", r->pitches[i], i); return -EINVAL; } } @@ -2257,12 +2257,12 @@ int drm_mode_addfb2(struct drm_device *dev, return -EINVAL; if ((config->min_width > r->width) || (r->width > config->max_width)) { - DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n", + DRM_ERROR("bad framebuffer width %d, should be >= %d && <= %d\n", r->width, config->min_width, config->max_width); return -EINVAL; } if ((config->min_height > r->height) || (r->height > config->max_height)) { - DRM_DEBUG_KMS("bad framebuffer height %d, should be >= %d && <= %d\n", + DRM_ERROR("bad framebuffer height %d, should be >= %d && <= %d\n", r->height, config->min_height, config->max_height); return -EINVAL; } @@ -2275,7 +2275,7 @@ int drm_mode_addfb2(struct drm_device *dev, fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); if (IS_ERR(fb)) { - DRM_DEBUG_KMS("could not create framebuffer\n"); + DRM_ERROR("could not create framebuffer\n"); ret = PTR_ERR(fb); goto out; } @@ -3376,12 +3376,10 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, ret = crtc->funcs->page_flip(crtc, fb, e); if (ret) { - if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { - spin_lock_irqsave(&dev->event_lock, flags); - file_priv->event_space += sizeof e->event; - spin_unlock_irqrestore(&dev->event_lock, flags); - kfree(e); - } + spin_lock_irqsave(&dev->event_lock, flags); + file_priv->event_space += sizeof e->event; + spin_unlock_irqrestore(&dev->event_lock, flags); + kfree(e); } out: diff --git a/trunk/drivers/gpu/drm/drm_fops.c b/trunk/drivers/gpu/drm/drm_fops.c index 123de28f94ef..cdfbf27b2b3c 100644 --- a/trunk/drivers/gpu/drm/drm_fops.c +++ b/trunk/drivers/gpu/drm/drm_fops.c @@ -507,12 +507,12 @@ int drm_release(struct inode *inode, struct file *filp) drm_events_release(file_priv); - if (dev->driver->driver_features & DRIVER_MODESET) - drm_fb_release(file_priv); - if (dev->driver->driver_features & DRIVER_GEM) drm_gem_release(dev, file_priv); + if (dev->driver->driver_features & DRIVER_MODESET) + drm_fb_release(file_priv); + mutex_lock(&dev->ctxlist_mutex); if (!list_empty(&dev->ctxlist)) { struct drm_ctx_list *pos, *n; diff --git a/trunk/drivers/gpu/drm/drm_gem.c b/trunk/drivers/gpu/drm/drm_gem.c index 1ab29a7345c5..fc6ded8f318b 100644 --- a/trunk/drivers/gpu/drm/drm_gem.c +++ b/trunk/drivers/gpu/drm/drm_gem.c @@ -626,7 +626,7 @@ void drm_gem_vm_open(struct vm_area_struct *vma) drm_gem_object_reference(obj); mutex_lock(&obj->dev->struct_mutex); - drm_vm_open_locked(obj->dev, vma); + drm_vm_open_locked(vma); mutex_unlock(&obj->dev->struct_mutex); } EXPORT_SYMBOL(drm_gem_vm_open); @@ -637,7 +637,7 @@ void drm_gem_vm_close(struct vm_area_struct *vma) struct drm_device *dev = obj->dev; mutex_lock(&dev->struct_mutex); - drm_vm_close_locked(obj->dev, vma); + drm_vm_close_locked(vma); drm_gem_object_unreference(obj); mutex_unlock(&dev->struct_mutex); } @@ -710,7 +710,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) */ drm_gem_object_reference(obj); - drm_vm_open_locked(dev, vma); + drm_vm_open_locked(vma); out_unlock: mutex_unlock(&dev->struct_mutex); diff --git a/trunk/drivers/gpu/drm/drm_usb.c b/trunk/drivers/gpu/drm/drm_usb.c index 37c9a523dd1c..c8c83dad2ce1 100644 --- a/trunk/drivers/gpu/drm/drm_usb.c +++ b/trunk/drivers/gpu/drm/drm_usb.c @@ -1,6 +1,6 @@ #include "drmP.h" #include -#include +#include int drm_get_usb_dev(struct usb_interface *interface, const struct usb_device_id *id, @@ -114,7 +114,3 @@ void drm_usb_exit(struct drm_driver *driver, usb_deregister(udriver); } EXPORT_SYMBOL(drm_usb_exit); - -MODULE_AUTHOR("David Airlie"); -MODULE_DESCRIPTION("USB DRM support"); -MODULE_LICENSE("GPL and additional rights"); diff --git a/trunk/drivers/gpu/drm/drm_vm.c b/trunk/drivers/gpu/drm/drm_vm.c index 961ee08927fe..149561818349 100644 --- a/trunk/drivers/gpu/drm/drm_vm.c +++ b/trunk/drivers/gpu/drm/drm_vm.c @@ -406,9 +406,10 @@ static const struct vm_operations_struct drm_vm_sg_ops = { * Create a new drm_vma_entry structure as the \p vma private data entry and * add it to drm_device::vmalist. */ -void drm_vm_open_locked(struct drm_device *dev, - struct vm_area_struct *vma) +void drm_vm_open_locked(struct vm_area_struct *vma) { + struct drm_file *priv = vma->vm_file->private_data; + struct drm_device *dev = priv->minor->dev; struct drm_vma_entry *vma_entry; DRM_DEBUG("0x%08lx,0x%08lx\n", @@ -429,13 +430,14 @@ static void drm_vm_open(struct vm_area_struct *vma) struct drm_device *dev = priv->minor->dev; mutex_lock(&dev->struct_mutex); - drm_vm_open_locked(dev, vma); + drm_vm_open_locked(vma); mutex_unlock(&dev->struct_mutex); } -void drm_vm_close_locked(struct drm_device *dev, - struct vm_area_struct *vma) +void drm_vm_close_locked(struct vm_area_struct *vma) { + struct drm_file *priv = vma->vm_file->private_data; + struct drm_device *dev = priv->minor->dev; struct drm_vma_entry *pt, *temp; DRM_DEBUG("0x%08lx,0x%08lx\n", @@ -465,7 +467,7 @@ static void drm_vm_close(struct vm_area_struct *vma) struct drm_device *dev = priv->minor->dev; mutex_lock(&dev->struct_mutex); - drm_vm_close_locked(dev, vma); + drm_vm_close_locked(vma); mutex_unlock(&dev->struct_mutex); } @@ -517,7 +519,7 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; /* Don't swap */ vma->vm_flags |= VM_DONTEXPAND; - drm_vm_open_locked(dev, vma); + drm_vm_open_locked(vma); return 0; } @@ -668,7 +670,7 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; /* Don't swap */ vma->vm_flags |= VM_DONTEXPAND; - drm_vm_open_locked(dev, vma); + drm_vm_open_locked(vma); return 0; } diff --git a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c index 1dffa8359f88..26d51979116b 100644 --- a/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/trunk/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -149,12 +149,22 @@ static int exynos_drm_gem_map_pages(struct drm_gem_object *obj, unsigned long pfn; if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { + unsigned long usize = buf->size; + if (!buf->pages) return -EINTR; - pfn = page_to_pfn(buf->pages[page_offset++]); - } else - pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset; + while (usize > 0) { + pfn = page_to_pfn(buf->pages[page_offset++]); + vm_insert_mixed(vma, f_vaddr, pfn); + f_vaddr += PAGE_SIZE; + usize -= PAGE_SIZE; + } + + return 0; + } + + pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset; return vm_insert_mixed(vma, f_vaddr, pfn); } @@ -514,8 +524,6 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, if (!buffer->pages) return -EINVAL; - vma->vm_flags |= VM_MIXEDMAP; - do { ret = vm_insert_page(vma, uaddr, buffer->pages[i++]); if (ret) { @@ -573,8 +581,10 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data, obj->filp->f_op = &exynos_drm_gem_fops; obj->filp->private_data = obj; - addr = vm_mmap(obj->filp, 0, args->size, + down_write(¤t->mm->mmap_sem); + addr = do_mmap(obj->filp, 0, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, 0); + up_write(¤t->mm->mmap_sem); drm_gem_object_unreference_unlocked(obj); @@ -702,6 +712,7 @@ int exynos_drm_gem_dumb_destroy(struct drm_file *file_priv, int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { struct drm_gem_object *obj = vma->vm_private_data; + struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); struct drm_device *dev = obj->dev; unsigned long f_vaddr; pgoff_t page_offset; @@ -713,10 +724,21 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) mutex_lock(&dev->struct_mutex); + /* + * allocate all pages as desired size if user wants to allocate + * physically non-continuous memory. + */ + if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { + ret = exynos_drm_gem_get_pages(obj); + if (ret < 0) + goto err; + } + ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset); if (ret < 0) DRM_ERROR("failed to map pages.\n"); +err: mutex_unlock(&dev->struct_mutex); return convert_to_vm_err_msg(ret); diff --git a/trunk/drivers/gpu/drm/gma500/Makefile b/trunk/drivers/gpu/drm/gma500/Makefile index abfa2a93f0d0..1583982917ce 100644 --- a/trunk/drivers/gpu/drm/gma500/Makefile +++ b/trunk/drivers/gpu/drm/gma500/Makefile @@ -1,7 +1,7 @@ # # KMS driver for the GMA500 # -ccflags-y += -I$(srctree)/include/drm +ccflags-y += -Iinclude/drm gma500_gfx-y += gem_glue.o \ accel_2d.o \ @@ -12,6 +12,7 @@ gma500_gfx-y += gem_glue.o \ intel_bios.o \ intel_i2c.o \ intel_gmbus.o \ + intel_opregion.o \ mmu.o \ power.o \ psb_drv.o \ @@ -24,8 +25,6 @@ gma500_gfx-y += gem_glue.o \ psb_device.o \ mid_bios.o -gma500_gfx-$(CONFIG_ACPI) += opregion.o \ - gma500_gfx-$(CONFIG_DRM_GMA3600) += cdv_device.o \ cdv_intel_crt.o \ cdv_intel_display.o \ diff --git a/trunk/drivers/gpu/drm/gma500/cdv_device.c b/trunk/drivers/gpu/drm/gma500/cdv_device.c index 8e393303f53a..62f9b735459b 100644 --- a/trunk/drivers/gpu/drm/gma500/cdv_device.c +++ b/trunk/drivers/gpu/drm/gma500/cdv_device.c @@ -57,7 +57,8 @@ static int cdv_output_init(struct drm_device *dev) cdv_intel_crt_init(dev, &dev_priv->mode_dev); cdv_intel_lvds_init(dev, &dev_priv->mode_dev); - /* These bits indicate HDMI not SDVO on CDV */ + /* These bits indicate HDMI not SDVO on CDV, but we don't yet support + the HDMI interface */ if (REG_READ(SDVOB) & SDVO_DETECTED) cdv_hdmi_init(dev, &dev_priv->mode_dev, SDVOB); if (REG_READ(SDVOC) & SDVO_DETECTED) @@ -68,71 +69,76 @@ static int cdv_output_init(struct drm_device *dev) #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE /* - * Cedartrail Backlght Interfaces + * Poulsbo Backlight Interfaces */ -static struct backlight_device *cdv_backlight_device; +#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */ +#define BLC_PWM_FREQ_CALC_CONSTANT 32 +#define MHz 1000000 -static int cdv_backlight_combination_mode(struct drm_device *dev) -{ - return REG_READ(BLC_PWM_CTL2) & PWM_LEGACY_MODE; -} +#define PSB_BLC_PWM_PRECISION_FACTOR 10 +#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE +#define PSB_BLC_MIN_PWM_REG_FREQ 0x2 + +#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE) +#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16) + +static int cdv_brightness; +static struct backlight_device *cdv_backlight_device; static int cdv_get_brightness(struct backlight_device *bd) { - struct drm_device *dev = bl_get_data(bd); - u32 val = REG_READ(BLC_PWM_CTL) & BACKLIGHT_DUTY_CYCLE_MASK; + /* return locally cached var instead of HW read (due to DPST etc.) */ + /* FIXME: ideally return actual value in case firmware fiddled with + it */ + return cdv_brightness; +} - if (cdv_backlight_combination_mode(dev)) { - u8 lbpc; - val &= ~1; - pci_read_config_byte(dev->pdev, 0xF4, &lbpc); - val *= lbpc; +static int cdv_backlight_setup(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + unsigned long core_clock; + /* u32 bl_max_freq; */ + /* unsigned long value; */ + u16 bl_max_freq; + uint32_t value; + uint32_t blc_pwm_precision_factor; + + /* get bl_max_freq and pol from dev_priv*/ + if (!dev_priv->lvds_bl) { + dev_err(dev->dev, "Has no valid LVDS backlight info\n"); + return -ENOENT; } - return val; -} + bl_max_freq = dev_priv->lvds_bl->freq; + blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR; -static u32 cdv_get_max_backlight(struct drm_device *dev) -{ - u32 max = REG_READ(BLC_PWM_CTL); + core_clock = dev_priv->core_freq; - if (max == 0) { - DRM_DEBUG_KMS("LVDS Panel PWM value is 0!\n"); - /* i915 does this, I believe which means that we should not - * smash PWM control as firmware will take control of it. */ - return 1; - } + value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT; + value *= blc_pwm_precision_factor; + value /= bl_max_freq; + value /= blc_pwm_precision_factor; - max >>= 16; - if (cdv_backlight_combination_mode(dev)) - max *= 0xff; - return max; + if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ || + value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ) + return -ERANGE; + else { + /* FIXME */ + } + return 0; } static int cdv_set_brightness(struct backlight_device *bd) { - struct drm_device *dev = bl_get_data(bd); int level = bd->props.brightness; - u32 blc_pwm_ctl; /* Percentage 1-100% being valid */ if (level < 1) level = 1; - if (cdv_backlight_combination_mode(dev)) { - u32 max = cdv_get_max_backlight(dev); - u8 lbpc; - - lbpc = level * 0xfe / max + 1; - level /= lbpc; - - pci_write_config_byte(dev->pdev, 0xF4, lbpc); - } - - blc_pwm_ctl = REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; - REG_WRITE(BLC_PWM_CTL, (blc_pwm_ctl | - (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); + /*cdv_intel_lvds_set_brightness(dev, level); FIXME */ + cdv_brightness = level; return 0; } @@ -144,6 +150,7 @@ static const struct backlight_ops cdv_ops = { static int cdv_backlight_init(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; + int ret; struct backlight_properties props; memset(&props, 0, sizeof(struct backlight_properties)); @@ -155,9 +162,14 @@ static int cdv_backlight_init(struct drm_device *dev) if (IS_ERR(cdv_backlight_device)) return PTR_ERR(cdv_backlight_device); - cdv_backlight_device->props.brightness = - cdv_get_brightness(cdv_backlight_device); - cdv_backlight_device->props.max_brightness = cdv_get_max_backlight(dev); + ret = cdv_backlight_setup(dev); + if (ret < 0) { + backlight_device_unregister(cdv_backlight_device); + cdv_backlight_device = NULL; + return ret; + } + cdv_backlight_device->props.brightness = 100; + cdv_backlight_device->props.max_brightness = 100; backlight_update_status(cdv_backlight_device); dev_priv->backlight_device = cdv_backlight_device; return 0; @@ -232,12 +244,11 @@ static void cdv_init_pm(struct drm_device *dev) static void cdv_errata(struct drm_device *dev) { /* Disable bonus launch. - * CPU and GPU competes for memory and display misses updates and - * flickers. Worst with dual core, dual displays. + * CPU and GPU competes for memory and display misses updates and flickers. + * Worst with dual core, dual displays. * - * Fixes were done to Win 7 gfx driver to disable a feature called - * Bonus Launch to work around the issue, by degrading - * performance. + * Fixes were done to Win 7 gfx driver to disable a feature called Bonus + * Launch to work around the issue, by degrading performance. */ CDV_MSG_WRITE32(3, 0x30, 0x08027108); } @@ -255,7 +266,7 @@ static int cdv_save_display_registers(struct drm_device *dev) struct psb_save_area *regs = &dev_priv->regs; struct drm_connector *connector; - dev_dbg(dev->dev, "Saving GPU registers.\n"); + dev_info(dev->dev, "Saving GPU registers.\n"); pci_read_config_byte(dev->pdev, 0xF4, ®s->cdv.saveLBB); @@ -485,70 +496,12 @@ static void cdv_hotplug_enable(struct drm_device *dev, bool on) } } -/* Cedarview */ -static const struct psb_offset cdv_regmap[2] = { - { - .fp0 = FPA0, - .fp1 = FPA1, - .cntr = DSPACNTR, - .conf = PIPEACONF, - .src = PIPEASRC, - .dpll = DPLL_A, - .dpll_md = DPLL_A_MD, - .htotal = HTOTAL_A, - .hblank = HBLANK_A, - .hsync = HSYNC_A, - .vtotal = VTOTAL_A, - .vblank = VBLANK_A, - .vsync = VSYNC_A, - .stride = DSPASTRIDE, - .size = DSPASIZE, - .pos = DSPAPOS, - .base = DSPABASE, - .surf = DSPASURF, - .addr = DSPABASE, - .status = PIPEASTAT, - .linoff = DSPALINOFF, - .tileoff = DSPATILEOFF, - .palette = PALETTE_A, - }, - { - .fp0 = FPB0, - .fp1 = FPB1, - .cntr = DSPBCNTR, - .conf = PIPEBCONF, - .src = PIPEBSRC, - .dpll = DPLL_B, - .dpll_md = DPLL_B_MD, - .htotal = HTOTAL_B, - .hblank = HBLANK_B, - .hsync = HSYNC_B, - .vtotal = VTOTAL_B, - .vblank = VBLANK_B, - .vsync = VSYNC_B, - .stride = DSPBSTRIDE, - .size = DSPBSIZE, - .pos = DSPBPOS, - .base = DSPBBASE, - .surf = DSPBSURF, - .addr = DSPBBASE, - .status = PIPEBSTAT, - .linoff = DSPBLINOFF, - .tileoff = DSPBTILEOFF, - .palette = PALETTE_B, - } -}; - static int cdv_chip_setup(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; INIT_WORK(&dev_priv->hotplug_work, cdv_hotplug_work_func); - - if (pci_enable_msi(dev->pdev)) - dev_warn(dev->dev, "Enabling MSI failed!\n"); - dev_priv->regmap = cdv_regmap; cdv_get_core_freq(dev); - psb_intel_opregion_init(dev); + gma_intel_opregion_init(dev); psb_intel_init_bios(dev); cdv_hotplug_enable(dev, false); return 0; diff --git a/trunk/drivers/gpu/drm/gma500/cdv_intel_display.c b/trunk/drivers/gpu/drm/gma500/cdv_intel_display.c index c3e9a0f701df..2fab77854971 100644 --- a/trunk/drivers/gpu/drm/gma500/cdv_intel_display.c +++ b/trunk/drivers/gpu/drm/gma500/cdv_intel_display.c @@ -218,7 +218,8 @@ static int cdv_dpll_set_clock_cdv(struct drm_device *dev, struct drm_crtc *crtc, struct cdv_intel_clock_t *clock, bool is_lvds) { - struct psb_intel_crtc *psb_crtc = to_psb_intel_crtc(crtc); + struct psb_intel_crtc *psb_crtc = + to_psb_intel_crtc(crtc); int pipe = psb_crtc->pipe; u32 m, n_vco, p; int ret = 0; @@ -502,12 +503,14 @@ static int cdv_intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; unsigned long start, offset; + int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE); + int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); + int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; u32 dspcntr; int ret = 0; @@ -529,9 +532,9 @@ static int cdv_intel_pipe_set_base(struct drm_crtc *crtc, start = psbfb->gtt->offset; offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); - REG_WRITE(map->stride, crtc->fb->pitches[0]); + REG_WRITE(dspstride, crtc->fb->pitches[0]); - dspcntr = REG_READ(map->cntr); + dspcntr = REG_READ(dspcntr_reg); dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; switch (crtc->fb->bits_per_pixel) { @@ -553,15 +556,15 @@ static int cdv_intel_pipe_set_base(struct drm_crtc *crtc, ret = -EINVAL; goto psb_intel_pipe_set_base_exit; } - REG_WRITE(map->cntr, dspcntr); + REG_WRITE(dspcntr_reg, dspcntr); dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n", start, offset, x, y); - REG_WRITE(map->base, offset); - REG_READ(map->base); - REG_WRITE(map->surf, start); - REG_READ(map->surf); + REG_WRITE(dspbase, offset); + REG_READ(dspbase); + REG_WRITE(dspsurf, start); + REG_READ(dspsurf); psb_intel_pipe_cleaner: /* If there was a previous display we can now unpin it */ @@ -718,7 +721,8 @@ static void cdv_intel_update_watermark (struct drm_device *dev, struct drm_crtc static void cdv_intel_crtc_load_lut(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); int palreg = PALETTE_A; int i; @@ -754,7 +758,7 @@ static void cdv_intel_crtc_load_lut(struct drm_crtc *crtc) gma_power_end(dev); } else { for (i = 0; i < 256; i++) { - dev_priv->regs.pipe[0].palette[i] = + dev_priv->regs.psb.save_palette_a[i] = ((psb_intel_crtc->lut_r[i] + psb_intel_crtc->lut_adj[i]) << 16) | ((psb_intel_crtc->lut_g[i] + @@ -775,10 +779,13 @@ static void cdv_intel_crtc_load_lut(struct drm_crtc *crtc) static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; + int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + int pipestat_reg = (pipe == 0) ? PIPEASTAT : PIPEBSTAT; u32 temp; /* XXX: When our outputs are all unaware of DPMS modes other than off @@ -796,44 +803,44 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) psb_intel_crtc->active = true; /* Enable the DPLL */ - temp = REG_READ(map->dpll); + temp = REG_READ(dpll_reg); if ((temp & DPLL_VCO_ENABLE) == 0) { - REG_WRITE(map->dpll, temp); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); - REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); - REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); } /* Jim Bish - switch plan and pipe per scott */ /* Enable the plane */ - temp = REG_READ(map->cntr); + temp = REG_READ(dspcntr_reg); if ((temp & DISPLAY_PLANE_ENABLE) == 0) { - REG_WRITE(map->cntr, + REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE); /* Flush the plane changes */ - REG_WRITE(map->base, REG_READ(map->base)); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); } udelay(150); /* Enable the pipe */ - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); if ((temp & PIPEACONF_ENABLE) == 0) - REG_WRITE(map->conf, temp | PIPEACONF_ENABLE); + REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); - temp = REG_READ(map->status); + temp = REG_READ(pipestat_reg); temp &= ~(0xFFFF); temp |= PIPE_FIFO_UNDERRUN; - REG_WRITE(map->status, temp); - REG_READ(map->status); + REG_WRITE(pipestat_reg, temp); + REG_READ(pipestat_reg); cdv_intel_update_watermark(dev, crtc); cdv_intel_crtc_load_lut(crtc); @@ -863,10 +870,10 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) cdv_intel_wait_for_vblank(dev); /* Next, disable display pipes */ - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); if ((temp & PIPEACONF_ENABLE) != 0) { - REG_WRITE(map->conf, temp & ~PIPEACONF_ENABLE); - REG_READ(map->conf); + REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); + REG_READ(pipeconf_reg); } /* Wait for vblank for the disable to take effect. */ @@ -875,19 +882,19 @@ static void cdv_intel_crtc_dpms(struct drm_crtc *crtc, int mode) udelay(150); /* Disable display plane */ - temp = REG_READ(map->cntr); + temp = REG_READ(dspcntr_reg); if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - REG_WRITE(map->cntr, + REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); /* Flush the plane changes */ - REG_WRITE(map->base, REG_READ(map->base)); - REG_READ(map->base); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + REG_READ(dspbase_reg); } - temp = REG_READ(map->dpll); + temp = REG_READ(dpll_reg); if ((temp & DPLL_VCO_ENABLE) != 0) { - REG_WRITE(map->dpll, temp & ~DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); + REG_READ(dpll_reg); } /* Wait for the clocks to turn off. */ @@ -946,7 +953,19 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, struct drm_psb_private *dev_priv = dev->dev_private; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; + int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; + int dpll_md_reg = (psb_intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; + int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; + int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; + int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; + int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; + int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; + int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; + int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; + int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; int refclk; struct cdv_intel_clock_t clock; u32 dpll = 0, dspcntr, pipeconf; @@ -1017,7 +1036,7 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, /* dpll |= (2 << 11); */ /* setup pipeconf */ - pipeconf = REG_READ(map->conf); + pipeconf = REG_READ(pipeconf_reg); /* Set up the display plane register */ dspcntr = DISPPLANE_GAMMA_ENABLE; @@ -1030,8 +1049,8 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, dspcntr |= DISPLAY_PLANE_ENABLE; pipeconf |= PIPEACONF_ENABLE; - REG_WRITE(map->dpll, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, dpll | DPLL_VGA_MODE_DIS | DPLL_SYNCLOCK_ENABLE); + REG_READ(dpll_reg); cdv_dpll_set_clock_cdv(dev, crtc, &clock, is_lvds); @@ -1075,48 +1094,48 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); drm_mode_debug_printmodeline(mode); - REG_WRITE(map->dpll, - (REG_READ(map->dpll) & ~DPLL_LOCK) | DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, + (REG_READ(dpll_reg) & ~DPLL_LOCK) | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); /* 42 usec w/o calibration, 110 with. rounded up. */ - if (!(REG_READ(map->dpll) & DPLL_LOCK)) { + if (!(REG_READ(dpll_reg) & DPLL_LOCK)) { dev_err(dev->dev, "Failed to get DPLL lock\n"); return -EBUSY; } { int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; - REG_WRITE(map->dpll_md, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); + REG_WRITE(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); } - REG_WRITE(map->htotal, (adjusted_mode->crtc_hdisplay - 1) | + REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - 1) | + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16)); - REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - 1) | + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16)); - REG_WRITE(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) | + REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - 1) | + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16)); - REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - 1) | + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); /* pipesrc and dspsize control the size that is scaled from, * which should always be the user's requested size. */ - REG_WRITE(map->size, + REG_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); - REG_WRITE(map->pos, 0); - REG_WRITE(map->src, + REG_WRITE(dsppos_reg, 0); + REG_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - REG_WRITE(map->conf, pipeconf); - REG_READ(map->conf); + REG_WRITE(pipeconf_reg, pipeconf); + REG_READ(pipeconf_reg); cdv_intel_wait_for_vblank(dev); - REG_WRITE(map->cntr, dspcntr); + REG_WRITE(dspcntr_reg, dspcntr); /* Flush the plane changes */ { @@ -1137,10 +1156,11 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, static void cdv_intel_crtc_save(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; + /* struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; */ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; - const struct psb_offset *map = &dev_priv->regmap[psb_intel_crtc->pipe]; + int pipeA = (psb_intel_crtc->pipe == 0); uint32_t paletteReg; int i; @@ -1149,25 +1169,25 @@ static void cdv_intel_crtc_save(struct drm_crtc *crtc) return; } - crtc_state->saveDSPCNTR = REG_READ(map->cntr); - crtc_state->savePIPECONF = REG_READ(map->conf); - crtc_state->savePIPESRC = REG_READ(map->src); - crtc_state->saveFP0 = REG_READ(map->fp0); - crtc_state->saveFP1 = REG_READ(map->fp1); - crtc_state->saveDPLL = REG_READ(map->dpll); - crtc_state->saveHTOTAL = REG_READ(map->htotal); - crtc_state->saveHBLANK = REG_READ(map->hblank); - crtc_state->saveHSYNC = REG_READ(map->hsync); - crtc_state->saveVTOTAL = REG_READ(map->vtotal); - crtc_state->saveVBLANK = REG_READ(map->vblank); - crtc_state->saveVSYNC = REG_READ(map->vsync); - crtc_state->saveDSPSTRIDE = REG_READ(map->stride); + crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR); + crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF); + crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC); + crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0); + crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1); + crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B); + crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B); + crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B); + crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B); + crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B); + crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B); + crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B); + crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE); /*NOTE: DSPSIZE DSPPOS only for psb*/ - crtc_state->saveDSPSIZE = REG_READ(map->size); - crtc_state->saveDSPPOS = REG_READ(map->pos); + crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE); + crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS); - crtc_state->saveDSPBASE = REG_READ(map->base); + crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE); DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", crtc_state->saveDSPCNTR, @@ -1188,7 +1208,7 @@ static void cdv_intel_crtc_save(struct drm_crtc *crtc) crtc_state->saveDSPBASE ); - paletteReg = map->palette; + paletteReg = pipeA ? PALETTE_A : PALETTE_B; for (i = 0; i < 256; ++i) crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2)); } @@ -1199,10 +1219,12 @@ static void cdv_intel_crtc_save(struct drm_crtc *crtc) static void cdv_intel_crtc_restore(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; + /* struct drm_psb_private * dev_priv = + (struct drm_psb_private *)dev->dev_private; */ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; - const struct psb_offset *map = &dev_priv->regmap[psb_intel_crtc->pipe]; + /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */ + int pipeA = (psb_intel_crtc->pipe == 0); uint32_t paletteReg; int i; @@ -1213,23 +1235,23 @@ static void cdv_intel_crtc_restore(struct drm_crtc *crtc) DRM_DEBUG( "current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", - REG_READ(map->cntr), - REG_READ(map->conf), - REG_READ(map->src), - REG_READ(map->fp0), - REG_READ(map->fp1), - REG_READ(map->dpll), - REG_READ(map->htotal), - REG_READ(map->hblank), - REG_READ(map->hsync), - REG_READ(map->vtotal), - REG_READ(map->vblank), - REG_READ(map->vsync), - REG_READ(map->stride), - REG_READ(map->size), - REG_READ(map->pos), - REG_READ(map->base) - ); + REG_READ(pipeA ? DSPACNTR : DSPBCNTR), + REG_READ(pipeA ? PIPEACONF : PIPEBCONF), + REG_READ(pipeA ? PIPEASRC : PIPEBSRC), + REG_READ(pipeA ? FPA0 : FPB0), + REG_READ(pipeA ? FPA1 : FPB1), + REG_READ(pipeA ? DPLL_A : DPLL_B), + REG_READ(pipeA ? HTOTAL_A : HTOTAL_B), + REG_READ(pipeA ? HBLANK_A : HBLANK_B), + REG_READ(pipeA ? HSYNC_A : HSYNC_B), + REG_READ(pipeA ? VTOTAL_A : VTOTAL_B), + REG_READ(pipeA ? VBLANK_A : VBLANK_B), + REG_READ(pipeA ? VSYNC_A : VSYNC_B), + REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE), + REG_READ(pipeA ? DSPASIZE : DSPBSIZE), + REG_READ(pipeA ? DSPAPOS : DSPBPOS), + REG_READ(pipeA ? DSPABASE : DSPBBASE) + ); DRM_DEBUG( "saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n", @@ -1249,51 +1271,51 @@ static void cdv_intel_crtc_restore(struct drm_crtc *crtc) crtc_state->saveDSPSIZE, crtc_state->saveDSPPOS, crtc_state->saveDSPBASE - ); + ); if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) { - REG_WRITE(map->dpll, - crtc_state->saveDPLL & ~DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(pipeA ? DPLL_A : DPLL_B, + crtc_state->saveDPLL & ~DPLL_VCO_ENABLE); + REG_READ(pipeA ? DPLL_A : DPLL_B); DRM_DEBUG("write dpll: %x\n", - REG_READ(map->dpll)); + REG_READ(pipeA ? DPLL_A : DPLL_B)); udelay(150); } - REG_WRITE(map->fp0, crtc_state->saveFP0); - REG_READ(map->fp0); + REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0); + REG_READ(pipeA ? FPA0 : FPB0); - REG_WRITE(map->fp1, crtc_state->saveFP1); - REG_READ(map->fp1); + REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1); + REG_READ(pipeA ? FPA1 : FPB1); - REG_WRITE(map->dpll, crtc_state->saveDPLL); - REG_READ(map->dpll); + REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL); + REG_READ(pipeA ? DPLL_A : DPLL_B); udelay(150); - REG_WRITE(map->htotal, crtc_state->saveHTOTAL); - REG_WRITE(map->hblank, crtc_state->saveHBLANK); - REG_WRITE(map->hsync, crtc_state->saveHSYNC); - REG_WRITE(map->vtotal, crtc_state->saveVTOTAL); - REG_WRITE(map->vblank, crtc_state->saveVBLANK); - REG_WRITE(map->vsync, crtc_state->saveVSYNC); - REG_WRITE(map->stride, crtc_state->saveDSPSTRIDE); + REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL); + REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK); + REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC); + REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL); + REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK); + REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC); + REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE); - REG_WRITE(map->size, crtc_state->saveDSPSIZE); - REG_WRITE(map->pos, crtc_state->saveDSPPOS); + REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE); + REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS); - REG_WRITE(map->src, crtc_state->savePIPESRC); - REG_WRITE(map->base, crtc_state->saveDSPBASE); - REG_WRITE(map->conf, crtc_state->savePIPECONF); + REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC); + REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); + REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF); cdv_intel_wait_for_vblank(dev); - REG_WRITE(map->cntr, crtc_state->saveDSPCNTR); - REG_WRITE(map->base, crtc_state->saveDSPBASE); + REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR); + REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); cdv_intel_wait_for_vblank(dev); - paletteReg = map->palette; + paletteReg = pipeA ? PALETTE_A : PALETTE_B; for (i = 0; i < 256; ++i) REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]); } @@ -1468,30 +1490,35 @@ static void i8xx_clock(int refclk, struct cdv_intel_clock_t *clock) static int cdv_intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) { - struct drm_psb_private *dev_priv = dev->dev_private; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; u32 dpll; u32 fp; struct cdv_intel_clock_t clock; bool is_lvds; - struct psb_pipe *p = &dev_priv->regs.pipe[pipe]; + struct drm_psb_private *dev_priv = dev->dev_private; if (gma_power_begin(dev, false)) { - dpll = REG_READ(map->dpll); + dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B); if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = REG_READ(map->fp0); + fp = REG_READ((pipe == 0) ? FPA0 : FPB0); else - fp = REG_READ(map->fp1); + fp = REG_READ((pipe == 0) ? FPA1 : FPB1); is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN); gma_power_end(dev); } else { - dpll = p->dpll; + dpll = (pipe == 0) ? + dev_priv->regs.psb.saveDPLL_A : + dev_priv->regs.psb.saveDPLL_B; + if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = p->fp0; + fp = (pipe == 0) ? + dev_priv->regs.psb.saveFPA0 : + dev_priv->regs.psb.saveFPB0; else - fp = p->fp1; + fp = (pipe == 0) ? + dev_priv->regs.psb.saveFPA1 : + dev_priv->regs.psb.saveFPB1; is_lvds = (pipe == 1) && (dev_priv->regs.psb.saveLVDS & LVDS_PORT_EN); @@ -1549,26 +1576,32 @@ struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev, { struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); int pipe = psb_intel_crtc->pipe; - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_pipe *p = &dev_priv->regs.pipe[pipe]; - const struct psb_offset *map = &dev_priv->regmap[pipe]; struct drm_display_mode *mode; int htot; int hsync; int vtot; int vsync; + struct drm_psb_private *dev_priv = dev->dev_private; if (gma_power_begin(dev, false)) { - htot = REG_READ(map->htotal); - hsync = REG_READ(map->hsync); - vtot = REG_READ(map->vtotal); - vsync = REG_READ(map->vsync); + htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B); + hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B); + vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B); + vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B); gma_power_end(dev); } else { - htot = p->htotal; - hsync = p->hsync; - vtot = p->vtotal; - vsync = p->vsync; + htot = (pipe == 0) ? + dev_priv->regs.psb.saveHTOTAL_A : + dev_priv->regs.psb.saveHTOTAL_B; + hsync = (pipe == 0) ? + dev_priv->regs.psb.saveHSYNC_A : + dev_priv->regs.psb.saveHSYNC_B; + vtot = (pipe == 0) ? + dev_priv->regs.psb.saveVTOTAL_A : + dev_priv->regs.psb.saveVTOTAL_B; + vsync = (pipe == 0) ? + dev_priv->regs.psb.saveVSYNC_A : + dev_priv->regs.psb.saveVSYNC_B; } mode = kzalloc(sizeof(*mode), GFP_KERNEL); diff --git a/trunk/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/trunk/drivers/gpu/drm/gma500/cdv_intel_lvds.c index ff5b58eb878c..44a8353d92bf 100644 --- a/trunk/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/trunk/drivers/gpu/drm/gma500/cdv_intel_lvds.c @@ -556,7 +556,7 @@ static void cdv_intel_lvds_enc_destroy(struct drm_encoder *encoder) drm_encoder_cleanup(encoder); } -static const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = { +const struct drm_encoder_funcs cdv_intel_lvds_enc_funcs = { .destroy = cdv_intel_lvds_enc_destroy, }; diff --git a/trunk/drivers/gpu/drm/gma500/framebuffer.c b/trunk/drivers/gpu/drm/gma500/framebuffer.c index 659ed3933b5b..c9fe4bdeb681 100644 --- a/trunk/drivers/gpu/drm/gma500/framebuffer.c +++ b/trunk/drivers/gpu/drm/gma500/framebuffer.c @@ -408,8 +408,6 @@ static int psbfb_create(struct psb_fbdev *fbdev, return -ENOMEM; } - memset(dev_priv->vram_addr + backing->offset, 0, size); - mutex_lock(&dev->struct_mutex); info = framebuffer_alloc(0, device); @@ -455,7 +453,8 @@ static int psbfb_create(struct psb_fbdev *fbdev, info->fix.ypanstep = 0; /* Accessed stolen memory directly */ - info->screen_base = dev_priv->vram_addr + backing->offset; + info->screen_base = (char *)dev_priv->vram_addr + + backing->offset; info->screen_size = size; if (dev_priv->gtt.stolen_size) { @@ -476,7 +475,7 @@ static int psbfb_create(struct psb_fbdev *fbdev, /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ - dev_dbg(dev->dev, "allocated %dx%d fb\n", + dev_info(dev->dev, "allocated %dx%d fb\n", psbfb->base.width, psbfb->base.height); mutex_unlock(&dev->struct_mutex); @@ -572,7 +571,7 @@ static int psbfb_probe(struct drm_fb_helper *helper, return new_fb; } -static struct drm_fb_helper_funcs psb_fb_helper_funcs = { +struct drm_fb_helper_funcs psb_fb_helper_funcs = { .gamma_set = psbfb_gamma_set, .gamma_get = psbfb_gamma_get, .fb_probe = psbfb_probe, diff --git a/trunk/drivers/gpu/drm/gma500/gtt.c b/trunk/drivers/gpu/drm/gma500/gtt.c index 04a371aceb34..54e5c9e1e6fa 100644 --- a/trunk/drivers/gpu/drm/gma500/gtt.c +++ b/trunk/drivers/gpu/drm/gma500/gtt.c @@ -61,7 +61,7 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type) * Given a gtt_range object return the GTT offset of the page table * entries for this gtt_range */ -static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) +static u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) { struct drm_psb_private *dev_priv = dev->dev_private; unsigned long offset; @@ -82,8 +82,7 @@ static u32 __iomem *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) */ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) { - u32 __iomem *gtt_slot; - u32 pte; + u32 *gtt_slot, pte; struct page **pages; int i; @@ -127,8 +126,7 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) { struct drm_psb_private *dev_priv = dev->dev_private; - u32 __iomem *gtt_slot; - u32 pte; + u32 *gtt_slot, pte; int i; WARN_ON(r->stolen); @@ -154,8 +152,7 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) */ void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll) { - u32 __iomem *gtt_slot; - u32 pte; + u32 *gtt_slot, pte; int i; if (roll >= r->npage) { @@ -416,6 +413,8 @@ int psb_gtt_init(struct drm_device *dev, int resume) unsigned long stolen_size, vram_stolen_size; unsigned i, num_pages; unsigned pfn_base; + uint32_t vram_pages; + uint32_t dvmt_mode = 0; struct psb_gtt *pg; int ret = 0; @@ -488,8 +487,13 @@ int psb_gtt_init(struct drm_device *dev, int resume) stolen_size = vram_stolen_size; - dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n", - dev_priv->stolen_base, vram_stolen_size / 1024); + printk(KERN_INFO "Stolen memory information\n"); + printk(KERN_INFO " base in RAM: 0x%x\n", dev_priv->stolen_base); + printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n", + vram_stolen_size/1024); + dvmt_mode = (dev_priv->gmch_ctrl >> 4) & 0x7; + printk(KERN_INFO " the correct size should be: %dM(dvmt mode=%d)\n", + (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode); if (resume && (gtt_pages != pg->gtt_pages) && (stolen_size != pg->stolen_size)) { @@ -525,8 +529,8 @@ int psb_gtt_init(struct drm_device *dev, int resume) */ pfn_base = dev_priv->stolen_base >> PAGE_SHIFT; - num_pages = vram_stolen_size >> PAGE_SHIFT; - dev_dbg(dev->dev, "Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n", + vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT; + printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n", num_pages, pfn_base << PAGE_SHIFT, 0); for (i = 0; i < num_pages; ++i) { pte = psb_gtt_mask_pte(pfn_base + i, 0); diff --git a/trunk/drivers/gpu/drm/gma500/intel_opregion.c b/trunk/drivers/gpu/drm/gma500/intel_opregion.c new file mode 100644 index 000000000000..7041f40affff --- /dev/null +++ b/trunk/drivers/gpu/drm/gma500/intel_opregion.c @@ -0,0 +1,178 @@ +/* + * Copyright 2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * FIXME: resolve with the i915 version + */ + +#include "psb_drv.h" + +#define PCI_ASLE 0xe4 +#define PCI_ASLS 0xfc + +#define OPREGION_HEADER_OFFSET 0 +#define OPREGION_ACPI_OFFSET 0x100 +#define ACPI_CLID 0x01ac /* current lid state indicator */ +#define ACPI_CDCK 0x01b0 /* current docking state indicator */ +#define OPREGION_SWSCI_OFFSET 0x200 +#define OPREGION_ASLE_OFFSET 0x300 +#define OPREGION_VBT_OFFSET 0x400 + +#define OPREGION_SIGNATURE "IntelGraphicsMem" +#define MBOX_ACPI (1<<0) +#define MBOX_SWSCI (1<<1) +#define MBOX_ASLE (1<<2) + +struct opregion_header { + u8 signature[16]; + u32 size; + u32 opregion_ver; + u8 bios_ver[32]; + u8 vbios_ver[16]; + u8 driver_ver[16]; + u32 mboxes; + u8 reserved[164]; +} __packed; + +/* OpRegion mailbox #1: public ACPI methods */ +struct opregion_acpi { + u32 drdy; /* driver readiness */ + u32 csts; /* notification status */ + u32 cevt; /* current event */ + u8 rsvd1[20]; + u32 didl[8]; /* supported display devices ID list */ + u32 cpdl[8]; /* currently presented display list */ + u32 cadl[8]; /* currently active display list */ + u32 nadl[8]; /* next active devices list */ + u32 aslp; /* ASL sleep time-out */ + u32 tidx; /* toggle table index */ + u32 chpd; /* current hotplug enable indicator */ + u32 clid; /* current lid state*/ + u32 cdck; /* current docking state */ + u32 sxsw; /* Sx state resume */ + u32 evts; /* ASL supported events */ + u32 cnot; /* current OS notification */ + u32 nrdy; /* driver status */ + u8 rsvd2[60]; +} __attribute__((packed)); + +/* OpRegion mailbox #2: SWSCI */ +struct opregion_swsci { + u32 scic; /* SWSCI command|status|data */ + u32 parm; /* command parameters */ + u32 dslp; /* driver sleep time-out */ + u8 rsvd[244]; +} __attribute__((packed)); + +/* OpRegion mailbox #3: ASLE */ +struct opregion_asle { + u32 ardy; /* driver readiness */ + u32 aslc; /* ASLE interrupt command */ + u32 tche; /* technology enabled indicator */ + u32 alsi; /* current ALS illuminance reading */ + u32 bclp; /* backlight brightness to set */ + u32 pfit; /* panel fitting state */ + u32 cblv; /* current brightness level */ + u16 bclm[20]; /* backlight level duty cycle mapping table */ + u32 cpfm; /* current panel fitting mode */ + u32 epfm; /* enabled panel fitting modes */ + u8 plut[74]; /* panel LUT and identifier */ + u32 pfmb; /* PWM freq and min brightness */ + u8 rsvd[102]; +} __attribute__((packed)); + +/* ASLE irq request bits */ +#define ASLE_SET_ALS_ILLUM (1 << 0) +#define ASLE_SET_BACKLIGHT (1 << 1) +#define ASLE_SET_PFIT (1 << 2) +#define ASLE_SET_PWM_FREQ (1 << 3) +#define ASLE_REQ_MSK 0xf + +/* response bits of ASLE irq request */ +#define ASLE_ALS_ILLUM_FAILED (1<<10) +#define ASLE_BACKLIGHT_FAILED (1<<12) +#define ASLE_PFIT_FAILED (1<<14) +#define ASLE_PWM_FREQ_FAILED (1<<16) + +/* ASLE backlight brightness to set */ +#define ASLE_BCLP_VALID (1<<31) +#define ASLE_BCLP_MSK (~(1<<31)) + +/* ASLE panel fitting request */ +#define ASLE_PFIT_VALID (1<<31) +#define ASLE_PFIT_CENTER (1<<0) +#define ASLE_PFIT_STRETCH_TEXT (1<<1) +#define ASLE_PFIT_STRETCH_GFX (1<<2) + +/* PWM frequency and minimum brightness */ +#define ASLE_PFMB_BRIGHTNESS_MASK (0xff) +#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8) +#define ASLE_PFMB_PWM_MASK (0x7ffffe00) +#define ASLE_PFMB_PWM_VALID (1<<31) + +#define ASLE_CBLV_VALID (1<<31) + +#define ACPI_OTHER_OUTPUT (0<<8) +#define ACPI_VGA_OUTPUT (1<<8) +#define ACPI_TV_OUTPUT (2<<8) +#define ACPI_DIGITAL_OUTPUT (3<<8) +#define ACPI_LVDS_OUTPUT (4<<8) + +int gma_intel_opregion_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + struct psb_intel_opregion *opregion = &dev_priv->opregion; + u32 opregion_phy; + void *base; + u32 *lid_state; + + dev_priv->lid_state = NULL; + + pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy); + if (opregion_phy == 0) + return -ENOTSUPP; + + base = ioremap(opregion_phy, 8*1024); + if (!base) + return -ENOMEM; + /* FIXME: should use _io ops - ditto on i915 */ + if (memcmp(base, OPREGION_SIGNATURE, 16)) { + DRM_ERROR("opregion signature mismatch\n"); + iounmap(base); + return -EINVAL; + } + + lid_state = base + 0x01ac; + + dev_priv->lid_state = lid_state; + dev_priv->lid_last_state = readl(lid_state); + opregion->header = base; + opregion->vbt = base + OPREGION_VBT_OFFSET; + return 0; +} + +int gma_intel_opregion_exit(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = dev->dev_private; + if (dev_priv->opregion.header) + iounmap(dev_priv->opregion.header); + return 0; +} diff --git a/trunk/drivers/gpu/drm/gma500/mdfld_device.c b/trunk/drivers/gpu/drm/gma500/mdfld_device.c index 2d8e741e06d7..a0bd48cd92f4 100644 --- a/trunk/drivers/gpu/drm/gma500/mdfld_device.c +++ b/trunk/drivers/gpu/drm/gma500/mdfld_device.c @@ -163,30 +163,142 @@ struct backlight_device *mdfld_get_backlight_device(void) * * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio */ -static int mdfld_save_display_registers(struct drm_device *dev, int pipenum) +static int mdfld_save_display_registers(struct drm_device *dev, int pipe) { struct drm_psb_private *dev_priv = dev->dev_private; struct medfield_state *regs = &dev_priv->regs.mdfld; - struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum]; - const struct psb_offset *map = &dev_priv->regmap[pipenum]; int i; - u32 *mipi_val; /* register */ + u32 dpll_reg = MRST_DPLL_A; + u32 fp_reg = MRST_FPA0; + u32 pipeconf_reg = PIPEACONF; + u32 htot_reg = HTOTAL_A; + u32 hblank_reg = HBLANK_A; + u32 hsync_reg = HSYNC_A; + u32 vtot_reg = VTOTAL_A; + u32 vblank_reg = VBLANK_A; + u32 vsync_reg = VSYNC_A; + u32 pipesrc_reg = PIPEASRC; + u32 dspstride_reg = DSPASTRIDE; + u32 dsplinoff_reg = DSPALINOFF; + u32 dsptileoff_reg = DSPATILEOFF; + u32 dspsize_reg = DSPASIZE; + u32 dsppos_reg = DSPAPOS; + u32 dspsurf_reg = DSPASURF; u32 mipi_reg = MIPI; - - switch (pipenum) { + u32 dspcntr_reg = DSPACNTR; + u32 dspstatus_reg = PIPEASTAT; + u32 palette_reg = PALETTE_A; + + /* pointer to values */ + u32 *dpll_val = ®s->saveDPLL_A; + u32 *fp_val = ®s->saveFPA0; + u32 *pipeconf_val = ®s->savePIPEACONF; + u32 *htot_val = ®s->saveHTOTAL_A; + u32 *hblank_val = ®s->saveHBLANK_A; + u32 *hsync_val = ®s->saveHSYNC_A; + u32 *vtot_val = ®s->saveVTOTAL_A; + u32 *vblank_val = ®s->saveVBLANK_A; + u32 *vsync_val = ®s->saveVSYNC_A; + u32 *pipesrc_val = ®s->savePIPEASRC; + u32 *dspstride_val = ®s->saveDSPASTRIDE; + u32 *dsplinoff_val = ®s->saveDSPALINOFF; + u32 *dsptileoff_val = ®s->saveDSPATILEOFF; + u32 *dspsize_val = ®s->saveDSPASIZE; + u32 *dsppos_val = ®s->saveDSPAPOS; + u32 *dspsurf_val = ®s->saveDSPASURF; + u32 *mipi_val = ®s->saveMIPI; + u32 *dspcntr_val = ®s->saveDSPACNTR; + u32 *dspstatus_val = ®s->saveDSPASTATUS; + u32 *palette_val = regs->save_palette_a; + + switch (pipe) { case 0: - mipi_val = ®s->saveMIPI; break; case 1: - mipi_val = ®s->saveMIPI; + /* regester */ + dpll_reg = MDFLD_DPLL_B; + fp_reg = MDFLD_DPLL_DIV0; + pipeconf_reg = PIPEBCONF; + htot_reg = HTOTAL_B; + hblank_reg = HBLANK_B; + hsync_reg = HSYNC_B; + vtot_reg = VTOTAL_B; + vblank_reg = VBLANK_B; + vsync_reg = VSYNC_B; + pipesrc_reg = PIPEBSRC; + dspstride_reg = DSPBSTRIDE; + dsplinoff_reg = DSPBLINOFF; + dsptileoff_reg = DSPBTILEOFF; + dspsize_reg = DSPBSIZE; + dsppos_reg = DSPBPOS; + dspsurf_reg = DSPBSURF; + dspcntr_reg = DSPBCNTR; + dspstatus_reg = PIPEBSTAT; + palette_reg = PALETTE_B; + + /* values */ + dpll_val = ®s->saveDPLL_B; + fp_val = ®s->saveFPB0; + pipeconf_val = ®s->savePIPEBCONF; + htot_val = ®s->saveHTOTAL_B; + hblank_val = ®s->saveHBLANK_B; + hsync_val = ®s->saveHSYNC_B; + vtot_val = ®s->saveVTOTAL_B; + vblank_val = ®s->saveVBLANK_B; + vsync_val = ®s->saveVSYNC_B; + pipesrc_val = ®s->savePIPEBSRC; + dspstride_val = ®s->saveDSPBSTRIDE; + dsplinoff_val = ®s->saveDSPBLINOFF; + dsptileoff_val = ®s->saveDSPBTILEOFF; + dspsize_val = ®s->saveDSPBSIZE; + dsppos_val = ®s->saveDSPBPOS; + dspsurf_val = ®s->saveDSPBSURF; + dspcntr_val = ®s->saveDSPBCNTR; + dspstatus_val = ®s->saveDSPBSTATUS; + palette_val = regs->save_palette_b; break; case 2: /* register */ + pipeconf_reg = PIPECCONF; + htot_reg = HTOTAL_C; + hblank_reg = HBLANK_C; + hsync_reg = HSYNC_C; + vtot_reg = VTOTAL_C; + vblank_reg = VBLANK_C; + vsync_reg = VSYNC_C; + pipesrc_reg = PIPECSRC; + dspstride_reg = DSPCSTRIDE; + dsplinoff_reg = DSPCLINOFF; + dsptileoff_reg = DSPCTILEOFF; + dspsize_reg = DSPCSIZE; + dsppos_reg = DSPCPOS; + dspsurf_reg = DSPCSURF; mipi_reg = MIPI_C; + dspcntr_reg = DSPCCNTR; + dspstatus_reg = PIPECSTAT; + palette_reg = PALETTE_C; + /* pointer to values */ + pipeconf_val = ®s->savePIPECCONF; + htot_val = ®s->saveHTOTAL_C; + hblank_val = ®s->saveHBLANK_C; + hsync_val = ®s->saveHSYNC_C; + vtot_val = ®s->saveVTOTAL_C; + vblank_val = ®s->saveVBLANK_C; + vsync_val = ®s->saveVSYNC_C; + pipesrc_val = ®s->savePIPECSRC; + dspstride_val = ®s->saveDSPCSTRIDE; + dsplinoff_val = ®s->saveDSPCLINOFF; + dsptileoff_val = ®s->saveDSPCTILEOFF; + dspsize_val = ®s->saveDSPCSIZE; + dsppos_val = ®s->saveDSPCPOS; + dspsurf_val = ®s->saveDSPCSURF; mipi_val = ®s->saveMIPI_C; + dspcntr_val = ®s->saveDSPCCNTR; + dspstatus_val = ®s->saveDSPCSTATUS; + palette_val = regs->save_palette_c; break; default: DRM_ERROR("%s, invalid pipe number.\n", __func__); @@ -194,30 +306,30 @@ static int mdfld_save_display_registers(struct drm_device *dev, int pipenum) } /* Pipe & plane A info */ - pipe->dpll = PSB_RVDC32(map->dpll); - pipe->fp0 = PSB_RVDC32(map->fp0); - pipe->conf = PSB_RVDC32(map->conf); - pipe->htotal = PSB_RVDC32(map->htotal); - pipe->hblank = PSB_RVDC32(map->hblank); - pipe->hsync = PSB_RVDC32(map->hsync); - pipe->vtotal = PSB_RVDC32(map->vtotal); - pipe->vblank = PSB_RVDC32(map->vblank); - pipe->vsync = PSB_RVDC32(map->vsync); - pipe->src = PSB_RVDC32(map->src); - pipe->stride = PSB_RVDC32(map->stride); - pipe->linoff = PSB_RVDC32(map->linoff); - pipe->tileoff = PSB_RVDC32(map->tileoff); - pipe->size = PSB_RVDC32(map->size); - pipe->pos = PSB_RVDC32(map->pos); - pipe->surf = PSB_RVDC32(map->surf); - pipe->cntr = PSB_RVDC32(map->cntr); - pipe->status = PSB_RVDC32(map->status); + *dpll_val = PSB_RVDC32(dpll_reg); + *fp_val = PSB_RVDC32(fp_reg); + *pipeconf_val = PSB_RVDC32(pipeconf_reg); + *htot_val = PSB_RVDC32(htot_reg); + *hblank_val = PSB_RVDC32(hblank_reg); + *hsync_val = PSB_RVDC32(hsync_reg); + *vtot_val = PSB_RVDC32(vtot_reg); + *vblank_val = PSB_RVDC32(vblank_reg); + *vsync_val = PSB_RVDC32(vsync_reg); + *pipesrc_val = PSB_RVDC32(pipesrc_reg); + *dspstride_val = PSB_RVDC32(dspstride_reg); + *dsplinoff_val = PSB_RVDC32(dsplinoff_reg); + *dsptileoff_val = PSB_RVDC32(dsptileoff_reg); + *dspsize_val = PSB_RVDC32(dspsize_reg); + *dsppos_val = PSB_RVDC32(dsppos_reg); + *dspsurf_val = PSB_RVDC32(dspsurf_reg); + *dspcntr_val = PSB_RVDC32(dspcntr_reg); + *dspstatus_val = PSB_RVDC32(dspstatus_reg); /*save palette (gamma) */ for (i = 0; i < 256; i++) - pipe->palette[i] = PSB_RVDC32(map->palette + (i << 2)); + palette_val[i] = PSB_RVDC32(palette_reg + (i << 2)); - if (pipenum == 1) { + if (pipe == 1) { regs->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL); regs->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS); @@ -237,7 +349,7 @@ static int mdfld_save_display_registers(struct drm_device *dev, int pipenum) * * Notes: FIXME_JLIU7 need to add the support for DPI MIPI & HDMI audio */ -static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) +static int mdfld_restore_display_registers(struct drm_device *dev, int pipe) { /* To get panel out of ULPS mode. */ u32 temp = 0; @@ -245,30 +357,142 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) struct drm_psb_private *dev_priv = dev->dev_private; struct mdfld_dsi_config *dsi_config = NULL; struct medfield_state *regs = &dev_priv->regs.mdfld; - struct psb_pipe *pipe = &dev_priv->regs.pipe[pipenum]; - const struct psb_offset *map = &dev_priv->regmap[pipenum]; - u32 i; - u32 dpll; + u32 i = 0; + u32 dpll = 0; u32 timeout = 0; - /* register */ + /* regester */ + u32 dpll_reg = MRST_DPLL_A; + u32 fp_reg = MRST_FPA0; + u32 pipeconf_reg = PIPEACONF; + u32 htot_reg = HTOTAL_A; + u32 hblank_reg = HBLANK_A; + u32 hsync_reg = HSYNC_A; + u32 vtot_reg = VTOTAL_A; + u32 vblank_reg = VBLANK_A; + u32 vsync_reg = VSYNC_A; + u32 pipesrc_reg = PIPEASRC; + u32 dspstride_reg = DSPASTRIDE; + u32 dsplinoff_reg = DSPALINOFF; + u32 dsptileoff_reg = DSPATILEOFF; + u32 dspsize_reg = DSPASIZE; + u32 dsppos_reg = DSPAPOS; + u32 dspsurf_reg = DSPASURF; + u32 dspstatus_reg = PIPEASTAT; u32 mipi_reg = MIPI; + u32 dspcntr_reg = DSPACNTR; + u32 palette_reg = PALETTE_A; /* values */ - u32 dpll_val = pipe->dpll; + u32 dpll_val = regs->saveDPLL_A & ~DPLL_VCO_ENABLE; + u32 fp_val = regs->saveFPA0; + u32 pipeconf_val = regs->savePIPEACONF; + u32 htot_val = regs->saveHTOTAL_A; + u32 hblank_val = regs->saveHBLANK_A; + u32 hsync_val = regs->saveHSYNC_A; + u32 vtot_val = regs->saveVTOTAL_A; + u32 vblank_val = regs->saveVBLANK_A; + u32 vsync_val = regs->saveVSYNC_A; + u32 pipesrc_val = regs->savePIPEASRC; + u32 dspstride_val = regs->saveDSPASTRIDE; + u32 dsplinoff_val = regs->saveDSPALINOFF; + u32 dsptileoff_val = regs->saveDSPATILEOFF; + u32 dspsize_val = regs->saveDSPASIZE; + u32 dsppos_val = regs->saveDSPAPOS; + u32 dspsurf_val = regs->saveDSPASURF; + u32 dspstatus_val = regs->saveDSPASTATUS; u32 mipi_val = regs->saveMIPI; + u32 dspcntr_val = regs->saveDSPACNTR; + u32 *palette_val = regs->save_palette_a; - switch (pipenum) { + switch (pipe) { case 0: - dpll_val &= ~DPLL_VCO_ENABLE; dsi_config = dev_priv->dsi_configs[0]; break; case 1: - dpll_val &= ~DPLL_VCO_ENABLE; + /* regester */ + dpll_reg = MDFLD_DPLL_B; + fp_reg = MDFLD_DPLL_DIV0; + pipeconf_reg = PIPEBCONF; + htot_reg = HTOTAL_B; + hblank_reg = HBLANK_B; + hsync_reg = HSYNC_B; + vtot_reg = VTOTAL_B; + vblank_reg = VBLANK_B; + vsync_reg = VSYNC_B; + pipesrc_reg = PIPEBSRC; + dspstride_reg = DSPBSTRIDE; + dsplinoff_reg = DSPBLINOFF; + dsptileoff_reg = DSPBTILEOFF; + dspsize_reg = DSPBSIZE; + dsppos_reg = DSPBPOS; + dspsurf_reg = DSPBSURF; + dspcntr_reg = DSPBCNTR; + dspstatus_reg = PIPEBSTAT; + palette_reg = PALETTE_B; + + /* values */ + dpll_val = regs->saveDPLL_B & ~DPLL_VCO_ENABLE; + fp_val = regs->saveFPB0; + pipeconf_val = regs->savePIPEBCONF; + htot_val = regs->saveHTOTAL_B; + hblank_val = regs->saveHBLANK_B; + hsync_val = regs->saveHSYNC_B; + vtot_val = regs->saveVTOTAL_B; + vblank_val = regs->saveVBLANK_B; + vsync_val = regs->saveVSYNC_B; + pipesrc_val = regs->savePIPEBSRC; + dspstride_val = regs->saveDSPBSTRIDE; + dsplinoff_val = regs->saveDSPBLINOFF; + dsptileoff_val = regs->saveDSPBTILEOFF; + dspsize_val = regs->saveDSPBSIZE; + dsppos_val = regs->saveDSPBPOS; + dspsurf_val = regs->saveDSPBSURF; + dspcntr_val = regs->saveDSPBCNTR; + dspstatus_val = regs->saveDSPBSTATUS; + palette_val = regs->save_palette_b; break; case 2: + /* regester */ + pipeconf_reg = PIPECCONF; + htot_reg = HTOTAL_C; + hblank_reg = HBLANK_C; + hsync_reg = HSYNC_C; + vtot_reg = VTOTAL_C; + vblank_reg = VBLANK_C; + vsync_reg = VSYNC_C; + pipesrc_reg = PIPECSRC; + dspstride_reg = DSPCSTRIDE; + dsplinoff_reg = DSPCLINOFF; + dsptileoff_reg = DSPCTILEOFF; + dspsize_reg = DSPCSIZE; + dsppos_reg = DSPCPOS; + dspsurf_reg = DSPCSURF; mipi_reg = MIPI_C; + dspcntr_reg = DSPCCNTR; + dspstatus_reg = PIPECSTAT; + palette_reg = PALETTE_C; + + /* values */ + pipeconf_val = regs->savePIPECCONF; + htot_val = regs->saveHTOTAL_C; + hblank_val = regs->saveHBLANK_C; + hsync_val = regs->saveHSYNC_C; + vtot_val = regs->saveVTOTAL_C; + vblank_val = regs->saveVBLANK_C; + vsync_val = regs->saveVSYNC_C; + pipesrc_val = regs->savePIPECSRC; + dspstride_val = regs->saveDSPCSTRIDE; + dsplinoff_val = regs->saveDSPCLINOFF; + dsptileoff_val = regs->saveDSPCTILEOFF; + dspsize_val = regs->saveDSPCSIZE; + dsppos_val = regs->saveDSPCPOS; + dspsurf_val = regs->saveDSPCSURF; mipi_val = regs->saveMIPI_C; + dspcntr_val = regs->saveDSPCCNTR; + dspstatus_val = regs->saveDSPCSTATUS; + palette_val = regs->save_palette_c; + dsi_config = dev_priv->dsi_configs[1]; break; default: @@ -279,14 +503,14 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) /*make sure VGA plane is off. it initializes to on after reset!*/ PSB_WVDC32(0x80000000, VGACNTRL); - if (pipenum == 1) { - PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, map->dpll); - PSB_RVDC32(map->dpll); + if (pipe == 1) { + PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg); + PSB_RVDC32(dpll_reg); - PSB_WVDC32(pipe->fp0, map->fp0); + PSB_WVDC32(fp_val, fp_reg); } else { - dpll = PSB_RVDC32(map->dpll); + dpll = PSB_RVDC32(dpll_reg); if (!(dpll & DPLL_VCO_ENABLE)) { @@ -294,23 +518,23 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) before enable the VCO */ if (dpll & MDFLD_PWR_GATE_EN) { dpll &= ~MDFLD_PWR_GATE_EN; - PSB_WVDC32(dpll, map->dpll); + PSB_WVDC32(dpll, dpll_reg); /* FIXME_MDFLD PO - change 500 to 1 after PO */ udelay(500); } - PSB_WVDC32(pipe->fp0, map->fp0); - PSB_WVDC32(dpll_val, map->dpll); + PSB_WVDC32(fp_val, fp_reg); + PSB_WVDC32(dpll_val, dpll_reg); /* FIXME_MDFLD PO - change 500 to 1 after PO */ udelay(500); dpll_val |= DPLL_VCO_ENABLE; - PSB_WVDC32(dpll_val, map->dpll); - PSB_RVDC32(map->dpll); + PSB_WVDC32(dpll_val, dpll_reg); + PSB_RVDC32(dpll_reg); /* wait for DSI PLL to lock */ while (timeout < 20000 && - !(PSB_RVDC32(map->conf) & PIPECONF_DSIPLL_LOCK)) { + !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) { udelay(150); timeout++; } @@ -323,28 +547,28 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) } } /* Restore mode */ - PSB_WVDC32(pipe->htotal, map->htotal); - PSB_WVDC32(pipe->hblank, map->hblank); - PSB_WVDC32(pipe->hsync, map->hsync); - PSB_WVDC32(pipe->vtotal, map->vtotal); - PSB_WVDC32(pipe->vblank, map->vblank); - PSB_WVDC32(pipe->vsync, map->vsync); - PSB_WVDC32(pipe->src, map->src); - PSB_WVDC32(pipe->status, map->status); + PSB_WVDC32(htot_val, htot_reg); + PSB_WVDC32(hblank_val, hblank_reg); + PSB_WVDC32(hsync_val, hsync_reg); + PSB_WVDC32(vtot_val, vtot_reg); + PSB_WVDC32(vblank_val, vblank_reg); + PSB_WVDC32(vsync_val, vsync_reg); + PSB_WVDC32(pipesrc_val, pipesrc_reg); + PSB_WVDC32(dspstatus_val, dspstatus_reg); /*set up the plane*/ - PSB_WVDC32(pipe->stride, map->stride); - PSB_WVDC32(pipe->linoff, map->linoff); - PSB_WVDC32(pipe->tileoff, map->tileoff); - PSB_WVDC32(pipe->size, map->size); - PSB_WVDC32(pipe->pos, map->pos); - PSB_WVDC32(pipe->surf, map->surf); - - if (pipenum == 1) { + PSB_WVDC32(dspstride_val, dspstride_reg); + PSB_WVDC32(dsplinoff_val, dsplinoff_reg); + PSB_WVDC32(dsptileoff_val, dsptileoff_reg); + PSB_WVDC32(dspsize_val, dspsize_reg); + PSB_WVDC32(dsppos_val, dsppos_reg); + PSB_WVDC32(dspsurf_val, dspsurf_reg); + + if (pipe == 1) { /* restore palette (gamma) */ /*DRM_UDELAY(50000); */ for (i = 0; i < 256; i++) - PSB_WVDC32(pipe->palette[i], map->palette + (i << 2)); + PSB_WVDC32(palette_val[i], palette_reg + (i << 2)); PSB_WVDC32(regs->savePFIT_CONTROL, PFIT_CONTROL); PSB_WVDC32(regs->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS); @@ -354,7 +578,7 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) /*TODO: resume pipe*/ /*enable the plane*/ - PSB_WVDC32(pipe->cntr & ~DISPLAY_PLANE_ENABLE, map->cntr); + PSB_WVDC32(dspcntr_val & ~DISPLAY_PLANE_ENABLE, dspcntr_reg); return 0; } @@ -364,7 +588,7 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) /*setup MIPI adapter + MIPI IP registers*/ if (dsi_config) - mdfld_dsi_controller_init(dsi_config, pipenum); + mdfld_dsi_controller_init(dsi_config, pipe); if (in_atomic() || in_interrupt()) mdelay(20); @@ -372,7 +596,7 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) msleep(20); /*enable the plane*/ - PSB_WVDC32(pipe->cntr, map->cntr); + PSB_WVDC32(dspcntr_val, dspcntr_reg); if (in_atomic() || in_interrupt()) mdelay(20); @@ -401,12 +625,12 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) mdelay(1); /*enable the pipe*/ - PSB_WVDC32(pipe->conf, map->conf); + PSB_WVDC32(pipeconf_val, pipeconf_reg); /* restore palette (gamma) */ /*DRM_UDELAY(50000); */ for (i = 0; i < 256; i++) - PSB_WVDC32(pipe->palette[i], map->palette + (i << 2)); + PSB_WVDC32(palette_val[i], palette_reg + (i << 2)); return 0; } @@ -443,97 +667,16 @@ static int mdfld_power_up(struct drm_device *dev) return 0; } -/* Medfield */ -static const struct psb_offset mdfld_regmap[3] = { - { - .fp0 = MRST_FPA0, - .fp1 = MRST_FPA1, - .cntr = DSPACNTR, - .conf = PIPEACONF, - .src = PIPEASRC, - .dpll = MRST_DPLL_A, - .htotal = HTOTAL_A, - .hblank = HBLANK_A, - .hsync = HSYNC_A, - .vtotal = VTOTAL_A, - .vblank = VBLANK_A, - .vsync = VSYNC_A, - .stride = DSPASTRIDE, - .size = DSPASIZE, - .pos = DSPAPOS, - .surf = DSPASURF, - .addr = MRST_DSPABASE, - .status = PIPEASTAT, - .linoff = DSPALINOFF, - .tileoff = DSPATILEOFF, - .palette = PALETTE_A, - }, - { - .fp0 = MDFLD_DPLL_DIV0, - .cntr = DSPBCNTR, - .conf = PIPEBCONF, - .src = PIPEBSRC, - .dpll = MDFLD_DPLL_B, - .htotal = HTOTAL_B, - .hblank = HBLANK_B, - .hsync = HSYNC_B, - .vtotal = VTOTAL_B, - .vblank = VBLANK_B, - .vsync = VSYNC_B, - .stride = DSPBSTRIDE, - .size = DSPBSIZE, - .pos = DSPBPOS, - .surf = DSPBSURF, - .addr = MRST_DSPBBASE, - .status = PIPEBSTAT, - .linoff = DSPBLINOFF, - .tileoff = DSPBTILEOFF, - .palette = PALETTE_B, - }, - { - .fp0 = MRST_FPA0, /* This is what the old code did ?? */ - .cntr = DSPCCNTR, - .conf = PIPECCONF, - .src = PIPECSRC, - /* No DPLL_C */ - .dpll = MRST_DPLL_A, - .htotal = HTOTAL_C, - .hblank = HBLANK_C, - .hsync = HSYNC_C, - .vtotal = VTOTAL_C, - .vblank = VBLANK_C, - .vsync = VSYNC_C, - .stride = DSPCSTRIDE, - .size = DSPBSIZE, - .pos = DSPCPOS, - .surf = DSPCSURF, - .addr = MDFLD_DSPCBASE, - .status = PIPECSTAT, - .linoff = DSPCLINOFF, - .tileoff = DSPCTILEOFF, - .palette = PALETTE_C, - }, -}; - -static int mdfld_chip_setup(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - if (pci_enable_msi(dev->pdev)) - dev_warn(dev->dev, "Enabling MSI failed!\n"); - dev_priv->regmap = mdfld_regmap; - return mid_chip_setup(dev); -} - const struct psb_ops mdfld_chip_ops = { .name = "mdfld", .accel_2d = 0, .pipes = 3, .crtcs = 3, - .lvds_mask = (1 << 1), - .hdmi_mask = (1 << 1), + .lvds_mask = (1 << 1); + .hdmi_mask = (1 << 1); .sgx_offset = MRST_SGX_OFFSET, - .chip_setup = mdfld_chip_setup, + .chip_setup = mid_chip_setup, .crtc_helper = &mdfld_helper_funcs, .crtc_funcs = &psb_intel_crtc_funcs, diff --git a/trunk/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c b/trunk/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c index b34ff097b979..d52358b744a0 100644 --- a/trunk/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c +++ b/trunk/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c @@ -869,6 +869,7 @@ void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder, mdfld_set_pipe_timing(dsi_config, pipe); REG_WRITE(DSPABASE, 0x00); + REG_WRITE(DSPASTRIDE, (mode->hdisplay * 4)); REG_WRITE(DSPASIZE, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); diff --git a/trunk/drivers/gpu/drm/gma500/mdfld_dsi_output.h b/trunk/drivers/gpu/drm/gma500/mdfld_dsi_output.h index 36eb0744841c..21071cef92a4 100644 --- a/trunk/drivers/gpu/drm/gma500/mdfld_dsi_output.h +++ b/trunk/drivers/gpu/drm/gma500/mdfld_dsi_output.h @@ -29,6 +29,7 @@ #define __MDFLD_DSI_OUTPUT_H__ #include +#include #include #include #include diff --git a/trunk/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c b/trunk/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c index 489ffd2c66e5..baa0e14165e0 100644 --- a/trunk/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c +++ b/trunk/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c @@ -605,8 +605,6 @@ int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector, struct mdfld_dsi_config *dsi_config = mdfld_dsi_get_config(dsi_connector); struct drm_device *dev = dsi_config->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - const struct psb_offset *map = &dev_priv->regmap[pipe]; u32 mipi_val = 0; if (!dsi_connector) { @@ -634,13 +632,21 @@ int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector, pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE; /*init regs*/ - /* FIXME: should just copy the regmap ptr ? */ - pkg_sender->dpll_reg = map->dpll; - pkg_sender->dspcntr_reg = map->cntr; - pkg_sender->pipeconf_reg = map->conf; - pkg_sender->dsplinoff_reg = map->linoff; - pkg_sender->dspsurf_reg = map->surf; - pkg_sender->pipestat_reg = map->status; + if (pipe == 0) { + pkg_sender->dpll_reg = MRST_DPLL_A; + pkg_sender->dspcntr_reg = DSPACNTR; + pkg_sender->pipeconf_reg = PIPEACONF; + pkg_sender->dsplinoff_reg = DSPALINOFF; + pkg_sender->dspsurf_reg = DSPASURF; + pkg_sender->pipestat_reg = PIPEASTAT; + } else if (pipe == 2) { + pkg_sender->dpll_reg = MRST_DPLL_A; + pkg_sender->dspcntr_reg = DSPCCNTR; + pkg_sender->pipeconf_reg = PIPECCONF; + pkg_sender->dsplinoff_reg = DSPCLINOFF; + pkg_sender->dspsurf_reg = DSPCSURF; + pkg_sender->pipestat_reg = PIPECSTAT; + } pkg_sender->mipi_intr_stat_reg = MIPI_INTR_STAT_REG(pipe); pkg_sender->mipi_lp_gen_data_reg = MIPI_LP_GEN_DATA_REG(pipe); diff --git a/trunk/drivers/gpu/drm/gma500/mdfld_intel_display.c b/trunk/drivers/gpu/drm/gma500/mdfld_intel_display.c index 3f3cd619c79f..a35a2921bdf7 100644 --- a/trunk/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ b/trunk/drivers/gpu/drm/gma500/mdfld_intel_display.c @@ -50,14 +50,17 @@ struct mrst_clock_t { void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe) { - struct drm_psb_private *dev_priv = dev->dev_private; - const struct psb_offset *map = &dev_priv->regmap[pipe]; int count, temp; + u32 pipeconf_reg = PIPEACONF; switch (pipe) { case 0: + break; case 1: + pipeconf_reg = PIPEBCONF; + break; case 2: + pipeconf_reg = PIPECCONF; break; default: DRM_ERROR("Illegal Pipe Number.\n"); @@ -70,7 +73,7 @@ void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe) /* Wait for for the pipe disable to take effect. */ for (count = 0; count < COUNT_MAX; count++) { - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); if ((temp & PIPEACONF_PIPE_STATE) == 0) break; } @@ -78,14 +81,17 @@ void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe) void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe) { - struct drm_psb_private *dev_priv = dev->dev_private; - const struct psb_offset *map = &dev_priv->regmap[pipe]; int count, temp; + u32 pipeconf_reg = PIPEACONF; switch (pipe) { case 0: + break; case 1: + pipeconf_reg = PIPEBCONF; + break; case 2: + pipeconf_reg = PIPECCONF; break; default: DRM_ERROR("Illegal Pipe Number.\n"); @@ -98,7 +104,7 @@ void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe) /* Wait for for the pipe enable to take effect. */ for (count = 0; count < COUNT_MAX; count++) { - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); if ((temp & PIPEACONF_PIPE_STATE) == 1) break; } @@ -183,12 +189,15 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; + /* struct drm_i915_master_private *master_priv; */ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; unsigned long start, offset; + int dsplinoff = DSPALINOFF; + int dspsurf = DSPASURF; + int dspstride = DSPASTRIDE; + int dspcntr_reg = DSPACNTR; u32 dspcntr; int ret; @@ -206,7 +215,23 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, if (ret) return ret; - if (pipe > 2) { + switch (pipe) { + case 0: + dsplinoff = DSPALINOFF; + break; + case 1: + dsplinoff = DSPBLINOFF; + dspsurf = DSPBSURF; + dspstride = DSPBSTRIDE; + dspcntr_reg = DSPBCNTR; + break; + case 2: + dsplinoff = DSPCLINOFF; + dspsurf = DSPCSURF; + dspstride = DSPCSTRIDE; + dspcntr_reg = DSPCCNTR; + break; + default: DRM_ERROR("Illegal Pipe Number.\n"); return -EINVAL; } @@ -217,8 +242,8 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, start = psbfb->gtt->offset; offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); - REG_WRITE(map->stride, crtc->fb->pitches[0]); - dspcntr = REG_READ(map->cntr); + REG_WRITE(dspstride, crtc->fb->pitches[0]); + dspcntr = REG_READ(dspcntr_reg); dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; switch (crtc->fb->bits_per_pixel) { @@ -236,14 +261,14 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, dspcntr |= DISPPLANE_32BPP_NO_ALPHA; break; } - REG_WRITE(map->cntr, dspcntr); + REG_WRITE(dspcntr_reg, dspcntr); dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n", start, offset, x, y); - REG_WRITE(map->linoff, offset); - REG_READ(map->linoff); - REG_WRITE(map->surf, start); - REG_READ(map->surf); + REG_WRITE(dsplinoff, offset); + REG_READ(dsplinoff); + REG_WRITE(dspsurf, start); + REG_READ(dspsurf); gma_power_end(dev); @@ -256,56 +281,78 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, */ void mdfld_disable_crtc(struct drm_device *dev, int pipe) { - struct drm_psb_private *dev_priv = dev->dev_private; - const struct psb_offset *map = &dev_priv->regmap[pipe]; + int dpll_reg = MRST_DPLL_A; + int dspcntr_reg = DSPACNTR; + int dspbase_reg = MRST_DSPABASE; + int pipeconf_reg = PIPEACONF; u32 temp; dev_dbg(dev->dev, "pipe = %d\n", pipe); + switch (pipe) { + case 0: + break; + case 1: + dpll_reg = MDFLD_DPLL_B; + dspcntr_reg = DSPBCNTR; + dspbase_reg = DSPBSURF; + pipeconf_reg = PIPEBCONF; + break; + case 2: + dpll_reg = MRST_DPLL_A; + dspcntr_reg = DSPCCNTR; + dspbase_reg = MDFLD_DSPCBASE; + pipeconf_reg = PIPECCONF; + break; + default: + DRM_ERROR("Illegal Pipe Number.\n"); + return; + } + if (pipe != 1) mdfld_dsi_gen_fifo_ready(dev, MIPI_GEN_FIFO_STAT_REG(pipe), HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY); /* Disable display plane */ - temp = REG_READ(map->cntr); + temp = REG_READ(dspcntr_reg); if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - REG_WRITE(map->cntr, + REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); /* Flush the plane changes */ - REG_WRITE(map->base, REG_READ(map->base)); - REG_READ(map->base); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + REG_READ(dspbase_reg); } /* FIXME_JLIU7 MDFLD_PO revisit */ /* Next, disable display pipes */ - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); if ((temp & PIPEACONF_ENABLE) != 0) { temp &= ~PIPEACONF_ENABLE; temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF; - REG_WRITE(map->conf, temp); - REG_READ(map->conf); + REG_WRITE(pipeconf_reg, temp); + REG_READ(pipeconf_reg); /* Wait for for the pipe disable to take effect. */ mdfldWaitForPipeDisable(dev, pipe); } - temp = REG_READ(map->dpll); + temp = REG_READ(dpll_reg); if (temp & DPLL_VCO_ENABLE) { if ((pipe != 1 && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE)) || pipe == 1) { temp &= ~(DPLL_VCO_ENABLE); - REG_WRITE(map->dpll, temp); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp); + REG_READ(dpll_reg); /* Wait for the clocks to turn off. */ /* FIXME_MDFLD PO may need more delay */ udelay(500); if (!(temp & MDFLD_PWR_GATE_EN)) { /* gating power of DPLL */ - REG_WRITE(map->dpll, temp | MDFLD_PWR_GATE_EN); + REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN); /* FIXME_MDFLD PO - change 500 to 1 after PO */ udelay(5000); } @@ -326,15 +373,41 @@ static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) struct drm_psb_private *dev_priv = dev->dev_private; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; + int dpll_reg = MRST_DPLL_A; + int dspcntr_reg = DSPACNTR; + int dspbase_reg = MRST_DSPABASE; + int pipeconf_reg = PIPEACONF; + u32 pipestat_reg = PIPEASTAT; u32 pipeconf = dev_priv->pipeconf[pipe]; u32 temp; int timeout = 0; dev_dbg(dev->dev, "mode = %d, pipe = %d\n", mode, pipe); - /* Note: Old code uses pipe a stat for pipe b but that appears - to be a bug */ +/* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */ +/* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */ + + switch (pipe) { + case 0: + break; + case 1: + dpll_reg = DPLL_B; + dspcntr_reg = DSPBCNTR; + dspbase_reg = MRST_DSPBBASE; + pipeconf_reg = PIPEBCONF; + dpll_reg = MDFLD_DPLL_B; + break; + case 2: + dpll_reg = MRST_DPLL_A; + dspcntr_reg = DSPCCNTR; + dspbase_reg = MDFLD_DSPCBASE; + pipeconf_reg = PIPECCONF; + pipestat_reg = PIPECSTAT; + break; + default: + DRM_ERROR("Illegal Pipe Number.\n"); + return; + } if (!gma_power_begin(dev, true)) return; @@ -347,25 +420,25 @@ static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: /* Enable the DPLL */ - temp = REG_READ(map->dpll); + temp = REG_READ(dpll_reg); if ((temp & DPLL_VCO_ENABLE) == 0) { /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */ if (temp & MDFLD_PWR_GATE_EN) { temp &= ~MDFLD_PWR_GATE_EN; - REG_WRITE(map->dpll, temp); + REG_WRITE(dpll_reg, temp); /* FIXME_MDFLD PO - change 500 to 1 after PO */ udelay(500); } - REG_WRITE(map->dpll, temp); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp); + REG_READ(dpll_reg); /* FIXME_MDFLD PO - change 500 to 1 after PO */ udelay(500); - REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); /** * wait for DSI PLL to lock @@ -373,25 +446,25 @@ static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) * since both MIPI pipes share the same PLL. */ while ((pipe != 2) && (timeout < 20000) && - !(REG_READ(map->conf) & PIPECONF_DSIPLL_LOCK)) { + !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) { udelay(150); timeout++; } } /* Enable the plane */ - temp = REG_READ(map->cntr); + temp = REG_READ(dspcntr_reg); if ((temp & DISPLAY_PLANE_ENABLE) == 0) { - REG_WRITE(map->cntr, + REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE); /* Flush the plane changes */ - REG_WRITE(map->base, REG_READ(map->base)); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); } /* Enable the pipe */ - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); if ((temp & PIPEACONF_ENABLE) == 0) { - REG_WRITE(map->conf, pipeconf); + REG_WRITE(pipeconf_reg, pipeconf); /* Wait for for the pipe enable to take effect. */ mdfldWaitForPipeEnable(dev, pipe); @@ -400,39 +473,39 @@ static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) /*workaround for sighting 3741701 Random X blank display*/ /*perform w/a in video mode only on pipe A or C*/ if (pipe == 0 || pipe == 2) { - REG_WRITE(map->status, REG_READ(map->status)); + REG_WRITE(pipestat_reg, REG_READ(pipestat_reg)); msleep(100); - if (PIPE_VBLANK_STATUS & REG_READ(map->status)) + if (PIPE_VBLANK_STATUS & REG_READ(pipestat_reg)) dev_dbg(dev->dev, "OK"); else { dev_dbg(dev->dev, "STUCK!!!!"); /*shutdown controller*/ - temp = REG_READ(map->cntr); - REG_WRITE(map->cntr, + temp = REG_READ(dspcntr_reg); + REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); - REG_WRITE(map->base, REG_READ(map->base)); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); /*mdfld_dsi_dpi_shut_down(dev, pipe);*/ REG_WRITE(0xb048, 1); msleep(100); - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); temp &= ~PIPEACONF_ENABLE; - REG_WRITE(map->conf, temp); + REG_WRITE(pipeconf_reg, temp); msleep(100); /*wait for pipe disable*/ REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 0); msleep(100); REG_WRITE(0xb004, REG_READ(0xb004)); /* try to bring the controller back up again*/ REG_WRITE(MIPI_DEVICE_READY_REG(pipe), 1); - temp = REG_READ(map->cntr); - REG_WRITE(map->cntr, + temp = REG_READ(dspcntr_reg); + REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE); - REG_WRITE(map->base, REG_READ(map->base)); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); /*mdfld_dsi_dpi_turn_on(dev, pipe);*/ REG_WRITE(0xb048, 2); msleep(100); - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); temp |= PIPEACONF_ENABLE; - REG_WRITE(map->conf, temp); + REG_WRITE(pipeconf_reg, temp); } } @@ -456,35 +529,35 @@ static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); /* Disable display plane */ - temp = REG_READ(map->cntr); + temp = REG_READ(dspcntr_reg); if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - REG_WRITE(map->cntr, + REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); /* Flush the plane changes */ - REG_WRITE(map->base, REG_READ(map->base)); - REG_READ(map->base); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + REG_READ(dspbase_reg); } /* Next, disable display pipes */ - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); if ((temp & PIPEACONF_ENABLE) != 0) { temp &= ~PIPEACONF_ENABLE; temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF; - REG_WRITE(map->conf, temp); - REG_READ(map->conf); + REG_WRITE(pipeconf_reg, temp); + REG_READ(pipeconf_reg); /* Wait for for the pipe disable to take effect. */ mdfldWaitForPipeDisable(dev, pipe); } - temp = REG_READ(map->dpll); + temp = REG_READ(dpll_reg); if (temp & DPLL_VCO_ENABLE) { if ((pipe != 1 && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE)) || pipe == 1) { temp &= ~(DPLL_VCO_ENABLE); - REG_WRITE(map->dpll, temp); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp); + REG_READ(dpll_reg); /* Wait for the clocks to turn off. */ /* FIXME_MDFLD PO may need more delay */ udelay(500); @@ -691,7 +764,21 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct drm_psb_private *dev_priv = dev->dev_private; int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; + int fp_reg = MRST_FPA0; + int dpll_reg = MRST_DPLL_A; + int dspcntr_reg = DSPACNTR; + int pipeconf_reg = PIPEACONF; + int htot_reg = HTOTAL_A; + int hblank_reg = HBLANK_A; + int hsync_reg = HSYNC_A; + int vtot_reg = VTOTAL_A; + int vblank_reg = VBLANK_A; + int vsync_reg = VSYNC_A; + int dspsize_reg = DSPASIZE; + int dsppos_reg = DSPAPOS; + int pipesrc_reg = PIPEASRC; + u32 *pipeconf = &dev_priv->pipeconf[pipe]; + u32 *dspcntr = &dev_priv->dspcntr[pipe]; int refclk = 0; int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0, clk_tmp = 0; @@ -719,6 +806,45 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, } #endif + switch (pipe) { + case 0: + break; + case 1: + fp_reg = FPB0; + dpll_reg = DPLL_B; + dspcntr_reg = DSPBCNTR; + pipeconf_reg = PIPEBCONF; + htot_reg = HTOTAL_B; + hblank_reg = HBLANK_B; + hsync_reg = HSYNC_B; + vtot_reg = VTOTAL_B; + vblank_reg = VBLANK_B; + vsync_reg = VSYNC_B; + dspsize_reg = DSPBSIZE; + dsppos_reg = DSPBPOS; + pipesrc_reg = PIPEBSRC; + fp_reg = MDFLD_DPLL_DIV0; + dpll_reg = MDFLD_DPLL_B; + break; + case 2: + dpll_reg = MRST_DPLL_A; + dspcntr_reg = DSPCCNTR; + pipeconf_reg = PIPECCONF; + htot_reg = HTOTAL_C; + hblank_reg = HBLANK_C; + hsync_reg = HSYNC_C; + vtot_reg = VTOTAL_C; + vblank_reg = VBLANK_C; + vsync_reg = VSYNC_C; + dspsize_reg = DSPCSIZE; + dsppos_reg = DSPCPOS; + pipesrc_reg = PIPECSRC; + break; + default: + DRM_ERROR("Illegal Pipe Number.\n"); + return 0; + } + ret = check_fb(crtc->fb); if (ret) return ret; @@ -803,21 +929,21 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, * contained within the displayable area of the screen image * (frame buffer). */ - REG_WRITE(map->size, ((min(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16) + REG_WRITE(dspsize_reg, ((min(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16) | (min(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1)); /* Set the CRTC with encoder mode. */ - REG_WRITE(map->src, ((mode->crtc_hdisplay - 1) << 16) + REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); } else { - REG_WRITE(map->size, + REG_WRITE(dspsize_reg, ((mode->crtc_vdisplay - 1) << 16) | (mode->crtc_hdisplay - 1)); - REG_WRITE(map->src, + REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); } - REG_WRITE(map->pos, 0); + REG_WRITE(dsppos_reg, 0); if (psb_intel_encoder) drm_connector_property_get_value(connector, @@ -835,34 +961,34 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, offsetY = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; - REG_WRITE(map->htotal, (mode->crtc_hdisplay - 1) | + REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(map->vtotal, (mode->crtc_vdisplay - 1) | + REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - offsetX - 1) | ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16)); - REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - offsetX - 1) | ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16)); - REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - offsetY - 1) | ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16)); - REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - offsetY - 1) | ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16)); } else { - REG_WRITE(map->htotal, (adjusted_mode->crtc_hdisplay - 1) | + REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) | + REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - 1) | + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16)); - REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - 1) | + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16)); - REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - 1) | + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16)); - REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - 1) | + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); } @@ -874,12 +1000,12 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, } /* setup pipeconf */ - dev_priv->pipeconf[pipe] = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */ + *pipeconf = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */ /* Set up the display plane register */ - dev_priv->dspcntr[pipe] = REG_READ(map->cntr); - dev_priv->dspcntr[pipe] |= pipe << DISPPLANE_SEL_PIPE_POS; - dev_priv->dspcntr[pipe] |= DISPLAY_PLANE_ENABLE; + *dspcntr = REG_READ(dspcntr_reg); + *dspcntr |= pipe << DISPPLANE_SEL_PIPE_POS; + *dspcntr |= DISPLAY_PLANE_ENABLE; if (is_mipi2) goto mrst_crtc_mode_set_exit; @@ -944,21 +1070,21 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, clock.p1, m_conv); } - dpll = REG_READ(map->dpll); + dpll = REG_READ(dpll_reg); if (dpll & DPLL_VCO_ENABLE) { dpll &= ~DPLL_VCO_ENABLE; - REG_WRITE(map->dpll, dpll); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, dpll); + REG_READ(dpll_reg); /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */ /* FIXME_MDFLD PO - change 500 to 1 after PO */ udelay(500); /* reset M1, N1 & P1 */ - REG_WRITE(map->fp0, 0); + REG_WRITE(fp_reg, 0); dpll &= ~MDFLD_P1_MASK; - REG_WRITE(map->dpll, dpll); + REG_WRITE(dpll_reg, dpll); /* FIXME_MDFLD PO - change 500 to 1 after PO */ udelay(500); } @@ -967,7 +1093,7 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, * enable the VCO */ if (dpll & MDFLD_PWR_GATE_EN) { dpll &= ~MDFLD_PWR_GATE_EN; - REG_WRITE(map->dpll, dpll); + REG_WRITE(dpll_reg, dpll); /* FIXME_MDFLD PO - change 500 to 1 after PO */ udelay(500); } @@ -1008,18 +1134,18 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, fp = 0x000000c1; } - REG_WRITE(map->fp0, fp); - REG_WRITE(map->dpll, dpll); + REG_WRITE(fp_reg, fp); + REG_WRITE(dpll_reg, dpll); /* FIXME_MDFLD PO - change 500 to 1 after PO */ udelay(500); dpll |= DPLL_VCO_ENABLE; - REG_WRITE(map->dpll, dpll); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, dpll); + REG_READ(dpll_reg); /* wait for DSI PLL to lock */ while (timeout < 20000 && - !(REG_READ(map->conf) & PIPECONF_DSIPLL_LOCK)) { + !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) { udelay(150); timeout++; } @@ -1029,11 +1155,11 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, dev_dbg(dev->dev, "is_mipi = 0x%x\n", is_mipi); - REG_WRITE(map->conf, dev_priv->pipeconf[pipe]); - REG_READ(map->conf); + REG_WRITE(pipeconf_reg, *pipeconf); + REG_READ(pipeconf_reg); /* Wait for for the pipe enable to take effect. */ - REG_WRITE(map->cntr, dev_priv->dspcntr[pipe]); + REG_WRITE(dspcntr_reg, *dspcntr); psb_intel_wait_for_vblank(dev); mrst_crtc_mode_set_exit: diff --git a/trunk/drivers/gpu/drm/gma500/mid_bios.c b/trunk/drivers/gpu/drm/gma500/mid_bios.c index b2a790bd9899..5eee9ad80da4 100644 --- a/trunk/drivers/gpu/drm/gma500/mid_bios.c +++ b/trunk/drivers/gpu/drm/gma500/mid_bios.c @@ -118,214 +118,139 @@ static void mid_get_pci_revID(struct drm_psb_private *dev_priv) dev_priv->platform_rev_id); } -struct vbt_header { - u32 signature; - u8 revision; -} __packed; - -/* The same for r0 and r1 */ -struct vbt_r0 { - struct vbt_header vbt_header; - u8 size; - u8 checksum; -} __packed; - -struct vbt_r10 { - struct vbt_header vbt_header; - u8 checksum; - u16 size; - u8 panel_count; - u8 primary_panel_idx; - u8 secondary_panel_idx; - u8 __reserved[5]; -} __packed; - -static int read_vbt_r0(u32 addr, struct vbt_r0 *vbt) -{ - void __iomem *vbt_virtual; - - vbt_virtual = ioremap(addr, sizeof(*vbt)); - if (vbt_virtual == NULL) - return -1; - - memcpy_fromio(vbt, vbt_virtual, sizeof(*vbt)); - iounmap(vbt_virtual); - - return 0; -} - -static int read_vbt_r10(u32 addr, struct vbt_r10 *vbt) -{ - void __iomem *vbt_virtual; - - vbt_virtual = ioremap(addr, sizeof(*vbt)); - if (!vbt_virtual) - return -1; - - memcpy_fromio(vbt, vbt_virtual, sizeof(*vbt)); - iounmap(vbt_virtual); - - return 0; -} - -static int mid_get_vbt_data_r0(struct drm_psb_private *dev_priv, u32 addr) -{ - struct vbt_r0 vbt; - void __iomem *gct_virtual; - struct gct_r0 gct; - u8 bpi; - - if (read_vbt_r0(addr, &vbt)) - return -1; - - gct_virtual = ioremap(addr + sizeof(vbt), vbt.size - sizeof(vbt)); - if (!gct_virtual) - return -1; - memcpy_fromio(&gct, gct_virtual, sizeof(gct)); - iounmap(gct_virtual); - - bpi = gct.PD.BootPanelIndex; - dev_priv->gct_data.bpi = bpi; - dev_priv->gct_data.pt = gct.PD.PanelType; - dev_priv->gct_data.DTD = gct.panel[bpi].DTD; - dev_priv->gct_data.Panel_Port_Control = - gct.panel[bpi].Panel_Port_Control; - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - gct.panel[bpi].Panel_MIPI_Display_Descriptor; - - return 0; -} - -static int mid_get_vbt_data_r1(struct drm_psb_private *dev_priv, u32 addr) -{ - struct vbt_r0 vbt; - void __iomem *gct_virtual; - struct gct_r1 gct; - u8 bpi; - - if (read_vbt_r0(addr, &vbt)) - return -1; - - gct_virtual = ioremap(addr + sizeof(vbt), vbt.size - sizeof(vbt)); - if (!gct_virtual) - return -1; - memcpy_fromio(&gct, gct_virtual, sizeof(gct)); - iounmap(gct_virtual); - - bpi = gct.PD.BootPanelIndex; - dev_priv->gct_data.bpi = bpi; - dev_priv->gct_data.pt = gct.PD.PanelType; - dev_priv->gct_data.DTD = gct.panel[bpi].DTD; - dev_priv->gct_data.Panel_Port_Control = - gct.panel[bpi].Panel_Port_Control; - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - gct.panel[bpi].Panel_MIPI_Display_Descriptor; - - return 0; -} - -static int mid_get_vbt_data_r10(struct drm_psb_private *dev_priv, u32 addr) -{ - struct vbt_r10 vbt; - void __iomem *gct_virtual; - struct gct_r10 *gct; - struct oaktrail_timing_info *dp_ti = &dev_priv->gct_data.DTD; - struct gct_r10_timing_info *ti; - int ret = -1; - - if (read_vbt_r10(addr, &vbt)) - return -1; - - gct = kmalloc(sizeof(*gct) * vbt.panel_count, GFP_KERNEL); - if (!gct) - return -1; - - gct_virtual = ioremap(addr + sizeof(vbt), - sizeof(*gct) * vbt.panel_count); - if (!gct_virtual) - goto out; - memcpy_fromio(gct, gct_virtual, sizeof(*gct)); - iounmap(gct_virtual); - - dev_priv->gct_data.bpi = vbt.primary_panel_idx; - dev_priv->gct_data.Panel_MIPI_Display_Descriptor = - gct[vbt.primary_panel_idx].Panel_MIPI_Display_Descriptor; - - ti = &gct[vbt.primary_panel_idx].DTD; - dp_ti->pixel_clock = ti->pixel_clock; - dp_ti->hactive_hi = ti->hactive_hi; - dp_ti->hactive_lo = ti->hactive_lo; - dp_ti->hblank_hi = ti->hblank_hi; - dp_ti->hblank_lo = ti->hblank_lo; - dp_ti->hsync_offset_hi = ti->hsync_offset_hi; - dp_ti->hsync_offset_lo = ti->hsync_offset_lo; - dp_ti->hsync_pulse_width_hi = ti->hsync_pulse_width_hi; - dp_ti->hsync_pulse_width_lo = ti->hsync_pulse_width_lo; - dp_ti->vactive_hi = ti->vactive_hi; - dp_ti->vactive_lo = ti->vactive_lo; - dp_ti->vblank_hi = ti->vblank_hi; - dp_ti->vblank_lo = ti->vblank_lo; - dp_ti->vsync_offset_hi = ti->vsync_offset_hi; - dp_ti->vsync_offset_lo = ti->vsync_offset_lo; - dp_ti->vsync_pulse_width_hi = ti->vsync_pulse_width_hi; - dp_ti->vsync_pulse_width_lo = ti->vsync_pulse_width_lo; - - ret = 0; -out: - kfree(gct); - return ret; -} - static void mid_get_vbt_data(struct drm_psb_private *dev_priv) { struct drm_device *dev = dev_priv->dev; + struct oaktrail_vbt *vbt = &dev_priv->vbt_data; u32 addr; - u8 __iomem *vbt_virtual; - struct vbt_header vbt_header; + u16 new_size; + u8 *vbt_virtual; + u8 bpi; + u8 number_desc = 0; + struct oaktrail_timing_info *dp_ti = &dev_priv->gct_data.DTD; + struct gct_r10_timing_info ti; + void *pGCT; struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0)); - int ret = -1; - /* Get the address of the platform config vbt */ + /* Get the address of the platform config vbt, B0:D2:F0;0xFC */ pci_read_config_dword(pci_gfx_root, 0xFC, &addr); pci_dev_put(pci_gfx_root); dev_dbg(dev->dev, "drm platform config address is %x\n", addr); - if (!addr) - goto out; + /* check for platform config address == 0. */ + /* this means fw doesn't support vbt */ - /* get the virtual address of the vbt */ - vbt_virtual = ioremap(addr, sizeof(vbt_header)); - if (!vbt_virtual) - goto out; + if (addr == 0) { + vbt->size = 0; + return; + } - memcpy_fromio(&vbt_header, vbt_virtual, sizeof(vbt_header)); - iounmap(vbt_virtual); + /* get the virtual address of the vbt */ + vbt_virtual = ioremap(addr, sizeof(*vbt)); + if (vbt_virtual == NULL) { + vbt->size = 0; + return; + } - if (memcmp(&vbt_header.signature, "$GCT", 4)) - goto out; + memcpy(vbt, vbt_virtual, sizeof(*vbt)); + iounmap(vbt_virtual); /* Free virtual address space */ - dev_dbg(dev->dev, "GCT revision is %02x\n", vbt_header.revision); + /* No matching signature don't process the data */ + if (memcmp(vbt->signature, "$GCT", 4)) { + vbt->size = 0; + return; + } - switch (vbt_header.revision) { - case 0x00: - ret = mid_get_vbt_data_r0(dev_priv, addr); + dev_dbg(dev->dev, "GCT revision is %x\n", vbt->revision); + + switch (vbt->revision) { + case 0: + vbt->oaktrail_gct = ioremap(addr + sizeof(*vbt) - 4, + vbt->size - sizeof(*vbt) + 4); + pGCT = vbt->oaktrail_gct; + bpi = ((struct oaktrail_gct_v1 *)pGCT)->PD.BootPanelIndex; + dev_priv->gct_data.bpi = bpi; + dev_priv->gct_data.pt = + ((struct oaktrail_gct_v1 *)pGCT)->PD.PanelType; + memcpy(&dev_priv->gct_data.DTD, + &((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].DTD, + sizeof(struct oaktrail_timing_info)); + dev_priv->gct_data.Panel_Port_Control = + ((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control; + dev_priv->gct_data.Panel_MIPI_Display_Descriptor = + ((struct oaktrail_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; break; - case 0x01: - ret = mid_get_vbt_data_r1(dev_priv, addr); + case 1: + vbt->oaktrail_gct = ioremap(addr + sizeof(*vbt) - 4, + vbt->size - sizeof(*vbt) + 4); + pGCT = vbt->oaktrail_gct; + bpi = ((struct oaktrail_gct_v2 *)pGCT)->PD.BootPanelIndex; + dev_priv->gct_data.bpi = bpi; + dev_priv->gct_data.pt = + ((struct oaktrail_gct_v2 *)pGCT)->PD.PanelType; + memcpy(&dev_priv->gct_data.DTD, + &((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].DTD, + sizeof(struct oaktrail_timing_info)); + dev_priv->gct_data.Panel_Port_Control = + ((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control; + dev_priv->gct_data.Panel_MIPI_Display_Descriptor = + ((struct oaktrail_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor; break; case 0x10: - ret = mid_get_vbt_data_r10(dev_priv, addr); + /*header definition changed from rev 01 (v2) to rev 10h. */ + /*so, some values have changed location*/ + new_size = vbt->checksum; /*checksum contains lo size byte*/ + /*LSB of oaktrail_gct contains hi size byte*/ + new_size |= ((0xff & (unsigned int)(long)vbt->oaktrail_gct)) << 8; + + vbt->checksum = vbt->size; /*size contains the checksum*/ + if (new_size > 0xff) + vbt->size = 0xff; /*restrict size to 255*/ + else + vbt->size = new_size; + + /* number of descriptors defined in the GCT */ + number_desc = ((0xff00 & (unsigned int)(long)vbt->oaktrail_gct)) >> 8; + bpi = ((0xff0000 & (unsigned int)(long)vbt->oaktrail_gct)) >> 16; + vbt->oaktrail_gct = ioremap(addr + GCT_R10_HEADER_SIZE, + GCT_R10_DISPLAY_DESC_SIZE * number_desc); + pGCT = vbt->oaktrail_gct; + pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE); + dev_priv->gct_data.bpi = bpi; /*save boot panel id*/ + + /*copy the GCT display timings into a temp structure*/ + memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info)); + + /*now copy the temp struct into the dev_priv->gct_data*/ + dp_ti->pixel_clock = ti.pixel_clock; + dp_ti->hactive_hi = ti.hactive_hi; + dp_ti->hactive_lo = ti.hactive_lo; + dp_ti->hblank_hi = ti.hblank_hi; + dp_ti->hblank_lo = ti.hblank_lo; + dp_ti->hsync_offset_hi = ti.hsync_offset_hi; + dp_ti->hsync_offset_lo = ti.hsync_offset_lo; + dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi; + dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo; + dp_ti->vactive_hi = ti.vactive_hi; + dp_ti->vactive_lo = ti.vactive_lo; + dp_ti->vblank_hi = ti.vblank_hi; + dp_ti->vblank_lo = ti.vblank_lo; + dp_ti->vsync_offset_hi = ti.vsync_offset_hi; + dp_ti->vsync_offset_lo = ti.vsync_offset_lo; + dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi; + dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo; + + /* Move the MIPI_Display_Descriptor data from GCT to dev priv */ + dev_priv->gct_data.Panel_MIPI_Display_Descriptor = + *((u8 *)pGCT + 0x0d); + dev_priv->gct_data.Panel_MIPI_Display_Descriptor |= + (*((u8 *)pGCT + 0x0e)) << 8; break; default: dev_err(dev->dev, "Unknown revision of GCT!\n"); + vbt->size = 0; } - -out: - if (ret) - dev_err(dev->dev, "Unable to read GCT!"); - else - dev_priv->has_gct = true; } int mid_chip_setup(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/gma500/oaktrail.h b/trunk/drivers/gpu/drm/gma500/oaktrail.h index f2f9f38a5362..2da1f368f14e 100644 --- a/trunk/drivers/gpu/drm/gma500/oaktrail.h +++ b/trunk/drivers/gpu/drm/gma500/oaktrail.h @@ -19,6 +19,14 @@ /* MID device specific descriptors */ +struct oaktrail_vbt { + s8 signature[4]; /*4 bytes,"$GCT" */ + u8 revision; + u8 size; + u8 checksum; + void *oaktrail_gct; +} __packed; + struct oaktrail_timing_info { u16 pixel_clock; u8 hactive_lo; @@ -153,7 +161,7 @@ union oaktrail_panel_rx { u16 panel_receiver; } __packed; -struct gct_r0 { +struct oaktrail_gct_v1 { union { /*8 bits,Defined as follows: */ struct { u8 PanelType:4; /*4 bits, Bit field for panels*/ @@ -170,7 +178,7 @@ struct gct_r0 { union oaktrail_panel_rx panelrx[4]; /* panel receivers*/ } __packed; -struct gct_r1 { +struct oaktrail_gct_v2 { union { /*8 bits,Defined as follows: */ struct { u8 PanelType:4; /*4 bits, Bit field for panels*/ @@ -187,16 +195,6 @@ struct gct_r1 { union oaktrail_panel_rx panelrx[4]; /* panel receivers*/ } __packed; -struct gct_r10 { - struct gct_r10_timing_info DTD; - u16 Panel_MIPI_Display_Descriptor; - u16 Panel_MIPI_Receiver_Descriptor; - u16 Panel_Backlight_Inverter_Descriptor; - u8 Panel_Initial_Brightness; - u32 MIPI_Ctlr_Init_ptr; - u32 MIPI_Panel_Init_ptr; -} __packed; - struct oaktrail_gct_data { u8 bpi; /* boot panel index, number of panel used during boot */ u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */ @@ -215,6 +213,9 @@ struct oaktrail_gct_data { #define MODE_SETTING_IN_DSR 0x4 #define MODE_SETTING_ENCODER_DONE 0x8 +#define GCT_R10_HEADER_SIZE 16 +#define GCT_R10_DISPLAY_DESC_SIZE 28 + /* * Moorestown HDMI interfaces */ diff --git a/trunk/drivers/gpu/drm/gma500/oaktrail_crtc.c b/trunk/drivers/gpu/drm/gma500/oaktrail_crtc.c index f821c835ca90..a39b0d0d680f 100644 --- a/trunk/drivers/gpu/drm/gma500/oaktrail_crtc.c +++ b/trunk/drivers/gpu/drm/gma500/oaktrail_crtc.c @@ -162,10 +162,12 @@ mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk, static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; + int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + int dspbase_reg = (pipe == 0) ? MRST_DSPABASE : DSPBBASE; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; u32 temp; if (!gma_power_begin(dev, true)) @@ -179,32 +181,32 @@ static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode) case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: /* Enable the DPLL */ - temp = REG_READ(map->dpll); + temp = REG_READ(dpll_reg); if ((temp & DPLL_VCO_ENABLE) == 0) { - REG_WRITE(map->dpll, temp); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); - REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); - REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); } /* Enable the pipe */ - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); if ((temp & PIPEACONF_ENABLE) == 0) - REG_WRITE(map->conf, temp | PIPEACONF_ENABLE); + REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); /* Enable the plane */ - temp = REG_READ(map->cntr); + temp = REG_READ(dspcntr_reg); if ((temp & DISPLAY_PLANE_ENABLE) == 0) { - REG_WRITE(map->cntr, + REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE); /* Flush the plane changes */ - REG_WRITE(map->base, REG_READ(map->base)); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); } psb_intel_crtc_load_lut(crtc); @@ -221,28 +223,28 @@ static void oaktrail_crtc_dpms(struct drm_crtc *crtc, int mode) /* Disable the VGA plane that we never use */ REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); /* Disable display plane */ - temp = REG_READ(map->cntr); + temp = REG_READ(dspcntr_reg); if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - REG_WRITE(map->cntr, + REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); /* Flush the plane changes */ - REG_WRITE(map->base, REG_READ(map->base)); - REG_READ(map->base); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + REG_READ(dspbase_reg); } /* Next, disable display pipes */ - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); if ((temp & PIPEACONF_ENABLE) != 0) { - REG_WRITE(map->conf, temp & ~PIPEACONF_ENABLE); - REG_READ(map->conf); + REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); + REG_READ(pipeconf_reg); } /* Wait for for the pipe disable to take effect. */ psb_intel_wait_for_vblank(dev); - temp = REG_READ(map->dpll); + temp = REG_READ(dpll_reg); if ((temp & DPLL_VCO_ENABLE) != 0) { - REG_WRITE(map->dpll, temp & ~DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); + REG_READ(dpll_reg); } /* Wait for the clocks to turn off. */ @@ -290,7 +292,17 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct drm_psb_private *dev_priv = dev->dev_private; int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; + int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0; + int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; + int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; + int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; + int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; + int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; + int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; + int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; int refclk = 0; struct oaktrail_clock_t clock; u32 dpll = 0, fp = 0, dspcntr, pipeconf; @@ -338,7 +350,7 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, if (oaktrail_panel_fitter_pipe(dev) == pipe) REG_WRITE(PFIT_CONTROL, 0); - REG_WRITE(map->src, + REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); @@ -357,34 +369,34 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, offsetY = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2; - REG_WRITE(map->htotal, (mode->crtc_hdisplay - 1) | + REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(map->vtotal, (mode->crtc_vdisplay - 1) | + REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(map->hblank, + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - offsetX - 1) | ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16)); - REG_WRITE(map->hsync, + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - offsetX - 1) | ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16)); - REG_WRITE(map->vblank, + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - offsetY - 1) | ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16)); - REG_WRITE(map->vsync, + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - offsetY - 1) | ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16)); } else { - REG_WRITE(map->htotal, (adjusted_mode->crtc_hdisplay - 1) | + REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) | + REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - 1) | + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16)); - REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - 1) | + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16)); - REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - 1) | + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16)); - REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - 1) | + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); } @@ -396,10 +408,10 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, } /* setup pipeconf */ - pipeconf = REG_READ(map->conf); + pipeconf = REG_READ(pipeconf_reg); /* Set up the display plane register */ - dspcntr = REG_READ(map->cntr); + dspcntr = REG_READ(dspcntr_reg); dspcntr |= DISPPLANE_GAMMA_ENABLE; if (pipe == 0) @@ -455,30 +467,30 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, mrstPrintPll("chosen", &clock); if (dpll & DPLL_VCO_ENABLE) { - REG_WRITE(map->fp0, fp); - REG_WRITE(map->dpll, dpll & ~DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(fp_reg, fp); + REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); + REG_READ(dpll_reg); /* Check the DPLLA lock bit PIPEACONF[29] */ udelay(150); } - REG_WRITE(map->fp0, fp); - REG_WRITE(map->dpll, dpll); - REG_READ(map->dpll); + REG_WRITE(fp_reg, fp); + REG_WRITE(dpll_reg, dpll); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); /* write it again -- the BIOS does, after all */ - REG_WRITE(map->dpll, dpll); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, dpll); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); - REG_WRITE(map->conf, pipeconf); - REG_READ(map->conf); + REG_WRITE(pipeconf_reg, pipeconf); + REG_READ(pipeconf_reg); psb_intel_wait_for_vblank(dev); - REG_WRITE(map->cntr, dspcntr); + REG_WRITE(dspcntr_reg, dspcntr); psb_intel_wait_for_vblank(dev); oaktrail_crtc_mode_set_exit: @@ -497,13 +509,15 @@ static int oaktrail_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; unsigned long start, offset; + int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE); + int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); + int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; u32 dspcntr; int ret = 0; @@ -519,9 +533,9 @@ static int oaktrail_pipe_set_base(struct drm_crtc *crtc, start = psbfb->gtt->offset; offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); - REG_WRITE(map->stride, crtc->fb->pitches[0]); + REG_WRITE(dspstride, crtc->fb->pitches[0]); - dspcntr = REG_READ(map->cntr); + dspcntr = REG_READ(dspcntr_reg); dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; switch (crtc->fb->bits_per_pixel) { @@ -543,12 +557,12 @@ static int oaktrail_pipe_set_base(struct drm_crtc *crtc, ret = -EINVAL; goto pipe_set_base_exit; } - REG_WRITE(map->cntr, dspcntr); + REG_WRITE(dspcntr_reg, dspcntr); - REG_WRITE(map->base, offset); - REG_READ(map->base); - REG_WRITE(map->surf, start); - REG_READ(map->surf); + REG_WRITE(dspbase, offset); + REG_READ(dspbase); + REG_WRITE(dspsurf, start); + REG_READ(dspsurf); pipe_set_base_exit: gma_power_end(dev); diff --git a/trunk/drivers/gpu/drm/gma500/oaktrail_device.c b/trunk/drivers/gpu/drm/gma500/oaktrail_device.c index 7a8ff8e2dfc0..4c5a1864adf4 100644 --- a/trunk/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/trunk/drivers/gpu/drm/gma500/oaktrail_device.c @@ -187,7 +187,6 @@ static int oaktrail_save_display_registers(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; struct psb_save_area *regs = &dev_priv->regs; - struct psb_pipe *p = ®s->pipe[0]; int i; u32 pp_stat; @@ -202,24 +201,24 @@ static int oaktrail_save_display_registers(struct drm_device *dev) regs->psb.saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT); /* Pipe & plane A info */ - p->conf = PSB_RVDC32(PIPEACONF); - p->src = PSB_RVDC32(PIPEASRC); - p->fp0 = PSB_RVDC32(MRST_FPA0); - p->fp1 = PSB_RVDC32(MRST_FPA1); - p->dpll = PSB_RVDC32(MRST_DPLL_A); - p->htotal = PSB_RVDC32(HTOTAL_A); - p->hblank = PSB_RVDC32(HBLANK_A); - p->hsync = PSB_RVDC32(HSYNC_A); - p->vtotal = PSB_RVDC32(VTOTAL_A); - p->vblank = PSB_RVDC32(VBLANK_A); - p->vsync = PSB_RVDC32(VSYNC_A); + regs->psb.savePIPEACONF = PSB_RVDC32(PIPEACONF); + regs->psb.savePIPEASRC = PSB_RVDC32(PIPEASRC); + regs->psb.saveFPA0 = PSB_RVDC32(MRST_FPA0); + regs->psb.saveFPA1 = PSB_RVDC32(MRST_FPA1); + regs->psb.saveDPLL_A = PSB_RVDC32(MRST_DPLL_A); + regs->psb.saveHTOTAL_A = PSB_RVDC32(HTOTAL_A); + regs->psb.saveHBLANK_A = PSB_RVDC32(HBLANK_A); + regs->psb.saveHSYNC_A = PSB_RVDC32(HSYNC_A); + regs->psb.saveVTOTAL_A = PSB_RVDC32(VTOTAL_A); + regs->psb.saveVBLANK_A = PSB_RVDC32(VBLANK_A); + regs->psb.saveVSYNC_A = PSB_RVDC32(VSYNC_A); regs->psb.saveBCLRPAT_A = PSB_RVDC32(BCLRPAT_A); - p->cntr = PSB_RVDC32(DSPACNTR); - p->stride = PSB_RVDC32(DSPASTRIDE); - p->addr = PSB_RVDC32(DSPABASE); - p->surf = PSB_RVDC32(DSPASURF); - p->linoff = PSB_RVDC32(DSPALINOFF); - p->tileoff = PSB_RVDC32(DSPATILEOFF); + regs->psb.saveDSPACNTR = PSB_RVDC32(DSPACNTR); + regs->psb.saveDSPASTRIDE = PSB_RVDC32(DSPASTRIDE); + regs->psb.saveDSPAADDR = PSB_RVDC32(DSPABASE); + regs->psb.saveDSPASURF = PSB_RVDC32(DSPASURF); + regs->psb.saveDSPALINOFF = PSB_RVDC32(DSPALINOFF); + regs->psb.saveDSPATILEOFF = PSB_RVDC32(DSPATILEOFF); /* Save cursor regs */ regs->psb.saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR); @@ -228,7 +227,7 @@ static int oaktrail_save_display_registers(struct drm_device *dev) /* Save palette (gamma) */ for (i = 0; i < 256; i++) - p->palette[i] = PSB_RVDC32(PALETTE_A + (i << 2)); + regs->psb.save_palette_a[i] = PSB_RVDC32(PALETTE_A + (i << 2)); if (dev_priv->hdmi_priv) oaktrail_hdmi_save(dev); @@ -301,7 +300,6 @@ static int oaktrail_restore_display_registers(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; struct psb_save_area *regs = &dev_priv->regs; - struct psb_pipe *p = ®s->pipe[0]; u32 pp_stat; int i; @@ -319,21 +317,21 @@ static int oaktrail_restore_display_registers(struct drm_device *dev) PSB_WVDC32(0x80000000, VGACNTRL); /* set the plls */ - PSB_WVDC32(p->fp0, MRST_FPA0); - PSB_WVDC32(p->fp1, MRST_FPA1); + PSB_WVDC32(regs->psb.saveFPA0, MRST_FPA0); + PSB_WVDC32(regs->psb.saveFPA1, MRST_FPA1); /* Actually enable it */ - PSB_WVDC32(p->dpll, MRST_DPLL_A); + PSB_WVDC32(regs->psb.saveDPLL_A, MRST_DPLL_A); DRM_UDELAY(150); /* Restore mode */ - PSB_WVDC32(p->htotal, HTOTAL_A); - PSB_WVDC32(p->hblank, HBLANK_A); - PSB_WVDC32(p->hsync, HSYNC_A); - PSB_WVDC32(p->vtotal, VTOTAL_A); - PSB_WVDC32(p->vblank, VBLANK_A); - PSB_WVDC32(p->vsync, VSYNC_A); - PSB_WVDC32(p->src, PIPEASRC); + PSB_WVDC32(regs->psb.saveHTOTAL_A, HTOTAL_A); + PSB_WVDC32(regs->psb.saveHBLANK_A, HBLANK_A); + PSB_WVDC32(regs->psb.saveHSYNC_A, HSYNC_A); + PSB_WVDC32(regs->psb.saveVTOTAL_A, VTOTAL_A); + PSB_WVDC32(regs->psb.saveVBLANK_A, VBLANK_A); + PSB_WVDC32(regs->psb.saveVSYNC_A, VSYNC_A); + PSB_WVDC32(regs->psb.savePIPEASRC, PIPEASRC); PSB_WVDC32(regs->psb.saveBCLRPAT_A, BCLRPAT_A); /* Restore performance mode*/ @@ -341,16 +339,16 @@ static int oaktrail_restore_display_registers(struct drm_device *dev) /* Enable the pipe*/ if (dev_priv->iLVDS_enable) - PSB_WVDC32(p->conf, PIPEACONF); + PSB_WVDC32(regs->psb.savePIPEACONF, PIPEACONF); /* Set up the plane*/ - PSB_WVDC32(p->linoff, DSPALINOFF); - PSB_WVDC32(p->stride, DSPASTRIDE); - PSB_WVDC32(p->tileoff, DSPATILEOFF); + PSB_WVDC32(regs->psb.saveDSPALINOFF, DSPALINOFF); + PSB_WVDC32(regs->psb.saveDSPASTRIDE, DSPASTRIDE); + PSB_WVDC32(regs->psb.saveDSPATILEOFF, DSPATILEOFF); /* Enable the plane */ - PSB_WVDC32(p->cntr, DSPACNTR); - PSB_WVDC32(p->surf, DSPASURF); + PSB_WVDC32(regs->psb.saveDSPACNTR, DSPACNTR); + PSB_WVDC32(regs->psb.saveDSPASURF, DSPASURF); /* Enable Cursor A */ PSB_WVDC32(regs->psb.saveDSPACURSOR_CTRL, CURACNTR); @@ -359,7 +357,7 @@ static int oaktrail_restore_display_registers(struct drm_device *dev) /* Restore palette (gamma) */ for (i = 0; i < 256; i++) - PSB_WVDC32(p->palette[i], PALETTE_A + (i << 2)); + PSB_WVDC32(regs->psb.save_palette_a[i], PALETTE_A + (i << 2)); if (dev_priv->hdmi_priv) oaktrail_hdmi_restore(dev); @@ -456,84 +454,31 @@ static int oaktrail_power_up(struct drm_device *dev) return 0; } -/* Oaktrail */ -static const struct psb_offset oaktrail_regmap[2] = { - { - .fp0 = MRST_FPA0, - .fp1 = MRST_FPA1, - .cntr = DSPACNTR, - .conf = PIPEACONF, - .src = PIPEASRC, - .dpll = MRST_DPLL_A, - .htotal = HTOTAL_A, - .hblank = HBLANK_A, - .hsync = HSYNC_A, - .vtotal = VTOTAL_A, - .vblank = VBLANK_A, - .vsync = VSYNC_A, - .stride = DSPASTRIDE, - .size = DSPASIZE, - .pos = DSPAPOS, - .surf = DSPASURF, - .addr = MRST_DSPABASE, - .status = PIPEASTAT, - .linoff = DSPALINOFF, - .tileoff = DSPATILEOFF, - .palette = PALETTE_A, - }, - { - .fp0 = FPB0, - .fp1 = FPB1, - .cntr = DSPBCNTR, - .conf = PIPEBCONF, - .src = PIPEBSRC, - .dpll = DPLL_B, - .htotal = HTOTAL_B, - .hblank = HBLANK_B, - .hsync = HSYNC_B, - .vtotal = VTOTAL_B, - .vblank = VBLANK_B, - .vsync = VSYNC_B, - .stride = DSPBSTRIDE, - .size = DSPBSIZE, - .pos = DSPBPOS, - .surf = DSPBSURF, - .addr = DSPBBASE, - .status = PIPEBSTAT, - .linoff = DSPBLINOFF, - .tileoff = DSPBTILEOFF, - .palette = PALETTE_B, - }, -}; static int oaktrail_chip_setup(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; + struct oaktrail_vbt *vbt = &dev_priv->vbt_data; int ret; - if (pci_enable_msi(dev->pdev)) - dev_warn(dev->dev, "Enabling MSI failed!\n"); - - dev_priv->regmap = oaktrail_regmap; - ret = mid_chip_setup(dev); if (ret < 0) return ret; - if (!dev_priv->has_gct) { + if (vbt->size == 0) { /* Now pull the BIOS data */ - psb_intel_opregion_init(dev); + gma_intel_opregion_init(dev); psb_intel_init_bios(dev); } - oaktrail_hdmi_setup(dev); return 0; } static void oaktrail_teardown(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; + struct oaktrail_vbt *vbt = &dev_priv->vbt_data; oaktrail_hdmi_teardown(dev); - if (!dev_priv->has_gct) + if (vbt->size == 0) psb_intel_destroy_bios(dev); } diff --git a/trunk/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/trunk/drivers/gpu/drm/gma500/oaktrail_hdmi.c index c10899c953b9..25956601191f 100644 --- a/trunk/drivers/gpu/drm/gma500/oaktrail_hdmi.c +++ b/trunk/drivers/gpu/drm/gma500/oaktrail_hdmi.c @@ -434,7 +434,6 @@ void oaktrail_hdmi_save(struct drm_device *dev) struct drm_psb_private *dev_priv = dev->dev_private; struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; struct psb_state *regs = &dev_priv->regs.psb; - struct psb_pipe *pipeb = &dev_priv->regs.pipe[1]; int i; /* dpll */ @@ -445,14 +444,14 @@ void oaktrail_hdmi_save(struct drm_device *dev) hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE); /* pipe B */ - pipeb->conf = PSB_RVDC32(PIPEBCONF); - pipeb->src = PSB_RVDC32(PIPEBSRC); - pipeb->htotal = PSB_RVDC32(HTOTAL_B); - pipeb->hblank = PSB_RVDC32(HBLANK_B); - pipeb->hsync = PSB_RVDC32(HSYNC_B); - pipeb->vtotal = PSB_RVDC32(VTOTAL_B); - pipeb->vblank = PSB_RVDC32(VBLANK_B); - pipeb->vsync = PSB_RVDC32(VSYNC_B); + regs->savePIPEBCONF = PSB_RVDC32(PIPEBCONF); + regs->savePIPEBSRC = PSB_RVDC32(PIPEBSRC); + regs->saveHTOTAL_B = PSB_RVDC32(HTOTAL_B); + regs->saveHBLANK_B = PSB_RVDC32(HBLANK_B); + regs->saveHSYNC_B = PSB_RVDC32(HSYNC_B); + regs->saveVTOTAL_B = PSB_RVDC32(VTOTAL_B); + regs->saveVBLANK_B = PSB_RVDC32(VBLANK_B); + regs->saveVSYNC_B = PSB_RVDC32(VSYNC_B); hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF); hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC); @@ -464,12 +463,12 @@ void oaktrail_hdmi_save(struct drm_device *dev) hdmi_dev->savePCH_VSYNC_B = PSB_RVDC32(PCH_VSYNC_B); /* plane */ - pipeb->cntr = PSB_RVDC32(DSPBCNTR); - pipeb->stride = PSB_RVDC32(DSPBSTRIDE); - pipeb->addr = PSB_RVDC32(DSPBBASE); - pipeb->surf = PSB_RVDC32(DSPBSURF); - pipeb->linoff = PSB_RVDC32(DSPBLINOFF); - pipeb->tileoff = PSB_RVDC32(DSPBTILEOFF); + regs->saveDSPBCNTR = PSB_RVDC32(DSPBCNTR); + regs->saveDSPBSTRIDE = PSB_RVDC32(DSPBSTRIDE); + regs->saveDSPBADDR = PSB_RVDC32(DSPBBASE); + regs->saveDSPBSURF = PSB_RVDC32(DSPBSURF); + regs->saveDSPBLINOFF = PSB_RVDC32(DSPBLINOFF); + regs->saveDSPBTILEOFF = PSB_RVDC32(DSPBTILEOFF); /* cursor B */ regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR); @@ -478,7 +477,7 @@ void oaktrail_hdmi_save(struct drm_device *dev) /* save palette */ for (i = 0; i < 256; i++) - pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2)); + regs->save_palette_b[i] = PSB_RVDC32(PALETTE_B + (i << 2)); } /* restore HDMI register state */ @@ -487,7 +486,6 @@ void oaktrail_hdmi_restore(struct drm_device *dev) struct drm_psb_private *dev_priv = dev->dev_private; struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv; struct psb_state *regs = &dev_priv->regs.psb; - struct psb_pipe *pipeb = &dev_priv->regs.pipe[1]; int i; /* dpll */ @@ -499,13 +497,13 @@ void oaktrail_hdmi_restore(struct drm_device *dev) DRM_UDELAY(150); /* pipe */ - PSB_WVDC32(pipeb->src, PIPEBSRC); - PSB_WVDC32(pipeb->htotal, HTOTAL_B); - PSB_WVDC32(pipeb->hblank, HBLANK_B); - PSB_WVDC32(pipeb->hsync, HSYNC_B); - PSB_WVDC32(pipeb->vtotal, VTOTAL_B); - PSB_WVDC32(pipeb->vblank, VBLANK_B); - PSB_WVDC32(pipeb->vsync, VSYNC_B); + PSB_WVDC32(regs->savePIPEBSRC, PIPEBSRC); + PSB_WVDC32(regs->saveHTOTAL_B, HTOTAL_B); + PSB_WVDC32(regs->saveHBLANK_B, HBLANK_B); + PSB_WVDC32(regs->saveHSYNC_B, HSYNC_B); + PSB_WVDC32(regs->saveVTOTAL_B, VTOTAL_B); + PSB_WVDC32(regs->saveVBLANK_B, VBLANK_B); + PSB_WVDC32(regs->saveVSYNC_B, VSYNC_B); PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC); PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B); @@ -515,15 +513,15 @@ void oaktrail_hdmi_restore(struct drm_device *dev) PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B); PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B, PCH_VSYNC_B); - PSB_WVDC32(pipeb->conf, PIPEBCONF); + PSB_WVDC32(regs->savePIPEBCONF, PIPEBCONF); PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF); /* plane */ - PSB_WVDC32(pipeb->linoff, DSPBLINOFF); - PSB_WVDC32(pipeb->stride, DSPBSTRIDE); - PSB_WVDC32(pipeb->tileoff, DSPBTILEOFF); - PSB_WVDC32(pipeb->cntr, DSPBCNTR); - PSB_WVDC32(pipeb->surf, DSPBSURF); + PSB_WVDC32(regs->saveDSPBLINOFF, DSPBLINOFF); + PSB_WVDC32(regs->saveDSPBSTRIDE, DSPBSTRIDE); + PSB_WVDC32(regs->saveDSPBTILEOFF, DSPBTILEOFF); + PSB_WVDC32(regs->saveDSPBCNTR, DSPBCNTR); + PSB_WVDC32(regs->saveDSPBSURF, DSPBSURF); /* cursor B */ PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR); @@ -532,5 +530,5 @@ void oaktrail_hdmi_restore(struct drm_device *dev) /* restore palette */ for (i = 0; i < 256; i++) - PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2)); + PSB_WVDC32(regs->save_palette_b[i], PALETTE_B + (i << 2)); } diff --git a/trunk/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c b/trunk/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c index 88627e3ba1e3..5e84fbde749b 100644 --- a/trunk/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c +++ b/trunk/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c @@ -250,7 +250,7 @@ static irqreturn_t oaktrail_hdmi_i2c_handler(int this_irq, void *dev) */ static void oaktrail_hdmi_i2c_gpio_fix(void) { - void __iomem *base; + void *base; unsigned int gpio_base = 0xff12c000; int gpio_len = 0x1000; u32 temp; diff --git a/trunk/drivers/gpu/drm/gma500/oaktrail_lvds.c b/trunk/drivers/gpu/drm/gma500/oaktrail_lvds.c index 558c77fb55ec..654f32b22b21 100644 --- a/trunk/drivers/gpu/drm/gma500/oaktrail_lvds.c +++ b/trunk/drivers/gpu/drm/gma500/oaktrail_lvds.c @@ -257,7 +257,7 @@ static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev, mode_dev->panel_fixed_mode = NULL; /* Use the firmware provided data on Moorestown */ - if (dev_priv->has_gct) { + if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/ mode = kzalloc(sizeof(*mode), GFP_KERNEL); if (!mode) return; @@ -371,7 +371,7 @@ void oaktrail_lvds_init(struct drm_device *dev, BRIGHTNESS_MAX_LEVEL); mode_dev->panel_wants_dither = false; - if (dev_priv->has_gct) + if (dev_priv->vbt_data.size != 0x00) mode_dev->panel_wants_dither = (dev_priv->gct_data. Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE); if (dev_priv->lvds_dither) diff --git a/trunk/drivers/gpu/drm/gma500/opregion.c b/trunk/drivers/gpu/drm/gma500/opregion.c deleted file mode 100644 index aa9e89f7e4c2..000000000000 --- a/trunk/drivers/gpu/drm/gma500/opregion.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright 2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ -#include -#include -#include "psb_drv.h" -#include "psb_intel_reg.h" - -#define PCI_ASLE 0xe4 -#define PCI_ASLS 0xfc - -#define OPREGION_HEADER_OFFSET 0 -#define OPREGION_ACPI_OFFSET 0x100 -#define ACPI_CLID 0x01ac /* current lid state indicator */ -#define ACPI_CDCK 0x01b0 /* current docking state indicator */ -#define OPREGION_SWSCI_OFFSET 0x200 -#define OPREGION_ASLE_OFFSET 0x300 -#define OPREGION_VBT_OFFSET 0x400 - -#define OPREGION_SIGNATURE "IntelGraphicsMem" -#define MBOX_ACPI (1<<0) -#define MBOX_SWSCI (1<<1) -#define MBOX_ASLE (1<<2) - -struct opregion_header { - u8 signature[16]; - u32 size; - u32 opregion_ver; - u8 bios_ver[32]; - u8 vbios_ver[16]; - u8 driver_ver[16]; - u32 mboxes; - u8 reserved[164]; -} __packed; - -/* OpRegion mailbox #1: public ACPI methods */ -struct opregion_acpi { - u32 drdy; /* driver readiness */ - u32 csts; /* notification status */ - u32 cevt; /* current event */ - u8 rsvd1[20]; - u32 didl[8]; /* supported display devices ID list */ - u32 cpdl[8]; /* currently presented display list */ - u32 cadl[8]; /* currently active display list */ - u32 nadl[8]; /* next active devices list */ - u32 aslp; /* ASL sleep time-out */ - u32 tidx; /* toggle table index */ - u32 chpd; /* current hotplug enable indicator */ - u32 clid; /* current lid state*/ - u32 cdck; /* current docking state */ - u32 sxsw; /* Sx state resume */ - u32 evts; /* ASL supported events */ - u32 cnot; /* current OS notification */ - u32 nrdy; /* driver status */ - u8 rsvd2[60]; -} __packed; - -/* OpRegion mailbox #2: SWSCI */ -struct opregion_swsci { - /*FIXME: add it later*/ -} __packed; - -/* OpRegion mailbox #3: ASLE */ -struct opregion_asle { - u32 ardy; /* driver readiness */ - u32 aslc; /* ASLE interrupt command */ - u32 tche; /* technology enabled indicator */ - u32 alsi; /* current ALS illuminance reading */ - u32 bclp; /* backlight brightness to set */ - u32 pfit; /* panel fitting state */ - u32 cblv; /* current brightness level */ - u16 bclm[20]; /* backlight level duty cycle mapping table */ - u32 cpfm; /* current panel fitting mode */ - u32 epfm; /* enabled panel fitting modes */ - u8 plut[74]; /* panel LUT and identifier */ - u32 pfmb; /* PWM freq and min brightness */ - u8 rsvd[102]; -} __packed; - -/* ASLE irq request bits */ -#define ASLE_SET_ALS_ILLUM (1 << 0) -#define ASLE_SET_BACKLIGHT (1 << 1) -#define ASLE_SET_PFIT (1 << 2) -#define ASLE_SET_PWM_FREQ (1 << 3) -#define ASLE_REQ_MSK 0xf - -/* response bits of ASLE irq request */ -#define ASLE_ALS_ILLUM_FAILED (1<<10) -#define ASLE_BACKLIGHT_FAILED (1<<12) -#define ASLE_PFIT_FAILED (1<<14) -#define ASLE_PWM_FREQ_FAILED (1<<16) - -/* ASLE backlight brightness to set */ -#define ASLE_BCLP_VALID (1<<31) -#define ASLE_BCLP_MSK (~(1<<31)) - -/* ASLE panel fitting request */ -#define ASLE_PFIT_VALID (1<<31) -#define ASLE_PFIT_CENTER (1<<0) -#define ASLE_PFIT_STRETCH_TEXT (1<<1) -#define ASLE_PFIT_STRETCH_GFX (1<<2) - -/* response bits of ASLE irq request */ -#define ASLE_ALS_ILLUM_FAILED (1<<10) -#define ASLE_BACKLIGHT_FAILED (1<<12) -#define ASLE_PFIT_FAILED (1<<14) -#define ASLE_PWM_FREQ_FAILED (1<<16) - -/* ASLE backlight brightness to set */ -#define ASLE_BCLP_VALID (1<<31) -#define ASLE_BCLP_MSK (~(1<<31)) - -/* ASLE panel fitting request */ -#define ASLE_PFIT_VALID (1<<31) -#define ASLE_PFIT_CENTER (1<<0) -#define ASLE_PFIT_STRETCH_TEXT (1<<1) -#define ASLE_PFIT_STRETCH_GFX (1<<2) - -/* PWM frequency and minimum brightness */ -#define ASLE_PFMB_BRIGHTNESS_MASK (0xff) -#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8) -#define ASLE_PFMB_PWM_MASK (0x7ffffe00) -#define ASLE_PFMB_PWM_VALID (1<<31) - -#define ASLE_CBLV_VALID (1<<31) - -static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct opregion_asle *asle = dev_priv->opregion.asle; - struct backlight_device *bd = dev_priv->backlight_device; - u32 max; - - DRM_DEBUG_DRIVER("asle set backlight %x\n", bclp); - - if (!(bclp & ASLE_BCLP_VALID)) - return ASLE_BACKLIGHT_FAILED; - - if (bd == NULL) - return ASLE_BACKLIGHT_FAILED; - - bclp &= ASLE_BCLP_MSK; - if (bclp > 255) - return ASLE_BACKLIGHT_FAILED; - -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - max = bd->props.max_brightness; - bd->props.brightness = bclp * max / 255; - backlight_update_status(bd); -#endif - asle->cblv = (bclp * 0x64) / 0xff | ASLE_CBLV_VALID; - - return 0; -} - -void psb_intel_opregion_asle_intr(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct opregion_asle *asle = dev_priv->opregion.asle; - u32 asle_stat = 0; - u32 asle_req; - - if (!asle) - return; - - asle_req = asle->aslc & ASLE_REQ_MSK; - if (!asle_req) { - DRM_DEBUG_DRIVER("non asle set request??\n"); - return; - } - - if (asle_req & ASLE_SET_BACKLIGHT) - asle_stat |= asle_set_backlight(dev, asle->bclp); - - asle->aslc = asle_stat; -} - -#define ASLE_ALS_EN (1<<0) -#define ASLE_BLC_EN (1<<1) -#define ASLE_PFIT_EN (1<<2) -#define ASLE_PFMB_EN (1<<3) - -void psb_intel_opregion_enable_asle(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct opregion_asle *asle = dev_priv->opregion.asle; - - if (asle) { - /* Don't do this on Medfield or other non PC like devices, they - use the bit for something different altogether */ - psb_enable_pipestat(dev_priv, 0, PIPE_LEGACY_BLC_EVENT_ENABLE); - psb_enable_pipestat(dev_priv, 1, PIPE_LEGACY_BLC_EVENT_ENABLE); - - asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN - | ASLE_PFMB_EN; - asle->ardy = 1; - } -} - -#define ACPI_EV_DISPLAY_SWITCH (1<<0) -#define ACPI_EV_LID (1<<1) -#define ACPI_EV_DOCK (1<<2) - -static struct psb_intel_opregion *system_opregion; - -static int psb_intel_opregion_video_event(struct notifier_block *nb, - unsigned long val, void *data) -{ - /* The only video events relevant to opregion are 0x80. These indicate - either a docking event, lid switch or display switch request. In - Linux, these are handled by the dock, button and video drivers. - We might want to fix the video driver to be opregion-aware in - future, but right now we just indicate to the firmware that the - request has been handled */ - - struct opregion_acpi *acpi; - - if (!system_opregion) - return NOTIFY_DONE; - - acpi = system_opregion->acpi; - acpi->csts = 0; - - return NOTIFY_OK; -} - -static struct notifier_block psb_intel_opregion_notifier = { - .notifier_call = psb_intel_opregion_video_event, -}; - -void psb_intel_opregion_init(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_opregion *opregion = &dev_priv->opregion; - - if (!opregion->header) - return; - - if (opregion->acpi) { - /* Notify BIOS we are ready to handle ACPI video ext notifs. - * Right now, all the events are handled by the ACPI video - * module. We don't actually need to do anything with them. */ - opregion->acpi->csts = 0; - opregion->acpi->drdy = 1; - - system_opregion = opregion; - register_acpi_notifier(&psb_intel_opregion_notifier); - } - - if (opregion->asle) - psb_intel_opregion_enable_asle(dev); -} - -void psb_intel_opregion_fini(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_opregion *opregion = &dev_priv->opregion; - - if (!opregion->header) - return; - - if (opregion->acpi) { - opregion->acpi->drdy = 0; - - system_opregion = NULL; - unregister_acpi_notifier(&psb_intel_opregion_notifier); - } - - /* just clear all opregion memory pointers now */ - iounmap(opregion->header); - opregion->header = NULL; - opregion->acpi = NULL; - opregion->swsci = NULL; - opregion->asle = NULL; - opregion->vbt = NULL; -} - -int psb_intel_opregion_setup(struct drm_device *dev) -{ - struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_intel_opregion *opregion = &dev_priv->opregion; - u32 opregion_phy, mboxes; - void __iomem *base; - int err = 0; - - pci_read_config_dword(dev->pdev, PCI_ASLS, &opregion_phy); - if (opregion_phy == 0) { - DRM_DEBUG_DRIVER("ACPI Opregion not supported\n"); - return -ENOTSUPP; - } - DRM_DEBUG("OpRegion detected at 0x%8x\n", opregion_phy); - base = acpi_os_ioremap(opregion_phy, 8*1024); - if (!base) - return -ENOMEM; - - if (memcmp(base, OPREGION_SIGNATURE, 16)) { - DRM_DEBUG_DRIVER("opregion signature mismatch\n"); - err = -EINVAL; - goto err_out; - } - - opregion->header = base; - opregion->vbt = base + OPREGION_VBT_OFFSET; - - opregion->lid_state = base + ACPI_CLID; - - mboxes = opregion->header->mboxes; - if (mboxes & MBOX_ACPI) { - DRM_DEBUG_DRIVER("Public ACPI methods supported\n"); - opregion->acpi = base + OPREGION_ACPI_OFFSET; - } - - if (mboxes & MBOX_ASLE) { - DRM_DEBUG_DRIVER("ASLE supported\n"); - opregion->asle = base + OPREGION_ASLE_OFFSET; - } - - return 0; - -err_out: - iounmap(base); - return err; -} - diff --git a/trunk/drivers/gpu/drm/gma500/opregion.h b/trunk/drivers/gpu/drm/gma500/opregion.h deleted file mode 100644 index 72dc6b921265..000000000000 --- a/trunk/drivers/gpu/drm/gma500/opregion.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#if defined(CONFIG_ACPI) -extern void psb_intel_opregion_asle_intr(struct drm_device *dev); -extern void psb_intel_opregion_init(struct drm_device *dev); -extern void psb_intel_opregion_fini(struct drm_device *dev); -extern int psb_intel_opregion_setup(struct drm_device *dev); - -#else - -extern inline void psb_intel_opregion_asle_intr(struct drm_device *dev) -{ -} - -extern inline void psb_intel_opregion_init(struct drm_device *dev) -{ -} - -extern inline void psb_intel_opregion_fini(struct drm_device *dev) -{ -} - -extern inline int psb_intel_opregion_setup(struct drm_device *dev) -{ - return 0; -} -#endif diff --git a/trunk/drivers/gpu/drm/gma500/psb_device.c b/trunk/drivers/gpu/drm/gma500/psb_device.c index 651af6768e14..34e6866a73b2 100644 --- a/trunk/drivers/gpu/drm/gma500/psb_device.c +++ b/trunk/drivers/gpu/drm/gma500/psb_device.c @@ -289,65 +289,11 @@ static void psb_get_core_freq(struct drm_device *dev) } } -/* Poulsbo */ -static const struct psb_offset psb_regmap[2] = { - { - .fp0 = FPA0, - .fp1 = FPA1, - .cntr = DSPACNTR, - .conf = PIPEACONF, - .src = PIPEASRC, - .dpll = DPLL_A, - .htotal = HTOTAL_A, - .hblank = HBLANK_A, - .hsync = HSYNC_A, - .vtotal = VTOTAL_A, - .vblank = VBLANK_A, - .vsync = VSYNC_A, - .stride = DSPASTRIDE, - .size = DSPASIZE, - .pos = DSPAPOS, - .base = DSPABASE, - .surf = DSPASURF, - .addr = DSPABASE, - .status = PIPEASTAT, - .linoff = DSPALINOFF, - .tileoff = DSPATILEOFF, - .palette = PALETTE_A, - }, - { - .fp0 = FPB0, - .fp1 = FPB1, - .cntr = DSPBCNTR, - .conf = PIPEBCONF, - .src = PIPEBSRC, - .dpll = DPLL_B, - .htotal = HTOTAL_B, - .hblank = HBLANK_B, - .hsync = HSYNC_B, - .vtotal = VTOTAL_B, - .vblank = VBLANK_B, - .vsync = VSYNC_B, - .stride = DSPBSTRIDE, - .size = DSPBSIZE, - .pos = DSPBPOS, - .base = DSPBBASE, - .surf = DSPBSURF, - .addr = DSPBBASE, - .status = PIPEBSTAT, - .linoff = DSPBLINOFF, - .tileoff = DSPBTILEOFF, - .palette = PALETTE_B, - } -}; - static int psb_chip_setup(struct drm_device *dev) { - struct drm_psb_private *dev_priv = dev->dev_private; - dev_priv->regmap = psb_regmap; psb_get_core_freq(dev); gma_intel_setup_gmbus(dev); - psb_intel_opregion_init(dev); + gma_intel_opregion_init(dev); psb_intel_init_bios(dev); return 0; } diff --git a/trunk/drivers/gpu/drm/gma500/psb_drv.c b/trunk/drivers/gpu/drm/gma500/psb_drv.c index 7473d3b8fffe..d5a6eab8227e 100644 --- a/trunk/drivers/gpu/drm/gma500/psb_drv.c +++ b/trunk/drivers/gpu/drm/gma500/psb_drv.c @@ -79,14 +79,6 @@ static DEFINE_PCI_DEVICE_TABLE(pciidlist) = { { 0x8086, 0x0be5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, { 0x8086, 0x0be6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, { 0x8086, 0x0be7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0be8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0be9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0bea, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0beb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0bec, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0bed, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0bee, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, - { 0x8086, 0x0bef, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &cdv_chip_ops}, #endif { 0, } }; @@ -180,6 +172,24 @@ static int psb_do_init(struct drm_device *dev) dev_priv->gatt_free_offset = pg->mmu_gatt_start + (stolen_gtt << PAGE_SHIFT) * 1024; + if (1 || drm_debug) { + uint32_t core_id = PSB_RSGX32(PSB_CR_CORE_ID); + uint32_t core_rev = PSB_RSGX32(PSB_CR_CORE_REVISION); + DRM_INFO("SGX core id = 0x%08x\n", core_id); + DRM_INFO("SGX core rev major = 0x%02x, minor = 0x%02x\n", + (core_rev & _PSB_CC_REVISION_MAJOR_MASK) >> + _PSB_CC_REVISION_MAJOR_SHIFT, + (core_rev & _PSB_CC_REVISION_MINOR_MASK) >> + _PSB_CC_REVISION_MINOR_SHIFT); + DRM_INFO + ("SGX core rev maintenance = 0x%02x, designer = 0x%02x\n", + (core_rev & _PSB_CC_REVISION_MAINTENANCE_MASK) >> + _PSB_CC_REVISION_MAINTENANCE_SHIFT, + (core_rev & _PSB_CC_REVISION_DESIGNER_MASK) >> + _PSB_CC_REVISION_DESIGNER_SHIFT); + } + + spin_lock_init(&dev_priv->irqmask_lock); spin_lock_init(&dev_priv->lock_2d); @@ -205,11 +215,12 @@ static int psb_driver_unload(struct drm_device *dev) /* Kill vblank etc here */ gma_backlight_exit(dev); + psb_modeset_cleanup(dev); if (dev_priv) { - psb_intel_opregion_fini(dev); psb_lid_timer_takedown(dev_priv); + gma_intel_opregion_exit(dev); if (dev_priv->ops->chip_teardown) dev_priv->ops->chip_teardown(dev); @@ -280,6 +291,11 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) pci_set_master(dev->pdev); + if (!IS_PSB(dev)) { + if (pci_enable_msi(dev->pdev)) + dev_warn(dev->dev, "Enabling MSI failed!\n"); + } + dev_priv->num_pipe = dev_priv->ops->pipes; resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE); @@ -294,8 +310,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) if (!dev_priv->sgx_reg) goto out_err; - psb_intel_opregion_setup(dev); - ret = dev_priv->ops->chip_setup(dev); if (ret) goto out_err; @@ -335,8 +349,9 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE); PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE); +/* igd_opregion_init(&dev_priv->opregion_dev); */ acpi_video_register(); - if (dev_priv->opregion.lid_state) + if (dev_priv->lid_state) psb_lid_timer_init(dev_priv); ret = drm_vblank_init(dev, dev_priv->num_pipe); @@ -356,8 +371,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R); PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - - drm_irq_install(dev); + if (IS_PSB(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) + drm_irq_install(dev); dev->vblank_disable_allowed = 1; diff --git a/trunk/drivers/gpu/drm/gma500/psb_drv.h b/trunk/drivers/gpu/drm/gma500/psb_drv.h index fd1bc8f6bf97..d3528a694206 100644 --- a/trunk/drivers/gpu/drm/gma500/psb_drv.h +++ b/trunk/drivers/gpu/drm/gma500/psb_drv.h @@ -30,7 +30,6 @@ #include "psb_intel_drv.h" #include "gtt.h" #include "power.h" -#include "opregion.h" #include "oaktrail.h" /* Append new drm mode definition here, align with libdrm definition */ @@ -121,7 +120,6 @@ enum { #define PSB_HWSTAM 0x2098 #define PSB_INSTPM 0x20C0 #define PSB_INT_IDENTITY_R 0x20A4 -#define _PSB_IRQ_ASLE (1<<0) #define _MDFLD_PIPEC_EVENT_FLAG (1<<2) #define _MDFLD_PIPEC_VBLANK_FLAG (1<<3) #define _PSB_DPST_PIPEB_FLAG (1<<4) @@ -261,7 +259,7 @@ struct psb_intel_opregion { struct opregion_swsci *swsci; struct opregion_asle *asle; void *vbt; - u32 __iomem *lid_state; + int enabled; }; struct sdvo_device_mapping { @@ -280,73 +278,51 @@ struct intel_gmbus { u32 reg0; }; -/* - * Register offset maps - */ - -struct psb_offset { - u32 fp0; - u32 fp1; - u32 cntr; - u32 conf; - u32 src; - u32 dpll; - u32 dpll_md; - u32 htotal; - u32 hblank; - u32 hsync; - u32 vtotal; - u32 vblank; - u32 vsync; - u32 stride; - u32 size; - u32 pos; - u32 surf; - u32 addr; - u32 base; - u32 status; - u32 linoff; - u32 tileoff; - u32 palette; -}; - /* * Register save state. This is used to hold the context when the * device is powered off. In the case of Oaktrail this can (but does not * yet) include screen blank. Operations occuring during the save * update the register cache instead. */ - -/* - * Common status for pipes. - */ -struct psb_pipe { - u32 fp0; - u32 fp1; - u32 cntr; - u32 conf; - u32 src; - u32 dpll; - u32 dpll_md; - u32 htotal; - u32 hblank; - u32 hsync; - u32 vtotal; - u32 vblank; - u32 vsync; - u32 stride; - u32 size; - u32 pos; - u32 base; - u32 surf; - u32 addr; - u32 status; - u32 linoff; - u32 tileoff; - u32 palette[256]; -}; - struct psb_state { + uint32_t saveDSPACNTR; + uint32_t saveDSPBCNTR; + uint32_t savePIPEACONF; + uint32_t savePIPEBCONF; + uint32_t savePIPEASRC; + uint32_t savePIPEBSRC; + uint32_t saveFPA0; + uint32_t saveFPA1; + uint32_t saveDPLL_A; + uint32_t saveDPLL_A_MD; + uint32_t saveHTOTAL_A; + uint32_t saveHBLANK_A; + uint32_t saveHSYNC_A; + uint32_t saveVTOTAL_A; + uint32_t saveVBLANK_A; + uint32_t saveVSYNC_A; + uint32_t saveDSPASTRIDE; + uint32_t saveDSPASIZE; + uint32_t saveDSPAPOS; + uint32_t saveDSPABASE; + uint32_t saveDSPASURF; + uint32_t saveDSPASTATUS; + uint32_t saveFPB0; + uint32_t saveFPB1; + uint32_t saveDPLL_B; + uint32_t saveDPLL_B_MD; + uint32_t saveHTOTAL_B; + uint32_t saveHBLANK_B; + uint32_t saveHSYNC_B; + uint32_t saveVTOTAL_B; + uint32_t saveVBLANK_B; + uint32_t saveVSYNC_B; + uint32_t saveDSPBSTRIDE; + uint32_t saveDSPBSIZE; + uint32_t saveDSPBPOS; + uint32_t saveDSPBBASE; + uint32_t saveDSPBSURF; + uint32_t saveDSPBSTATUS; uint32_t saveVCLK_DIVISOR_VGA0; uint32_t saveVCLK_DIVISOR_VGA1; uint32_t saveVCLK_POST_DIV; @@ -361,8 +337,14 @@ struct psb_state { uint32_t savePP_CONTROL; uint32_t savePP_CYCLE; uint32_t savePFIT_CONTROL; + uint32_t savePaletteA[256]; + uint32_t savePaletteB[256]; uint32_t saveCLOCKGATING; uint32_t saveDSPARB; + uint32_t saveDSPATILEOFF; + uint32_t saveDSPBTILEOFF; + uint32_t saveDSPAADDR; + uint32_t saveDSPBADDR; uint32_t savePFIT_AUTO_RATIOS; uint32_t savePFIT_PGM_RATIOS; uint32_t savePP_ON_DELAYS; @@ -370,6 +352,8 @@ struct psb_state { uint32_t savePP_DIVISOR; uint32_t saveBCLRPAT_A; uint32_t saveBCLRPAT_B; + uint32_t saveDSPALINOFF; + uint32_t saveDSPBLINOFF; uint32_t savePERF_MODE; uint32_t saveDSPFW1; uint32_t saveDSPFW2; @@ -384,6 +368,8 @@ struct psb_state { uint32_t saveDSPBCURSOR_BASE; uint32_t saveDSPACURSOR_POS; uint32_t saveDSPBCURSOR_POS; + uint32_t save_palette_a[256]; + uint32_t save_palette_b[256]; uint32_t saveOV_OVADD; uint32_t saveOV_OGAMC0; uint32_t saveOV_OGAMC1; @@ -406,7 +392,64 @@ struct psb_state { }; struct medfield_state { + uint32_t saveDPLL_A; + uint32_t saveFPA0; + uint32_t savePIPEACONF; + uint32_t saveHTOTAL_A; + uint32_t saveHBLANK_A; + uint32_t saveHSYNC_A; + uint32_t saveVTOTAL_A; + uint32_t saveVBLANK_A; + uint32_t saveVSYNC_A; + uint32_t savePIPEASRC; + uint32_t saveDSPASTRIDE; + uint32_t saveDSPALINOFF; + uint32_t saveDSPATILEOFF; + uint32_t saveDSPASIZE; + uint32_t saveDSPAPOS; + uint32_t saveDSPASURF; + uint32_t saveDSPACNTR; + uint32_t saveDSPASTATUS; + uint32_t save_palette_a[256]; uint32_t saveMIPI; + + uint32_t saveDPLL_B; + uint32_t saveFPB0; + uint32_t savePIPEBCONF; + uint32_t saveHTOTAL_B; + uint32_t saveHBLANK_B; + uint32_t saveHSYNC_B; + uint32_t saveVTOTAL_B; + uint32_t saveVBLANK_B; + uint32_t saveVSYNC_B; + uint32_t savePIPEBSRC; + uint32_t saveDSPBSTRIDE; + uint32_t saveDSPBLINOFF; + uint32_t saveDSPBTILEOFF; + uint32_t saveDSPBSIZE; + uint32_t saveDSPBPOS; + uint32_t saveDSPBSURF; + uint32_t saveDSPBCNTR; + uint32_t saveDSPBSTATUS; + uint32_t save_palette_b[256]; + + uint32_t savePIPECCONF; + uint32_t saveHTOTAL_C; + uint32_t saveHBLANK_C; + uint32_t saveHSYNC_C; + uint32_t saveVTOTAL_C; + uint32_t saveVBLANK_C; + uint32_t saveVSYNC_C; + uint32_t savePIPECSRC; + uint32_t saveDSPCSTRIDE; + uint32_t saveDSPCLINOFF; + uint32_t saveDSPCTILEOFF; + uint32_t saveDSPCSIZE; + uint32_t saveDSPCPOS; + uint32_t saveDSPCSURF; + uint32_t saveDSPCCNTR; + uint32_t saveDSPCSTATUS; + uint32_t save_palette_c[256]; uint32_t saveMIPI_C; uint32_t savePFIT_CONTROL; @@ -435,7 +478,6 @@ struct cdv_state { }; struct psb_save_area { - struct psb_pipe pipe[3]; uint32_t saveBSM; uint32_t saveVBT; union { @@ -454,7 +496,6 @@ struct psb_ops; struct drm_psb_private { struct drm_device *dev; const struct psb_ops *ops; - const struct psb_offset *regmap; struct child_device_config *child_dev; int child_dev_num; @@ -464,9 +505,9 @@ struct drm_psb_private { /* GTT Memory manager */ struct psb_gtt_mm *gtt_mm; struct page *scratch_page; - u32 __iomem *gtt_map; + u32 *gtt_map; uint32_t stolen_base; - u8 __iomem *vram_addr; + void *vram_addr; unsigned long vram_stolen_size; int gtt_initialized; u16 gmch_ctrl; /* Saved GTT setup */ @@ -482,8 +523,8 @@ struct drm_psb_private { * Register base */ - uint8_t __iomem *sgx_reg; - uint8_t __iomem *vdc_reg; + uint8_t *sgx_reg; + uint8_t *vdc_reg; uint32_t gatt_free_offset; /* @@ -569,7 +610,7 @@ struct drm_psb_private { int rpm_enabled; /* MID specific */ - bool has_gct; + struct oaktrail_vbt vbt_data; struct oaktrail_gct_data gct_data; /* Oaktrail HDMI state */ @@ -597,6 +638,7 @@ struct drm_psb_private { spinlock_t lid_lock; struct timer_list lid_timer; struct psb_intel_opregion opregion; + u32 *lid_state; u32 lid_last_state; /* @@ -764,6 +806,12 @@ psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc); +/* + * intel_opregion.c + */ +extern int gma_intel_opregion_init(struct drm_device *dev); +extern int gma_intel_opregion_exit(struct drm_device *dev); + /* * framebuffer.c */ diff --git a/trunk/drivers/gpu/drm/gma500/psb_intel_display.c b/trunk/drivers/gpu/drm/gma500/psb_intel_display.c index f3a3160aafdc..2616558457c8 100644 --- a/trunk/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/trunk/drivers/gpu/drm/gma500/psb_intel_display.c @@ -337,12 +337,15 @@ static int psb_intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; + /* struct drm_i915_master_private *master_priv; */ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; unsigned long start, offset; + int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE); + int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); + int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; u32 dspcntr; int ret = 0; @@ -364,9 +367,9 @@ static int psb_intel_pipe_set_base(struct drm_crtc *crtc, offset = y * crtc->fb->pitches[0] + x * (crtc->fb->bits_per_pixel / 8); - REG_WRITE(map->stride, crtc->fb->pitches[0]); + REG_WRITE(dspstride, crtc->fb->pitches[0]); - dspcntr = REG_READ(map->cntr); + dspcntr = REG_READ(dspcntr_reg); dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; switch (crtc->fb->bits_per_pixel) { @@ -389,10 +392,18 @@ static int psb_intel_pipe_set_base(struct drm_crtc *crtc, psb_gtt_unpin(psbfb->gtt); goto psb_intel_pipe_set_base_exit; } - REG_WRITE(map->cntr, dspcntr); + REG_WRITE(dspcntr_reg, dspcntr); + - REG_WRITE(map->base, start + offset); - REG_READ(map->base); + if (0 /* FIXMEAC - check what PSB needs */) { + REG_WRITE(dspbase, offset); + REG_READ(dspbase); + REG_WRITE(dspsurf, start); + REG_READ(dspsurf); + } else { + REG_WRITE(dspbase, start + offset); + REG_READ(dspbase); + } psb_intel_pipe_cleaner: /* If there was a previous display we can now unpin it */ @@ -413,10 +424,14 @@ static int psb_intel_pipe_set_base(struct drm_crtc *crtc, static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; + /* struct drm_i915_master_private *master_priv; */ + /* struct drm_i915_private *dev_priv = dev->dev_private; */ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; + int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; u32 temp; /* XXX: When our outputs are all unaware of DPMS modes other than off @@ -427,34 +442,34 @@ static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode) case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: /* Enable the DPLL */ - temp = REG_READ(map->dpll); + temp = REG_READ(dpll_reg); if ((temp & DPLL_VCO_ENABLE) == 0) { - REG_WRITE(map->dpll, temp); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); - REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); - REG_WRITE(map->dpll, temp | DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); } /* Enable the pipe */ - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); if ((temp & PIPEACONF_ENABLE) == 0) - REG_WRITE(map->conf, temp | PIPEACONF_ENABLE); + REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); /* Enable the plane */ - temp = REG_READ(map->cntr); + temp = REG_READ(dspcntr_reg); if ((temp & DISPLAY_PLANE_ENABLE) == 0) { - REG_WRITE(map->cntr, + REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE); /* Flush the plane changes */ - REG_WRITE(map->base, REG_READ(map->base)); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); } psb_intel_crtc_load_lut(crtc); @@ -472,29 +487,29 @@ static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode) REG_WRITE(VGACNTRL, VGA_DISP_DISABLE); /* Disable display plane */ - temp = REG_READ(map->cntr); + temp = REG_READ(dspcntr_reg); if ((temp & DISPLAY_PLANE_ENABLE) != 0) { - REG_WRITE(map->cntr, + REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); /* Flush the plane changes */ - REG_WRITE(map->base, REG_READ(map->base)); - REG_READ(map->base); + REG_WRITE(dspbase_reg, REG_READ(dspbase_reg)); + REG_READ(dspbase_reg); } /* Next, disable display pipes */ - temp = REG_READ(map->conf); + temp = REG_READ(pipeconf_reg); if ((temp & PIPEACONF_ENABLE) != 0) { - REG_WRITE(map->conf, temp & ~PIPEACONF_ENABLE); - REG_READ(map->conf); + REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); + REG_READ(pipeconf_reg); } /* Wait for vblank for the disable to take effect. */ psb_intel_wait_for_vblank(dev); - temp = REG_READ(map->dpll); + temp = REG_READ(dpll_reg); if ((temp & DPLL_VCO_ENABLE) != 0) { - REG_WRITE(map->dpll, temp & ~DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); + REG_READ(dpll_reg); } /* Wait for the clocks to turn off. */ @@ -574,11 +589,22 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; + int fp_reg = (pipe == 0) ? FPA0 : FPB0; + int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; + int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; + int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; + int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B; + int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B; + int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; + int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; + int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; + int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; + int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; + int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; + int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; int refclk; struct psb_intel_clock_t clock; u32 dpll = 0, fp = 0, dspcntr, pipeconf; @@ -664,7 +690,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, dpll |= PLL_REF_INPUT_DREFCLK; /* setup pipeconf */ - pipeconf = REG_READ(map->conf); + pipeconf = REG_READ(pipeconf_reg); /* Set up the display plane register */ dspcntr = DISPPLANE_GAMMA_ENABLE; @@ -686,9 +712,9 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, drm_mode_debug_printmodeline(mode); if (dpll & DPLL_VCO_ENABLE) { - REG_WRITE(map->fp0, fp); - REG_WRITE(map->dpll, dpll & ~DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_WRITE(fp_reg, fp); + REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); + REG_READ(dpll_reg); udelay(150); } @@ -721,45 +747,45 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, REG_READ(LVDS); } - REG_WRITE(map->fp0, fp); - REG_WRITE(map->dpll, dpll); - REG_READ(map->dpll); + REG_WRITE(fp_reg, fp); + REG_WRITE(dpll_reg, dpll); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); /* write it again -- the BIOS does, after all */ - REG_WRITE(map->dpll, dpll); + REG_WRITE(dpll_reg, dpll); - REG_READ(map->dpll); + REG_READ(dpll_reg); /* Wait for the clocks to stabilize. */ udelay(150); - REG_WRITE(map->htotal, (adjusted_mode->crtc_hdisplay - 1) | + REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16)); - REG_WRITE(map->hblank, (adjusted_mode->crtc_hblank_start - 1) | + REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16)); - REG_WRITE(map->hsync, (adjusted_mode->crtc_hsync_start - 1) | + REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16)); - REG_WRITE(map->vtotal, (adjusted_mode->crtc_vdisplay - 1) | + REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16)); - REG_WRITE(map->vblank, (adjusted_mode->crtc_vblank_start - 1) | + REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16)); - REG_WRITE(map->vsync, (adjusted_mode->crtc_vsync_start - 1) | + REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16)); /* pipesrc and dspsize control the size that is scaled from, * which should always be the user's requested size. */ - REG_WRITE(map->size, + REG_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1)); - REG_WRITE(map->pos, 0); - REG_WRITE(map->src, + REG_WRITE(dsppos_reg, 0); + REG_WRITE(pipesrc_reg, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - REG_WRITE(map->conf, pipeconf); - REG_READ(map->conf); + REG_WRITE(pipeconf_reg, pipeconf); + REG_READ(pipeconf_reg); psb_intel_wait_for_vblank(dev); - REG_WRITE(map->cntr, dspcntr); + REG_WRITE(dspcntr_reg, dspcntr); /* Flush the plane changes */ crtc_funcs->mode_set_base(crtc, x, y, old_fb); @@ -773,10 +799,10 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, void psb_intel_crtc_load_lut(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; + struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - const struct psb_offset *map = &dev_priv->regmap[psb_intel_crtc->pipe]; - int palreg = map->palette; + int palreg = PALETTE_A; int i; /* The clocks have to be on to load the palette. */ @@ -785,7 +811,12 @@ void psb_intel_crtc_load_lut(struct drm_crtc *crtc) switch (psb_intel_crtc->pipe) { case 0: + break; case 1: + palreg = PALETTE_B; + break; + case 2: + palreg = PALETTE_C; break; default: dev_err(dev->dev, "Illegal Pipe Number.\n"); @@ -805,7 +836,7 @@ void psb_intel_crtc_load_lut(struct drm_crtc *crtc) gma_power_end(dev); } else { for (i = 0; i < 256; i++) { - dev_priv->regs.pipe[0].palette[i] = + dev_priv->regs.psb.save_palette_a[i] = ((psb_intel_crtc->lut_r[i] + psb_intel_crtc->lut_adj[i]) << 16) | ((psb_intel_crtc->lut_g[i] + @@ -823,10 +854,11 @@ void psb_intel_crtc_load_lut(struct drm_crtc *crtc) static void psb_intel_crtc_save(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; + /* struct drm_psb_private *dev_priv = + (struct drm_psb_private *)dev->dev_private; */ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; - const struct psb_offset *map = &dev_priv->regmap[psb_intel_crtc->pipe]; + int pipeA = (psb_intel_crtc->pipe == 0); uint32_t paletteReg; int i; @@ -835,27 +867,27 @@ static void psb_intel_crtc_save(struct drm_crtc *crtc) return; } - crtc_state->saveDSPCNTR = REG_READ(map->cntr); - crtc_state->savePIPECONF = REG_READ(map->conf); - crtc_state->savePIPESRC = REG_READ(map->src); - crtc_state->saveFP0 = REG_READ(map->fp0); - crtc_state->saveFP1 = REG_READ(map->fp1); - crtc_state->saveDPLL = REG_READ(map->dpll); - crtc_state->saveHTOTAL = REG_READ(map->htotal); - crtc_state->saveHBLANK = REG_READ(map->hblank); - crtc_state->saveHSYNC = REG_READ(map->hsync); - crtc_state->saveVTOTAL = REG_READ(map->vtotal); - crtc_state->saveVBLANK = REG_READ(map->vblank); - crtc_state->saveVSYNC = REG_READ(map->vsync); - crtc_state->saveDSPSTRIDE = REG_READ(map->stride); + crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR); + crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF); + crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC); + crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0); + crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1); + crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B); + crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B); + crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B); + crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B); + crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B); + crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B); + crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B); + crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE); /*NOTE: DSPSIZE DSPPOS only for psb*/ - crtc_state->saveDSPSIZE = REG_READ(map->size); - crtc_state->saveDSPPOS = REG_READ(map->pos); + crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE); + crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS); - crtc_state->saveDSPBASE = REG_READ(map->base); + crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE); - paletteReg = map->palette; + paletteReg = pipeA ? PALETTE_A : PALETTE_B; for (i = 0; i < 256; ++i) crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2)); } @@ -866,10 +898,12 @@ static void psb_intel_crtc_save(struct drm_crtc *crtc) static void psb_intel_crtc_restore(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; + /* struct drm_psb_private * dev_priv = + (struct drm_psb_private *)dev->dev_private; */ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state; - const struct psb_offset *map = &dev_priv->regmap[psb_intel_crtc->pipe]; + /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */ + int pipeA = (psb_intel_crtc->pipe == 0); uint32_t paletteReg; int i; @@ -879,45 +913,45 @@ static void psb_intel_crtc_restore(struct drm_crtc *crtc) } if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) { - REG_WRITE(map->dpll, + REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL & ~DPLL_VCO_ENABLE); - REG_READ(map->dpll); + REG_READ(pipeA ? DPLL_A : DPLL_B); udelay(150); } - REG_WRITE(map->fp0, crtc_state->saveFP0); - REG_READ(map->fp0); + REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0); + REG_READ(pipeA ? FPA0 : FPB0); - REG_WRITE(map->fp1, crtc_state->saveFP1); - REG_READ(map->fp1); + REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1); + REG_READ(pipeA ? FPA1 : FPB1); - REG_WRITE(map->dpll, crtc_state->saveDPLL); - REG_READ(map->dpll); + REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL); + REG_READ(pipeA ? DPLL_A : DPLL_B); udelay(150); - REG_WRITE(map->htotal, crtc_state->saveHTOTAL); - REG_WRITE(map->hblank, crtc_state->saveHBLANK); - REG_WRITE(map->hsync, crtc_state->saveHSYNC); - REG_WRITE(map->vtotal, crtc_state->saveVTOTAL); - REG_WRITE(map->vblank, crtc_state->saveVBLANK); - REG_WRITE(map->vsync, crtc_state->saveVSYNC); - REG_WRITE(map->stride, crtc_state->saveDSPSTRIDE); + REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL); + REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK); + REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC); + REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL); + REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK); + REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC); + REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE); - REG_WRITE(map->size, crtc_state->saveDSPSIZE); - REG_WRITE(map->pos, crtc_state->saveDSPPOS); + REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE); + REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS); - REG_WRITE(map->src, crtc_state->savePIPESRC); - REG_WRITE(map->base, crtc_state->saveDSPBASE); - REG_WRITE(map->conf, crtc_state->savePIPECONF); + REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC); + REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); + REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF); psb_intel_wait_for_vblank(dev); - REG_WRITE(map->cntr, crtc_state->saveDSPCNTR); - REG_WRITE(map->base, crtc_state->saveDSPBASE); + REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR); + REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE); psb_intel_wait_for_vblank(dev); - paletteReg = map->palette; + paletteReg = pipeA ? PALETTE_A : PALETTE_B; for (i = 0; i < 256; ++i) REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]); } @@ -1081,30 +1115,34 @@ static int psb_intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) { struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); - struct drm_psb_private *dev_priv = dev->dev_private; int pipe = psb_intel_crtc->pipe; - const struct psb_offset *map = &dev_priv->regmap[pipe]; u32 dpll; u32 fp; struct psb_intel_clock_t clock; bool is_lvds; - struct psb_pipe *p = &dev_priv->regs.pipe[pipe]; + struct drm_psb_private *dev_priv = dev->dev_private; if (gma_power_begin(dev, false)) { - dpll = REG_READ(map->dpll); + dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B); if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = REG_READ(map->fp0); + fp = REG_READ((pipe == 0) ? FPA0 : FPB0); else - fp = REG_READ(map->fp1); + fp = REG_READ((pipe == 0) ? FPA1 : FPB1); is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN); gma_power_end(dev); } else { - dpll = p->dpll; + dpll = (pipe == 0) ? + dev_priv->regs.psb.saveDPLL_A : + dev_priv->regs.psb.saveDPLL_B; if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = p->fp0; + fp = (pipe == 0) ? + dev_priv->regs.psb.saveFPA0 : + dev_priv->regs.psb.saveFPB0; else - fp = p->fp1; + fp = (pipe == 0) ? + dev_priv->regs.psb.saveFPA1 : + dev_priv->regs.psb.saveFPB1; is_lvds = (pipe == 1) && (dev_priv->regs.psb.saveLVDS & LVDS_PORT_EN); @@ -1164,20 +1202,26 @@ struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev, int vtot; int vsync; struct drm_psb_private *dev_priv = dev->dev_private; - struct psb_pipe *p = &dev_priv->regs.pipe[pipe]; - const struct psb_offset *map = &dev_priv->regmap[pipe]; if (gma_power_begin(dev, false)) { - htot = REG_READ(map->htotal); - hsync = REG_READ(map->hsync); - vtot = REG_READ(map->vtotal); - vsync = REG_READ(map->vsync); + htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B); + hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B); + vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B); + vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B); gma_power_end(dev); } else { - htot = p->htotal; - hsync = p->hsync; - vtot = p->vtotal; - vsync = p->vsync; + htot = (pipe == 0) ? + dev_priv->regs.psb.saveHTOTAL_A : + dev_priv->regs.psb.saveHTOTAL_B; + hsync = (pipe == 0) ? + dev_priv->regs.psb.saveHSYNC_A : + dev_priv->regs.psb.saveHSYNC_B; + vtot = (pipe == 0) ? + dev_priv->regs.psb.saveVTOTAL_A : + dev_priv->regs.psb.saveVTOTAL_B; + vsync = (pipe == 0) ? + dev_priv->regs.psb.saveVSYNC_A : + dev_priv->regs.psb.saveVSYNC_B; } mode = kzalloc(sizeof(*mode), GFP_KERNEL); diff --git a/trunk/drivers/gpu/drm/gma500/psb_intel_reg.h b/trunk/drivers/gpu/drm/gma500/psb_intel_reg.h index 8e8c8efb0a89..519a9cd9ffbc 100644 --- a/trunk/drivers/gpu/drm/gma500/psb_intel_reg.h +++ b/trunk/drivers/gpu/drm/gma500/psb_intel_reg.h @@ -507,7 +507,6 @@ #define PIPE_VBLANK_INTERRUPT_ENABLE (1UL << 17) #define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL << 18) #define PIPE_TE_ENABLE (1UL << 22) -#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL << 22) #define PIPE_DPST_EVENT_ENABLE (1UL << 23) #define PIPE_VSYNC_ENABL (1UL << 25) #define PIPE_HDMI_AUDIO_UNDERRUN (1UL << 26) diff --git a/trunk/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/trunk/drivers/gpu/drm/gma500/psb_intel_sdvo.c index d39b15be7649..958b4e2d4aed 100644 --- a/trunk/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/trunk/drivers/gpu/drm/gma500/psb_intel_sdvo.c @@ -2038,7 +2038,8 @@ psb_intel_sdvo_add_hdmi_properties(struct psb_intel_sdvo_connector *connector) struct drm_device *dev = connector->base.base.dev; intel_attach_force_audio_property(&connector->base.base); - intel_attach_broadcast_rgb_property(&connector->base.base); + if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) + intel_attach_broadcast_rgb_property(&connector->base.base); */ } diff --git a/trunk/drivers/gpu/drm/gma500/psb_irq.c b/trunk/drivers/gpu/drm/gma500/psb_irq.c index 8652cdf3f03f..2fcdffdc9063 100644 --- a/trunk/drivers/gpu/drm/gma500/psb_irq.c +++ b/trunk/drivers/gpu/drm/gma500/psb_irq.c @@ -190,9 +190,6 @@ static void mid_pipe_event_handler(struct drm_device *dev, int pipe) */ static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) { - if (vdc_stat & _PSB_IRQ_ASLE) - psb_intel_opregion_asle_intr(dev); - if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG) mid_pipe_event_handler(dev, 0); @@ -286,7 +283,6 @@ void psb_irq_preinstall(struct drm_device *dev) /* Revisit this area - want per device masks ? */ if (dev_priv->ops->hotplug) dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC; - dev_priv->vdc_irq_mask |= _PSB_IRQ_ASLE; /* This register is safe even if display island is off */ PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); @@ -426,7 +422,7 @@ void psb_irq_turn_off_dpst(struct drm_device *dev) psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); - PSB_WVDC32(pwm_reg & ~PWM_PHASEIN_INT_ENABLE, + PSB_WVDC32(pwm_reg & !(PWM_PHASEIN_INT_ENABLE), PWM_CONTROL_LOGIC); pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC); diff --git a/trunk/drivers/gpu/drm/gma500/psb_lid.c b/trunk/drivers/gpu/drm/gma500/psb_lid.c index 7ff8bb2bdc23..b867aabe6bf3 100644 --- a/trunk/drivers/gpu/drm/gma500/psb_lid.c +++ b/trunk/drivers/gpu/drm/gma500/psb_lid.c @@ -29,7 +29,7 @@ static void psb_lid_timer_func(unsigned long data) struct drm_device *dev = (struct drm_device *)dev_priv->dev; struct timer_list *lid_timer = &dev_priv->lid_timer; unsigned long irq_flags; - u32 __iomem *lid_state = dev_priv->opregion.lid_state; + u32 *lid_state = dev_priv->lid_state; u32 pp_status; if (readl(lid_state) == dev_priv->lid_last_state) diff --git a/trunk/drivers/gpu/drm/i810/i810_dma.c b/trunk/drivers/gpu/drm/i810/i810_dma.c index f920fb5e42b6..2c8a60c3b98e 100644 --- a/trunk/drivers/gpu/drm/i810/i810_dma.c +++ b/trunk/drivers/gpu/drm/i810/i810_dma.c @@ -129,7 +129,6 @@ static int i810_map_buffer(struct drm_buf *buf, struct drm_file *file_priv) if (buf_priv->currently_mapped == I810_BUF_MAPPED) return -EINVAL; - /* This is all entirely broken */ down_write(¤t->mm->mmap_sem); old_fops = file_priv->filp->f_op; file_priv->filp->f_op = &i810_buffer_fops; @@ -158,8 +157,11 @@ static int i810_unmap_buffer(struct drm_buf *buf) if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EINVAL; - retcode = vm_munmap((unsigned long)buf_priv->virtual, + down_write(¤t->mm->mmap_sem); + retcode = do_munmap(current->mm, + (unsigned long)buf_priv->virtual, (size_t) buf->total); + up_write(¤t->mm->mmap_sem); buf_priv->currently_mapped = I810_BUF_UNMAPPED; buf_priv->virtual = NULL; diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index a8db38617f4a..35462df7cefd 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -1274,9 +1274,6 @@ static int i915_emon_status(struct seq_file *m, void *unused) unsigned long temp, chipset, gfx; int ret; - if (!IS_GEN5(dev)) - return -ENODEV; - ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 068958cdd555..a813f652fa1f 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1706,9 +1706,6 @@ void i915_update_gfx_val(struct drm_i915_private *dev_priv) unsigned long diffms; u32 count; - if (dev_priv->info->gen != 5) - return; - getrawmonotonic(&now); diff1 = timespec_sub(now, dev_priv->last_time2); @@ -2151,14 +2148,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) setup_timer(&dev_priv->hangcheck_timer, i915_hangcheck_elapsed, (unsigned long) dev); - if (IS_GEN5(dev)) { - spin_lock(&mchdev_lock); - i915_mch_dev = dev_priv; - dev_priv->mchdev_lock = &mchdev_lock; - spin_unlock(&mchdev_lock); + spin_lock(&mchdev_lock); + i915_mch_dev = dev_priv; + dev_priv->mchdev_lock = &mchdev_lock; + spin_unlock(&mchdev_lock); - ips_ping_for_i915_load(); - } + ips_ping_for_i915_load(); return 0; diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index dd87937e921f..7bc4a40132ad 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -1026,9 +1026,11 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, if (obj == NULL) return -ENOENT; - addr = vm_mmap(obj->filp, 0, args->size, + down_write(¤t->mm->mmap_sem); + addr = do_mmap(obj->filp, 0, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, args->offset); + up_write(¤t->mm->mmap_sem); drm_gem_object_unreference_unlocked(obj); if (IS_ERR((void *)addr)) return addr; diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c index c77bfa9ad340..68ec0130a626 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1116,11 +1116,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, return -EINVAL; } - if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) { - DRM_DEBUG("execbuf with %u cliprects\n", - args->num_cliprects); - return -EINVAL; - } cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), GFP_KERNEL); if (cliprects == NULL) { @@ -1392,8 +1387,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, struct drm_i915_gem_exec_object2 *exec2_list = NULL; int ret; - if (args->buffer_count < 1 || - args->buffer_count > UINT_MAX / sizeof(*exec2_list)) { + if (args->buffer_count < 1) { DRM_DEBUG("execbuf2 with %d buffers\n", args->buffer_count); return -EINVAL; } diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index 417ca99e697d..0976137ab79a 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -449,8 +449,8 @@ intel_crt_detect(struct drm_connector *connector, bool force) { struct drm_device *dev = connector->dev; struct intel_crt *crt = intel_attached_crt(connector); + struct drm_crtc *crtc; enum drm_connector_status status; - struct intel_load_detect_pipe tmp; if (I915_HAS_HOTPLUG(dev)) { if (intel_crt_detect_hotplug(connector)) { @@ -469,16 +469,23 @@ intel_crt_detect(struct drm_connector *connector, bool force) return connector->status; /* for pre-945g platforms use load detect */ - if (intel_get_load_detect_pipe(&crt->base, connector, NULL, - &tmp)) { - if (intel_crt_detect_ddc(connector)) - status = connector_status_connected; - else - status = intel_crt_load_detect(crt); - intel_release_load_detect_pipe(&crt->base, connector, - &tmp); - } else - status = connector_status_unknown; + crtc = crt->base.base.crtc; + if (crtc && crtc->enabled) { + status = intel_crt_load_detect(crt); + } else { + struct intel_load_detect_pipe tmp; + + if (intel_get_load_detect_pipe(&crt->base, connector, NULL, + &tmp)) { + if (intel_crt_detect_ddc(connector)) + status = connector_status_connected; + else + status = intel_crt_load_detect(crt); + intel_release_load_detect_pipe(&crt->base, connector, + &tmp); + } else + status = connector_status_unknown; + } return status; } diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 8c239f2d6bcd..4c844c68ec80 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -3078,11 +3078,8 @@ static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, return false; } - /* All interlaced capable intel hw wants timings in frames. Note though - * that intel_lvds_mode_fixup does some funny tricks with the crtc - * timings, so we need to be careful not to clobber these.*/ - if (!(adjusted_mode->private_flags & INTEL_MODE_CRTC_TIMINGS_SET)) - drm_mode_set_crtcinfo(adjusted_mode, 0); + /* All interlaced capable intel hw wants timings in frames. */ + drm_mode_set_crtcinfo(adjusted_mode, 0); return true; } @@ -5388,6 +5385,9 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + int dpll_reg = DPLL(pipe); + int dpll = I915_READ(dpll_reg); if (HAS_PCH_SPLIT(dev)) return; @@ -5400,15 +5400,10 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) * the manual case. */ if (!HAS_PIPE_CXSR(dev) && intel_crtc->lowfreq_avail) { - int pipe = intel_crtc->pipe; - int dpll_reg = DPLL(pipe); - int dpll; - DRM_DEBUG_DRIVER("downclocking LVDS\n"); assert_panel_unlocked(dev_priv, pipe); - dpll = I915_READ(dpll_reg); dpll |= DISPLAY_RATE_SELECT_FPA1; I915_WRITE(dpll_reg, dpll); intel_wait_for_vblank(dev, pipe); @@ -5798,13 +5793,7 @@ static int intel_gen6_queue_flip(struct drm_device *dev, OUT_RING(fb->pitches[0] | obj->tiling_mode); OUT_RING(obj->gtt_offset); - /* Contrary to the suggestions in the documentation, - * "Enable Panel Fitter" does not seem to be required when page - * flipping with a non-native mode, and worse causes a normal - * modeset to fail. - * pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; - */ - pf = 0; + pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE; pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff; OUT_RING(pf | pipesrc); ADVANCE_LP_RING(); diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 44cf32c8bcbf..22c66b7c7e4a 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -688,7 +688,7 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, int lane_count, clock; int max_lane_count = intel_dp_max_lane_count(intel_dp); int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; - int bpp; + int bpp, mode_rate; static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; if (is_edp(intel_dp) && intel_dp->panel_fixed_mode) { @@ -702,24 +702,30 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, mode->clock = intel_dp->panel_fixed_mode->clock; } + DRM_DEBUG_KMS("DP link computation with max lane count %i " + "max bw %02x pixel clock %iKHz\n", + max_lane_count, bws[max_clock], mode->clock); + if (!intel_dp_adjust_dithering(intel_dp, mode, adjusted_mode)) return false; bpp = adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC ? 18 : 24; + mode_rate = intel_dp_link_required(mode->clock, bpp); for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { for (clock = 0; clock <= max_clock; clock++) { int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); - if (intel_dp_link_required(mode->clock, bpp) - <= link_avail) { + if (mode_rate <= link_avail) { intel_dp->link_bw = bws[clock]; intel_dp->lane_count = lane_count; adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); - DRM_DEBUG_KMS("Display port link bw %02x lane " - "count %d clock %d\n", + DRM_DEBUG_KMS("DP link bw %02x lane " + "count %d clock %d bpp %d\n", intel_dp->link_bw, intel_dp->lane_count, - adjusted_mode->clock); + adjusted_mode->clock, bpp); + DRM_DEBUG_KMS("DP link bw required %i available %i\n", + mode_rate, link_avail); return true; } } diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 7a7cae77f0ca..c5bf8bebf0b0 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -117,10 +117,6 @@ #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) #define INTEL_MODE_DP_FORCE_6BPC (0x10) -/* This flag must be set by the encoder's mode_fixup if it changes the crtc - * timings in the mode to prevent the crtc fixup from overwriting them. - * Currently only lvds needs that. */ -#define INTEL_MODE_CRTC_TIMINGS_SET (0x20) static inline void intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, diff --git a/trunk/drivers/gpu/drm/i915/intel_fb.c b/trunk/drivers/gpu/drm/i915/intel_fb.c index bf8690720a0c..71ef2896be96 100644 --- a/trunk/drivers/gpu/drm/i915/intel_fb.c +++ b/trunk/drivers/gpu/drm/i915/intel_fb.c @@ -279,8 +279,6 @@ void intel_fb_restore_mode(struct drm_device *dev) struct drm_mode_config *config = &dev->mode_config; struct drm_plane *plane; - mutex_lock(&dev->mode_config.mutex); - ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); if (ret) DRM_DEBUG("failed to restore crtc mode\n"); @@ -288,6 +286,4 @@ void intel_fb_restore_mode(struct drm_device *dev) /* Be sure to shut off any planes that may be active */ list_for_each_entry(plane, &config->plane_list, head) plane->funcs->disable_plane(plane); - - mutex_unlock(&dev->mode_config.mutex); } diff --git a/trunk/drivers/gpu/drm/i915/intel_hdmi.c b/trunk/drivers/gpu/drm/i915/intel_hdmi.c index 1eef50d470d2..7de2d3b85b32 100644 --- a/trunk/drivers/gpu/drm/i915/intel_hdmi.c +++ b/trunk/drivers/gpu/drm/i915/intel_hdmi.c @@ -136,7 +136,7 @@ static void i9xx_write_infoframe(struct drm_encoder *encoder, val &= ~VIDEO_DIP_SELECT_MASK; - I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | val | port | flags); + I915_WRITE(VIDEO_DIP_CTL, val | port | flags); for (i = 0; i < len; i += 4) { I915_WRITE(VIDEO_DIP_DATA, *data); diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 9dee82350def..17a4630cec8a 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -187,8 +187,6 @@ centre_horizontally(struct drm_display_mode *mode, mode->crtc_hsync_start = mode->crtc_hblank_start + sync_pos; mode->crtc_hsync_end = mode->crtc_hsync_start + sync_width; - - mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; } static void @@ -210,8 +208,6 @@ centre_vertically(struct drm_display_mode *mode, mode->crtc_vsync_start = mode->crtc_vblank_start + sync_pos; mode->crtc_vsync_end = mode->crtc_vsync_start + sync_width; - - mode->private_flags |= INTEL_MODE_CRTC_TIMINGS_SET; } static inline u32 panel_fitter_scaling(u32 source, u32 target) @@ -287,8 +283,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, for_each_pipe(pipe) I915_WRITE(BCLRPAT(pipe), 0); - drm_mode_set_crtcinfo(adjusted_mode, 0); - switch (intel_lvds->fitting_mode) { case DRM_MODE_SCALE_CENTER: /* @@ -750,7 +744,7 @@ static const struct dmi_system_id intel_no_lvds[] = { .ident = "Hewlett-Packard t5745", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "hp t5745"), + DMI_MATCH(DMI_BOARD_NAME, "hp t5745"), }, }, { @@ -758,7 +752,7 @@ static const struct dmi_system_id intel_no_lvds[] = { .ident = "Hewlett-Packard st5747", .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "hp st5747"), + DMI_MATCH(DMI_BOARD_NAME, "hp st5747"), }, }, { diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c index 2b2e011e9055..cad45ff8251b 100644 --- a/trunk/drivers/gpu/drm/i915/intel_panel.c +++ b/trunk/drivers/gpu/drm/i915/intel_panel.c @@ -50,6 +50,8 @@ intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, adjusted_mode->vtotal = fixed_mode->vtotal; adjusted_mode->clock = fixed_mode->clock; + + drm_mode_set_crtcinfo(adjusted_mode, 0); } /* adjusted_mode has been preset to be the panel's fixed mode */ diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index b5ef7c145ee5..12d9bc789dfb 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -418,14 +418,6 @@ static int init_render_ring(struct intel_ring_buffer *ring) if (INTEL_INFO(dev)->gen >= 6) { I915_WRITE(INSTPM, INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); - - /* From the Sandybridge PRM, volume 1 part 3, page 24: - * "If this bit is set, STCunit will have LRA as replacement - * policy. [...] This bit must be reset. LRA replacement - * policy is not supported." - */ - I915_WRITE(CACHE_MODE_0, - CM0_STC_EVICT_DISABLE_LRA_SNB << CM0_MASK_SHIFT); } return ret; diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index 3d9dfa57130b..c330efd59a0e 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -745,7 +745,6 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, uint16_t width, height; uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; uint16_t h_sync_offset, v_sync_offset; - int mode_clock; width = mode->crtc_hdisplay; height = mode->crtc_vdisplay; @@ -760,11 +759,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; - mode_clock = mode->clock; - mode_clock /= intel_mode_get_pixel_multiplier(mode) ?: 1; - mode_clock /= 10; - dtd->part1.clock = mode_clock; - + dtd->part1.clock = mode->clock / 10; dtd->part1.h_active = width & 0xff; dtd->part1.h_blank = h_blank_len & 0xff; dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | @@ -1015,7 +1010,7 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder); u32 sdvox; struct intel_sdvo_in_out_map in_out; - struct intel_sdvo_dtd input_dtd, output_dtd; + struct intel_sdvo_dtd input_dtd; int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); int rate; @@ -1040,13 +1035,20 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, intel_sdvo->attached_output)) return; - /* lvds has a special fixed output timing. */ - if (intel_sdvo->is_lvds) - intel_sdvo_get_dtd_from_mode(&output_dtd, - intel_sdvo->sdvo_lvds_fixed_mode); - else - intel_sdvo_get_dtd_from_mode(&output_dtd, mode); - (void) intel_sdvo_set_output_timing(intel_sdvo, &output_dtd); + /* We have tried to get input timing in mode_fixup, and filled into + * adjusted_mode. + */ + if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { + input_dtd = intel_sdvo->input_dtd; + } else { + /* Set the output timing to the screen */ + if (!intel_sdvo_set_target_output(intel_sdvo, + intel_sdvo->attached_output)) + return; + + intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); + (void) intel_sdvo_set_output_timing(intel_sdvo, &input_dtd); + } /* Set the input timing to the screen. Assume always input 0. */ if (!intel_sdvo_set_target_input(intel_sdvo)) @@ -1064,10 +1066,6 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, !intel_sdvo_set_tv_format(intel_sdvo)) return; - /* We have tried to get input timing in mode_fixup, and filled into - * adjusted_mode. - */ - intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); (void) intel_sdvo_set_input_timing(intel_sdvo, &input_dtd); switch (pixel_multiplier) { diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_acpi.c b/trunk/drivers/gpu/drm/nouveau/nouveau_acpi.c index 284bd25d5d21..7814a760c164 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -270,7 +270,7 @@ static bool nouveau_dsm_detect(void) struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name}; struct pci_dev *pdev = NULL; int has_dsm = 0; - int has_optimus = 0; + int has_optimus; int vga_count = 0; bool guid_valid; int retval; diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c index 0be4a815e706..80963d05b54a 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6156,14 +6156,10 @@ dcb_fake_connectors(struct nvbios *bios) /* heuristic: if we ever get a non-zero connector field, assume * that all the indices are valid and we don't need fake them. - * - * and, as usual, a blacklist of boards with bad bios data.. */ - if (!nv_match_device(bios->dev, 0x0392, 0x107d, 0x20a2)) { - for (i = 0; i < dcbt->entries; i++) { - if (dcbt->entry[i].connector) - return; - } + for (i = 0; i < dcbt->entries; i++) { + if (dcbt->entry[i].connector) + return; } /* no useful connector info available, we need to make it up diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_hdmi.c b/trunk/drivers/gpu/drm/nouveau/nouveau_hdmi.c index c3de36384522..59ea1c14eca0 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_hdmi.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_hdmi.c @@ -32,9 +32,7 @@ static bool hdmi_sor(struct drm_encoder *encoder) { struct drm_nouveau_private *dev_priv = encoder->dev->dev_private; - if (dev_priv->chipset < 0xa3 || - dev_priv->chipset == 0xaa || - dev_priv->chipset == 0xac) + if (dev_priv->chipset < 0xa3) return false; return true; } diff --git a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c index da3e7c3abab7..34d591b7d4ef 100644 --- a/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/trunk/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -235,7 +235,6 @@ nouveau_pm_profile_set(struct drm_device *dev, const char *profile) return -EPERM; strncpy(string, profile, sizeof(string)); - string[sizeof(string) - 1] = 0; if ((ptr = strchr(string, '\n'))) *ptr = '\0'; diff --git a/trunk/drivers/gpu/drm/nouveau/nv10_gpio.c b/trunk/drivers/gpu/drm/nouveau/nv10_gpio.c index 9d79180069df..550ad3fcf0af 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv10_gpio.c +++ b/trunk/drivers/gpu/drm/nouveau/nv10_gpio.c @@ -65,7 +65,7 @@ nv10_gpio_drive(struct drm_device *dev, int line, int dir, int out) if (line < 10) { line = (line - 2) * 4; reg = NV_PCRTC_GPIO_EXT; - mask = 0x00000003; + mask = 0x00000003 << ((line - 2) * 4); data = (dir << 1) | out; } else if (line < 14) { diff --git a/trunk/drivers/gpu/drm/nouveau/nv50_sor.c b/trunk/drivers/gpu/drm/nouveau/nv50_sor.c index 274640212475..a7844ab6a50c 100644 --- a/trunk/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/trunk/drivers/gpu/drm/nouveau/nv50_sor.c @@ -42,7 +42,7 @@ nv50_sor_dp_lane_map(struct drm_device *dev, struct dcb_entry *dcb, u8 lane) struct drm_nouveau_private *dev_priv = dev->dev_private; static const u8 nvaf[] = { 24, 16, 8, 0 }; /* thanks, apple.. */ static const u8 nv50[] = { 16, 8, 0, 24 }; - if (dev_priv->chipset == 0xaf) + if (dev_priv->card_type == 0xaf) return nvaf[lane]; return nv50[lane]; } diff --git a/trunk/drivers/gpu/drm/nouveau/nvc0_fb.c b/trunk/drivers/gpu/drm/nouveau/nvc0_fb.c index f704e942372e..5bf55038fd92 100644 --- a/trunk/drivers/gpu/drm/nouveau/nvc0_fb.c +++ b/trunk/drivers/gpu/drm/nouveau/nvc0_fb.c @@ -54,11 +54,6 @@ nvc0_mfb_isr(struct drm_device *dev) nvc0_mfb_subp_isr(dev, unit, subp); units &= ~(1 << unit); } - - /* we do something horribly wrong and upset PMFB a lot, so mask off - * interrupts from it after the first one until it's fixed - */ - nv_mask(dev, 0x000640, 0x02000000, 0x00000000); } static void diff --git a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c index 01d77d1554f4..2fab38f5a08e 100644 --- a/trunk/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/trunk/drivers/gpu/drm/radeon/atombios_crtc.c @@ -575,9 +575,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, if (rdev->family < CHIP_RV770) pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; - /* use frac fb div on APUs */ - if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev)) - pll->flags |= RADEON_PLL_USE_FRAC_FB_DIV; } else { pll->flags |= RADEON_PLL_LEGACY; @@ -957,8 +954,8 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode break; } - if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) || - (radeon_encoder_get_dp_bridge_encoder_id(encoder) != ENCODER_OBJECT_ID_NONE)) { + if (radeon_encoder->active_device & + (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index 7e7ac3d6e76e..eed7acefb492 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -2424,18 +2424,27 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *rin u32 srbm_status; u32 grbm_status; u32 grbm_status_se0, grbm_status_se1; + struct r100_gpu_lockup *lockup = &rdev->config.evergreen.lockup; + int r; srbm_status = RREG32(SRBM_STATUS); grbm_status = RREG32(GRBM_STATUS); grbm_status_se0 = RREG32(GRBM_STATUS_SE0); grbm_status_se1 = RREG32(GRBM_STATUS_SE1); if (!(grbm_status & GUI_ACTIVE)) { - radeon_ring_lockup_update(ring); + r100_gpu_lockup_update(lockup, ring); return false; } /* force CP activities */ - radeon_ring_force_activity(rdev, ring); - return radeon_ring_test_lockup(rdev, ring); + r = radeon_ring_lock(rdev, ring, 2); + if (!r) { + /* PACKET2 NOP */ + radeon_ring_write(ring, 0x80000000); + radeon_ring_write(ring, 0x80000000); + radeon_ring_unlock_commit(rdev, ring); + } + ring->rptr = RREG32(CP_RB_RPTR); + return r100_gpu_cp_is_lockup(rdev, lockup, ring); } static int evergreen_gpu_soft_reset(struct radeon_device *rdev) @@ -3367,9 +3376,12 @@ static int evergreen_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_ring_tests(rdev); - if (r) + r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + if (r) { + DRM_ERROR("radeon: failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; + } r = r600_audio_init(rdev); if (r) { @@ -3550,6 +3562,7 @@ void evergreen_fini(struct radeon_device *rdev) evergreen_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); radeon_gem_fini(rdev); + radeon_semaphore_driver_fini(rdev); radeon_fence_driver_fini(rdev); radeon_agp_fini(rdev); radeon_bo_fini(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/trunk/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 30f04800b38b..222acd2d33df 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -637,6 +637,7 @@ int evergreen_blit_init(struct radeon_device *rdev) if (rdev->r600_blit.shader_obj) goto done; + mutex_init(&rdev->r600_blit.mutex); rdev->r600_blit.state_offset = 0; if (rdev->family < CHIP_CAYMAN) diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c index 4e7dd2b4843d..70089d32b80f 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c @@ -1057,7 +1057,7 @@ static int evergreen_cs_packet_parse_vline(struct radeon_cs_parser *p) uint32_t header, h_idx, reg, wait_reg_mem_info; volatile uint32_t *ib; - ib = p->ib.ptr; + ib = p->ib->ptr; /* parse the WAIT_REG_MEM */ r = evergreen_cs_packet_parse(p, &wait_reg_mem, p->idx); @@ -1215,7 +1215,7 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) if (!(evergreen_reg_safe_bm[i] & m)) return 0; } - ib = p->ib.ptr; + ib = p->ib->ptr; switch (reg) { /* force following reg to 0 in an attempt to disable out buffer * which will need us to better understand how it works to perform @@ -1896,7 +1896,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, u32 idx_value; track = (struct evergreen_cs_track *)p->track; - ib = p->ib.ptr; + ib = p->ib->ptr; idx = pkt->idx + 1; idx_value = radeon_get_ib_value(p, idx); @@ -2610,8 +2610,8 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) } } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); #if 0 - for (r = 0; r < p->ib.length_dw; r++) { - printk(KERN_INFO "%05d 0x%08X\n", r, p->ib.ptr[r]); + for (r = 0; r < p->ib->length_dw; r++) { + printk(KERN_INFO "%05d 0x%08X\n", r, p->ib->ptr[r]); mdelay(1); } #endif diff --git a/trunk/drivers/gpu/drm/radeon/ni.c b/trunk/drivers/gpu/drm/radeon/ni.c index 107b2177e6c5..a48ca53fcd6a 100644 --- a/trunk/drivers/gpu/drm/radeon/ni.c +++ b/trunk/drivers/gpu/drm/radeon/ni.c @@ -1392,6 +1392,35 @@ int cayman_cp_resume(struct radeon_device *rdev) return 0; } +bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) +{ + u32 srbm_status; + u32 grbm_status; + u32 grbm_status_se0, grbm_status_se1; + struct r100_gpu_lockup *lockup = &rdev->config.cayman.lockup; + int r; + + srbm_status = RREG32(SRBM_STATUS); + grbm_status = RREG32(GRBM_STATUS); + grbm_status_se0 = RREG32(GRBM_STATUS_SE0); + grbm_status_se1 = RREG32(GRBM_STATUS_SE1); + if (!(grbm_status & GUI_ACTIVE)) { + r100_gpu_lockup_update(lockup, ring); + return false; + } + /* force CP activities */ + r = radeon_ring_lock(rdev, ring, 2); + if (!r) { + /* PACKET2 NOP */ + radeon_ring_write(ring, 0x80000000); + radeon_ring_write(ring, 0x80000000); + radeon_ring_unlock_commit(rdev, ring); + } + /* XXX deal with CP0,1,2 */ + ring->rptr = RREG32(ring->rptr_reg); + return r100_gpu_cp_is_lockup(rdev, lockup, ring); +} + static int cayman_gpu_soft_reset(struct radeon_device *rdev) { struct evergreen_mc_save save; @@ -1572,9 +1601,12 @@ static int cayman_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_ring_tests(rdev); - if (r) + r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + if (r) { + DRM_ERROR("radeon: failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; + } r = radeon_vm_manager_start(rdev); if (r) @@ -1744,6 +1776,7 @@ void cayman_fini(struct radeon_device *rdev) cayman_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); radeon_gem_fini(rdev); + radeon_semaphore_driver_fini(rdev); radeon_fence_driver_fini(rdev); radeon_bo_fini(rdev); radeon_atombios_fini(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/r100.c b/trunk/drivers/gpu/drm/radeon/r100.c index 0874a6dd411f..cb1141854282 100644 --- a/trunk/drivers/gpu/drm/radeon/r100.c +++ b/trunk/drivers/gpu/drm/radeon/r100.c @@ -139,9 +139,9 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p, } tmp |= tile_flags; - p->ib.ptr[idx] = (value & 0x3fc00000) | tmp; + p->ib->ptr[idx] = (value & 0x3fc00000) | tmp; } else - p->ib.ptr[idx] = (value & 0xffc00000) | tmp; + p->ib->ptr[idx] = (value & 0xffc00000) | tmp; return 0; } @@ -156,7 +156,7 @@ int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, volatile uint32_t *ib; u32 idx_value; - ib = p->ib.ptr; + ib = p->ib->ptr; track = (struct r100_cs_track *)p->track; c = radeon_get_ib_value(p, idx++) & 0x1F; if (c > 16) { @@ -660,7 +660,7 @@ int r100_pci_gart_enable(struct radeon_device *rdev) tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN; WREG32(RADEON_AIC_CNTL, tmp); r100_pci_gart_tlb_flush(rdev); - DRM_INFO("PCI GART of %uM enabled (table at 0x%016llX).\n", + DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", (unsigned)(rdev->mc.gtt_size >> 20), (unsigned long long)rdev->gart.table_addr); rdev->gart.ready = true; @@ -1275,7 +1275,7 @@ void r100_cs_dump_packet(struct radeon_cs_parser *p, unsigned i; unsigned idx; - ib = p->ib.ptr; + ib = p->ib->ptr; idx = pkt->idx; for (i = 0; i <= (pkt->count + 1); i++, idx++) { DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); @@ -1354,7 +1354,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) uint32_t header, h_idx, reg; volatile uint32_t *ib; - ib = p->ib.ptr; + ib = p->ib->ptr; /* parse the wait until */ r = r100_cs_packet_parse(p, &waitreloc, p->idx); @@ -1533,7 +1533,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, u32 tile_flags = 0; u32 idx_value; - ib = p->ib.ptr; + ib = p->ib->ptr; track = (struct r100_cs_track *)p->track; idx_value = radeon_get_ib_value(p, idx); @@ -1889,7 +1889,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p, volatile uint32_t *ib; int r; - ib = p->ib.ptr; + ib = p->ib->ptr; idx = pkt->idx + 1; track = (struct r100_cs_track *)p->track; switch (pkt->opcode) { @@ -2159,18 +2159,79 @@ int r100_mc_wait_for_idle(struct radeon_device *rdev) return -1; } +void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_ring *ring) +{ + lockup->last_cp_rptr = ring->rptr; + lockup->last_jiffies = jiffies; +} + +/** + * r100_gpu_cp_is_lockup() - check if CP is lockup by recording information + * @rdev: radeon device structure + * @lockup: r100_gpu_lockup structure holding CP lockup tracking informations + * @cp: radeon_cp structure holding CP information + * + * We don't need to initialize the lockup tracking information as we will either + * have CP rptr to a different value of jiffies wrap around which will force + * initialization of the lockup tracking informations. + * + * A possible false positivie is if we get call after while and last_cp_rptr == + * the current CP rptr, even if it's unlikely it might happen. To avoid this + * if the elapsed time since last call is bigger than 2 second than we return + * false and update the tracking information. Due to this the caller must call + * r100_gpu_cp_is_lockup several time in less than 2sec for lockup to be reported + * the fencing code should be cautious about that. + * + * Caller should write to the ring to force CP to do something so we don't get + * false positive when CP is just gived nothing to do. + * + **/ +bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_ring *ring) +{ + unsigned long cjiffies, elapsed; + + cjiffies = jiffies; + if (!time_after(cjiffies, lockup->last_jiffies)) { + /* likely a wrap around */ + lockup->last_cp_rptr = ring->rptr; + lockup->last_jiffies = jiffies; + return false; + } + if (ring->rptr != lockup->last_cp_rptr) { + /* CP is still working no lockup */ + lockup->last_cp_rptr = ring->rptr; + lockup->last_jiffies = jiffies; + return false; + } + elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); + if (elapsed >= 10000) { + dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); + return true; + } + /* give a chance to the GPU ... */ + return false; +} + bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) { u32 rbbm_status; + int r; rbbm_status = RREG32(R_000E40_RBBM_STATUS); if (!G_000E40_GUI_ACTIVE(rbbm_status)) { - radeon_ring_lockup_update(ring); + r100_gpu_lockup_update(&rdev->config.r100.lockup, ring); return false; } /* force CP activities */ - radeon_ring_force_activity(rdev, ring); - return radeon_ring_test_lockup(rdev, ring); + r = radeon_ring_lock(rdev, ring, 2); + if (!r) { + /* PACKET2 NOP */ + radeon_ring_write(ring, 0x80000000); + radeon_ring_write(ring, 0x80000000); + radeon_ring_unlock_commit(rdev, ring); + } + ring->rptr = RREG32(ring->rptr_reg); + return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, ring); } void r100_bm_disable(struct radeon_device *rdev) @@ -2239,6 +2300,7 @@ int r100_asic_reset(struct radeon_device *rdev) if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) || G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { dev_err(rdev->dev, "failed to reset GPU\n"); + rdev->gpu_lockup = true; ret = -1; } else dev_info(rdev->dev, "GPU reset succeed\n"); @@ -3684,7 +3746,7 @@ void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) { - struct radeon_ib ib; + struct radeon_ib *ib; uint32_t scratch; uint32_t tmp = 0; unsigned i; @@ -3700,22 +3762,22 @@ int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) if (r) { return r; } - ib.ptr[0] = PACKET0(scratch, 0); - ib.ptr[1] = 0xDEADBEEF; - ib.ptr[2] = PACKET2(0); - ib.ptr[3] = PACKET2(0); - ib.ptr[4] = PACKET2(0); - ib.ptr[5] = PACKET2(0); - ib.ptr[6] = PACKET2(0); - ib.ptr[7] = PACKET2(0); - ib.length_dw = 8; - r = radeon_ib_schedule(rdev, &ib); + ib->ptr[0] = PACKET0(scratch, 0); + ib->ptr[1] = 0xDEADBEEF; + ib->ptr[2] = PACKET2(0); + ib->ptr[3] = PACKET2(0); + ib->ptr[4] = PACKET2(0); + ib->ptr[5] = PACKET2(0); + ib->ptr[6] = PACKET2(0); + ib->ptr[7] = PACKET2(0); + ib->length_dw = 8; + r = radeon_ib_schedule(rdev, ib); if (r) { radeon_scratch_free(rdev, scratch); radeon_ib_free(rdev, &ib); return r; } - r = radeon_fence_wait(ib.fence, false); + r = radeon_fence_wait(ib->fence, false); if (r) { return r; } @@ -3907,9 +3969,12 @@ static int r100_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_ring_tests(rdev); - if (r) + r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + if (r) { + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; + } return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/r200.c b/trunk/drivers/gpu/drm/radeon/r200.c index a26144d01207..a59cc474d537 100644 --- a/trunk/drivers/gpu/drm/radeon/r200.c +++ b/trunk/drivers/gpu/drm/radeon/r200.c @@ -154,7 +154,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, u32 tile_flags = 0; u32 idx_value; - ib = p->ib.ptr; + ib = p->ib->ptr; track = (struct r100_cs_track *)p->track; idx_value = radeon_get_ib_value(p, idx); switch (reg) { diff --git a/trunk/drivers/gpu/drm/radeon/r300.c b/trunk/drivers/gpu/drm/radeon/r300.c index 97722a33e513..fa14383f9ca0 100644 --- a/trunk/drivers/gpu/drm/radeon/r300.c +++ b/trunk/drivers/gpu/drm/radeon/r300.c @@ -377,6 +377,28 @@ void r300_gpu_init(struct radeon_device *rdev) rdev->num_gb_pipes, rdev->num_z_pipes); } +bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) +{ + u32 rbbm_status; + int r; + + rbbm_status = RREG32(R_000E40_RBBM_STATUS); + if (!G_000E40_GUI_ACTIVE(rbbm_status)) { + r100_gpu_lockup_update(&rdev->config.r300.lockup, ring); + return false; + } + /* force CP activities */ + r = radeon_ring_lock(rdev, ring, 2); + if (!r) { + /* PACKET2 NOP */ + radeon_ring_write(ring, 0x80000000); + radeon_ring_write(ring, 0x80000000); + radeon_ring_unlock_commit(rdev, ring); + } + ring->rptr = RREG32(RADEON_CP_RB_RPTR); + return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, ring); +} + int r300_asic_reset(struct radeon_device *rdev) { struct r100_mc_save save; @@ -427,6 +449,7 @@ int r300_asic_reset(struct radeon_device *rdev) /* Check if GPU is idle */ if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { dev_err(rdev->dev, "failed to reset GPU\n"); + rdev->gpu_lockup = true; ret = -1; } else dev_info(rdev->dev, "GPU reset succeed\n"); @@ -604,7 +627,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, int r; u32 idx_value; - ib = p->ib.ptr; + ib = p->ib->ptr; track = (struct r100_cs_track *)p->track; idx_value = radeon_get_ib_value(p, idx); @@ -1146,7 +1169,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p, unsigned idx; int r; - ib = p->ib.ptr; + ib = p->ib->ptr; idx = pkt->idx + 1; track = (struct r100_cs_track *)p->track; switch(pkt->opcode) { @@ -1395,9 +1418,12 @@ static int r300_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_ring_tests(rdev); - if (r) + r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + if (r) { + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; + } return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/r420.c b/trunk/drivers/gpu/drm/radeon/r420.c index 99137be7a300..f3fcaacfea01 100644 --- a/trunk/drivers/gpu/drm/radeon/r420.c +++ b/trunk/drivers/gpu/drm/radeon/r420.c @@ -279,9 +279,12 @@ static int r420_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_ring_tests(rdev); - if (r) + r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + if (r) { + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; + } return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/r520.c b/trunk/drivers/gpu/drm/radeon/r520.c index b5cf8375cd25..ebcc15b03c9f 100644 --- a/trunk/drivers/gpu/drm/radeon/r520.c +++ b/trunk/drivers/gpu/drm/radeon/r520.c @@ -207,10 +207,12 @@ static int r520_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_ring_tests(rdev); - if (r) + r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + if (r) { + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; - + } return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/r600.c b/trunk/drivers/gpu/drm/radeon/r600.c index 4c0d8c96a0ec..222245d0138a 100644 --- a/trunk/drivers/gpu/drm/radeon/r600.c +++ b/trunk/drivers/gpu/drm/radeon/r600.c @@ -1135,7 +1135,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc } if (rdev->flags & RADEON_IS_AGP) { size_bf = mc->gtt_start; - size_af = 0xFFFFFFFF - mc->gtt_end; + size_af = 0xFFFFFFFF - mc->gtt_end + 1; if (size_bf > size_af) { if (mc->mc_vram_size > size_bf) { dev_warn(rdev->dev, "limiting VRAM\n"); @@ -1149,7 +1149,7 @@ static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc mc->real_vram_size = size_af; mc->mc_vram_size = size_af; } - mc->vram_start = mc->gtt_end + 1; + mc->vram_start = mc->gtt_end; } mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", @@ -1350,17 +1350,31 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) u32 srbm_status; u32 grbm_status; u32 grbm_status2; + struct r100_gpu_lockup *lockup; + int r; + + if (rdev->family >= CHIP_RV770) + lockup = &rdev->config.rv770.lockup; + else + lockup = &rdev->config.r600.lockup; srbm_status = RREG32(R_000E50_SRBM_STATUS); grbm_status = RREG32(R_008010_GRBM_STATUS); grbm_status2 = RREG32(R_008014_GRBM_STATUS2); if (!G_008010_GUI_ACTIVE(grbm_status)) { - radeon_ring_lockup_update(ring); + r100_gpu_lockup_update(lockup, ring); return false; } /* force CP activities */ - radeon_ring_force_activity(rdev, ring); - return radeon_ring_test_lockup(rdev, ring); + r = radeon_ring_lock(rdev, ring, 2); + if (!r) { + /* PACKET2 NOP */ + radeon_ring_write(ring, 0x80000000); + radeon_ring_write(ring, 0x80000000); + radeon_ring_unlock_commit(rdev, ring); + } + ring->rptr = RREG32(ring->rptr_reg); + return r100_gpu_cp_is_lockup(rdev, lockup, ring); } int r600_asic_reset(struct radeon_device *rdev) @@ -2363,15 +2377,20 @@ int r600_copy_blit(struct radeon_device *rdev, unsigned num_gpu_pages, struct radeon_fence *fence) { - struct radeon_sa_bo *vb = NULL; int r; - r = r600_blit_prepare_copy(rdev, num_gpu_pages, &vb); + mutex_lock(&rdev->r600_blit.mutex); + rdev->r600_blit.vb_ib = NULL; + r = r600_blit_prepare_copy(rdev, num_gpu_pages); if (r) { + if (rdev->r600_blit.vb_ib) + radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); + mutex_unlock(&rdev->r600_blit.mutex); return r; } - r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages, vb); - r600_blit_done_copy(rdev, fence, vb); + r600_kms_blit_copy(rdev, src_offset, dst_offset, num_gpu_pages); + r600_blit_done_copy(rdev, fence); + mutex_unlock(&rdev->r600_blit.mutex); return 0; } @@ -2475,9 +2494,12 @@ int r600_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_ring_tests(rdev); - if (r) + r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + if (r) { + DRM_ERROR("radeon: failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; + } return 0; } @@ -2653,6 +2675,7 @@ void r600_fini(struct radeon_device *rdev) r600_vram_scratch_fini(rdev); radeon_agp_fini(rdev); radeon_gem_fini(rdev); + radeon_semaphore_driver_fini(rdev); radeon_fence_driver_fini(rdev); radeon_bo_fini(rdev); radeon_atombios_fini(rdev); @@ -2681,7 +2704,7 @@ void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) { - struct radeon_ib ib; + struct radeon_ib *ib; uint32_t scratch; uint32_t tmp = 0; unsigned i; @@ -2699,18 +2722,18 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) DRM_ERROR("radeon: failed to get ib (%d).\n", r); return r; } - ib.ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1); - ib.ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); - ib.ptr[2] = 0xDEADBEEF; - ib.length_dw = 3; - r = radeon_ib_schedule(rdev, &ib); + ib->ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1); + ib->ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); + ib->ptr[2] = 0xDEADBEEF; + ib->length_dw = 3; + r = radeon_ib_schedule(rdev, ib); if (r) { radeon_scratch_free(rdev, scratch); radeon_ib_free(rdev, &ib); DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); return r; } - r = radeon_fence_wait(ib.fence, false); + r = radeon_fence_wait(ib->fence, false); if (r) { DRM_ERROR("radeon: fence wait failed (%d).\n", r); return r; @@ -2722,7 +2745,7 @@ int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) DRM_UDELAY(1); } if (i < rdev->usec_timeout) { - DRM_INFO("ib test on ring %d succeeded in %u usecs\n", ib.fence->ring, i); + DRM_INFO("ib test on ring %d succeeded in %u usecs\n", ib->fence->ring, i); } else { DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", scratch, tmp); diff --git a/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c b/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c index ef20822a1586..db38f587f27a 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/trunk/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -513,6 +513,7 @@ int r600_blit_init(struct radeon_device *rdev) rdev->r600_blit.primitives.set_default_state = set_default_state; rdev->r600_blit.ring_size_common = 40; /* shaders + def state */ + rdev->r600_blit.ring_size_common += 16; /* fence emit for VB IB */ rdev->r600_blit.ring_size_common += 5; /* done copy */ rdev->r600_blit.ring_size_common += 16; /* fence emit for done copy */ @@ -527,6 +528,7 @@ int r600_blit_init(struct radeon_device *rdev) if (rdev->r600_blit.shader_obj) goto done; + mutex_init(&rdev->r600_blit.mutex); rdev->r600_blit.state_offset = 0; if (rdev->family >= CHIP_RV770) @@ -619,6 +621,27 @@ void r600_blit_fini(struct radeon_device *rdev) radeon_bo_unref(&rdev->r600_blit.shader_obj); } +static int r600_vb_ib_get(struct radeon_device *rdev, unsigned size) +{ + int r; + r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, + &rdev->r600_blit.vb_ib, size); + if (r) { + DRM_ERROR("failed to get IB for vertex buffer\n"); + return r; + } + + rdev->r600_blit.vb_total = size; + rdev->r600_blit.vb_used = 0; + return 0; +} + +static void r600_vb_ib_put(struct radeon_device *rdev) +{ + radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence); + radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); +} + static unsigned r600_blit_create_rect(unsigned num_gpu_pages, int *width, int *height, int max_dim) { @@ -665,8 +688,7 @@ static unsigned r600_blit_create_rect(unsigned num_gpu_pages, } -int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages, - struct radeon_sa_bo **vb) +int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages) { struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; int r; @@ -683,54 +705,46 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages, } /* 48 bytes for vertex per loop */ - r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, vb, - (num_loops*48)+256, 256, true); - if (r) { + r = r600_vb_ib_get(rdev, (num_loops*48)+256); + if (r) return r; - } /* calculate number of loops correctly */ ring_size = num_loops * dwords_per_loop; ring_size += rdev->r600_blit.ring_size_common; r = radeon_ring_lock(rdev, ring, ring_size); - if (r) { - radeon_sa_bo_free(rdev, vb, NULL); + if (r) return r; - } rdev->r600_blit.primitives.set_default_state(rdev); rdev->r600_blit.primitives.set_shaders(rdev); return 0; } -void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence, - struct radeon_sa_bo *vb) +void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence) { - struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; int r; - r = radeon_fence_emit(rdev, fence); - if (r) { - radeon_ring_unlock_undo(rdev, ring); - return; - } + if (rdev->r600_blit.vb_ib) + r600_vb_ib_put(rdev); + + if (fence) + r = radeon_fence_emit(rdev, fence); - radeon_ring_unlock_commit(rdev, ring); - radeon_sa_bo_free(rdev, &vb, fence); + radeon_ring_unlock_commit(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); } void r600_kms_blit_copy(struct radeon_device *rdev, u64 src_gpu_addr, u64 dst_gpu_addr, - unsigned num_gpu_pages, - struct radeon_sa_bo *vb) + unsigned num_gpu_pages) { u64 vb_gpu_addr; - u32 *vb_cpu_addr; + u32 *vb; - DRM_DEBUG("emitting copy %16llx %16llx %d\n", - src_gpu_addr, dst_gpu_addr, num_gpu_pages); - vb_cpu_addr = (u32 *)radeon_sa_bo_cpu_addr(vb); - vb_gpu_addr = radeon_sa_bo_gpu_addr(vb); + DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", + src_gpu_addr, dst_gpu_addr, + num_gpu_pages, rdev->r600_blit.vb_used); + vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); while (num_gpu_pages) { int w, h; @@ -742,34 +756,39 @@ void r600_kms_blit_copy(struct radeon_device *rdev, size_in_bytes = pages_per_loop * RADEON_GPU_PAGE_SIZE; DRM_DEBUG("rectangle w=%d h=%d\n", w, h); - vb_cpu_addr[0] = 0; - vb_cpu_addr[1] = 0; - vb_cpu_addr[2] = 0; - vb_cpu_addr[3] = 0; + if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) { + WARN_ON(1); + } + + vb[0] = 0; + vb[1] = 0; + vb[2] = 0; + vb[3] = 0; - vb_cpu_addr[4] = 0; - vb_cpu_addr[5] = i2f(h); - vb_cpu_addr[6] = 0; - vb_cpu_addr[7] = i2f(h); + vb[4] = 0; + vb[5] = i2f(h); + vb[6] = 0; + vb[7] = i2f(h); - vb_cpu_addr[8] = i2f(w); - vb_cpu_addr[9] = i2f(h); - vb_cpu_addr[10] = i2f(w); - vb_cpu_addr[11] = i2f(h); + vb[8] = i2f(w); + vb[9] = i2f(h); + vb[10] = i2f(w); + vb[11] = i2f(h); rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8, w, h, w, src_gpu_addr, size_in_bytes); rdev->r600_blit.primitives.set_render_target(rdev, COLOR_8_8_8_8, w, h, dst_gpu_addr); rdev->r600_blit.primitives.set_scissors(rdev, 0, 0, w, h); + vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used; rdev->r600_blit.primitives.set_vtx_resource(rdev, vb_gpu_addr); rdev->r600_blit.primitives.draw_auto(rdev); rdev->r600_blit.primitives.cp_set_surface_sync(rdev, PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA, size_in_bytes, dst_gpu_addr); - vb_cpu_addr += 12; - vb_gpu_addr += 4*12; + vb += 12; + rdev->r600_blit.vb_used += 4*12; src_gpu_addr += size_in_bytes; dst_gpu_addr += size_in_bytes; num_gpu_pages -= pages_per_loop; diff --git a/trunk/drivers/gpu/drm/radeon/r600_cs.c b/trunk/drivers/gpu/drm/radeon/r600_cs.c index 0133f5f09bd6..b8e12af304a9 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_cs.c +++ b/trunk/drivers/gpu/drm/radeon/r600_cs.c @@ -345,7 +345,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) u32 height, height_align, pitch, pitch_align, depth_align; u64 base_offset, base_align; struct array_mode_checker array_check; - volatile u32 *ib = p->ib.ptr; + volatile u32 *ib = p->ib->ptr; unsigned array_mode; u32 format; @@ -471,7 +471,7 @@ static int r600_cs_track_validate_db(struct radeon_cs_parser *p) u64 base_offset, base_align; struct array_mode_checker array_check; int array_mode; - volatile u32 *ib = p->ib.ptr; + volatile u32 *ib = p->ib->ptr; if (track->db_bo == NULL) { @@ -961,7 +961,7 @@ static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) uint32_t header, h_idx, reg, wait_reg_mem_info; volatile uint32_t *ib; - ib = p->ib.ptr; + ib = p->ib->ptr; /* parse the WAIT_REG_MEM */ r = r600_cs_packet_parse(p, &wait_reg_mem, p->idx); @@ -1110,7 +1110,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) m = 1 << ((reg >> 2) & 31); if (!(r600_reg_safe_bm[i] & m)) return 0; - ib = p->ib.ptr; + ib = p->ib->ptr; switch (reg) { /* force following reg to 0 in an attempt to disable out buffer * which will need us to better understand how it works to perform @@ -1714,7 +1714,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, u32 idx_value; track = (struct r600_cs_track *)p->track; - ib = p->ib.ptr; + ib = p->ib->ptr; idx = pkt->idx + 1; idx_value = radeon_get_ib_value(p, idx); @@ -2249,8 +2249,8 @@ int r600_cs_parse(struct radeon_cs_parser *p) } } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); #if 0 - for (r = 0; r < p->ib.length_dw; r++) { - printk(KERN_INFO "%05d 0x%08X\n", r, p->ib.ptr[r]); + for (r = 0; r < p->ib->length_dw; r++) { + printk(KERN_INFO "%05d 0x%08X\n", r, p->ib->ptr[r]); mdelay(1); } #endif @@ -2298,6 +2298,7 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, { struct radeon_cs_parser parser; struct radeon_cs_chunk *ib_chunk; + struct radeon_ib fake_ib; struct r600_cs_track *track; int r; @@ -2313,8 +2314,9 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, parser.dev = &dev->pdev->dev; parser.rdev = NULL; parser.family = family; + parser.ib = &fake_ib; parser.track = track; - parser.ib.ptr = ib; + fake_ib.ptr = ib; r = radeon_cs_parser_init(&parser, data); if (r) { DRM_ERROR("Failed to initialize parser !\n"); @@ -2331,8 +2333,8 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, * input memory (cached) and write to the IB (which can be * uncached). */ ib_chunk = &parser.chunks[parser.chunk_ib_idx]; - parser.ib.length_dw = ib_chunk->length_dw; - *l = parser.ib.length_dw; + parser.ib->length_dw = ib_chunk->length_dw; + *l = parser.ib->length_dw; r = r600_cs_parse(&parser); if (r) { DRM_ERROR("Invalid command stream !\n"); diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h index 60233d7a6f7d..610acee74a3d 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon.h +++ b/trunk/drivers/gpu/drm/radeon/radeon.h @@ -94,38 +94,33 @@ extern int radeon_disp_priority; extern int radeon_hw_i2c; extern int radeon_pcie_gen2; extern int radeon_msi; -extern int radeon_lockup_timeout; /* * Copy from radeon_drv.h so we don't have to include both and have conflicting * symbol; */ -#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ -#define RADEON_FENCE_JIFFIES_TIMEOUT (HZ / 2) +#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ +#define RADEON_FENCE_JIFFIES_TIMEOUT (HZ / 2) /* RADEON_IB_POOL_SIZE must be a power of 2 */ -#define RADEON_IB_POOL_SIZE 16 -#define RADEON_DEBUGFS_MAX_COMPONENTS 32 -#define RADEONFB_CONN_LIMIT 4 -#define RADEON_BIOS_NUM_SCRATCH 8 +#define RADEON_IB_POOL_SIZE 16 +#define RADEON_DEBUGFS_MAX_COMPONENTS 32 +#define RADEONFB_CONN_LIMIT 4 +#define RADEON_BIOS_NUM_SCRATCH 8 /* max number of rings */ -#define RADEON_NUM_RINGS 3 - -/* fence seq are set to this number when signaled */ -#define RADEON_FENCE_SIGNALED_SEQ 0LL -#define RADEON_FENCE_NOTEMITED_SEQ (~0LL) +#define RADEON_NUM_RINGS 3 /* internal ring indices */ /* r1xx+ has gfx CP ring */ -#define RADEON_RING_TYPE_GFX_INDEX 0 +#define RADEON_RING_TYPE_GFX_INDEX 0 /* cayman has 2 compute CP rings */ -#define CAYMAN_RING_TYPE_CP1_INDEX 1 -#define CAYMAN_RING_TYPE_CP2_INDEX 2 +#define CAYMAN_RING_TYPE_CP1_INDEX 1 +#define CAYMAN_RING_TYPE_CP2_INDEX 2 /* hardcode those limit for now */ -#define RADEON_VA_RESERVED_SIZE (8 << 20) -#define RADEON_IB_VM_MAX_SIZE (64 << 10) +#define RADEON_VA_RESERVED_SIZE (8 << 20) +#define RADEON_IB_VM_MAX_SIZE (64 << 10) /* * Errata workarounds. @@ -258,20 +253,28 @@ struct radeon_fence_driver { uint32_t scratch_reg; uint64_t gpu_addr; volatile uint32_t *cpu_addr; - /* seq is protected by ring emission lock */ - uint64_t seq; - atomic64_t last_seq; - unsigned long last_activity; + atomic_t seq; + uint32_t last_seq; + unsigned long last_jiffies; + unsigned long last_timeout; + wait_queue_head_t queue; + struct list_head created; + struct list_head emitted; + struct list_head signaled; bool initialized; }; struct radeon_fence { struct radeon_device *rdev; struct kref kref; + struct list_head list; /* protected by radeon_fence.lock */ - uint64_t seq; + uint32_t seq; + bool emitted; + bool signaled; /* RB, DMA, etc. */ - unsigned ring; + int ring; + struct radeon_semaphore *semaphore; }; int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); @@ -282,14 +285,11 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence); void radeon_fence_process(struct radeon_device *rdev, int ring); bool radeon_fence_signaled(struct radeon_fence *fence); int radeon_fence_wait(struct radeon_fence *fence, bool interruptible); -int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring); -int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring); -int radeon_fence_wait_any(struct radeon_device *rdev, - struct radeon_fence **fences, - bool intr); +int radeon_fence_wait_next(struct radeon_device *rdev, int ring); +int radeon_fence_wait_last(struct radeon_device *rdev, int ring); struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence); void radeon_fence_unref(struct radeon_fence **fence); -unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring); +int radeon_fence_count_emitted(struct radeon_device *rdev, int ring); /* * Tiling registers @@ -382,11 +382,8 @@ struct radeon_bo_list { * alignment). */ struct radeon_sa_manager { - spinlock_t lock; struct radeon_bo *bo; - struct list_head *hole; - struct list_head flist[RADEON_NUM_RINGS]; - struct list_head olist; + struct list_head sa_bo; unsigned size; uint64_t gpu_addr; void *cpu_ptr; @@ -397,12 +394,10 @@ struct radeon_sa_bo; /* sub-allocation buffer */ struct radeon_sa_bo { - struct list_head olist; - struct list_head flist; + struct list_head list; struct radeon_sa_manager *manager; - unsigned soffset; - unsigned eoffset; - struct radeon_fence *fence; + unsigned offset; + unsigned size; }; /* @@ -433,26 +428,42 @@ int radeon_mode_dumb_destroy(struct drm_file *file_priv, /* * Semaphores. */ +struct radeon_ring; + +#define RADEON_SEMAPHORE_BO_SIZE 256 + +struct radeon_semaphore_driver { + rwlock_t lock; + struct list_head bo; +}; + +struct radeon_semaphore_bo; + /* everything here is constant */ struct radeon_semaphore { - struct radeon_sa_bo *sa_bo; - signed waiters; + struct list_head list; uint64_t gpu_addr; + uint32_t *cpu_ptr; + struct radeon_semaphore_bo *bo; +}; + +struct radeon_semaphore_bo { + struct list_head list; + struct radeon_ib *ib; + struct list_head free; + struct radeon_semaphore semaphores[RADEON_SEMAPHORE_BO_SIZE/8]; + unsigned nused; }; +void radeon_semaphore_driver_fini(struct radeon_device *rdev); int radeon_semaphore_create(struct radeon_device *rdev, struct radeon_semaphore **semaphore); void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, struct radeon_semaphore *semaphore); void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, struct radeon_semaphore *semaphore); -int radeon_semaphore_sync_rings(struct radeon_device *rdev, - struct radeon_semaphore *semaphore, - bool sync_to[RADEON_NUM_RINGS], - int dst_ring); void radeon_semaphore_free(struct radeon_device *rdev, - struct radeon_semaphore *semaphore, - struct radeon_fence *fence); + struct radeon_semaphore *semaphore); /* * GART structures, functions & helpers @@ -623,14 +634,26 @@ void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc); */ struct radeon_ib { - struct radeon_sa_bo *sa_bo; - uint32_t length_dw; - uint64_t gpu_addr; - uint32_t *ptr; - struct radeon_fence *fence; - unsigned vm_id; - bool is_const_ib; - struct radeon_semaphore *semaphore; + struct radeon_sa_bo sa_bo; + unsigned idx; + uint32_t length_dw; + uint64_t gpu_addr; + uint32_t *ptr; + struct radeon_fence *fence; + unsigned vm_id; + bool is_const_ib; +}; + +/* + * locking - + * mutex protects scheduled_ibs, ready, alloc_bm + */ +struct radeon_ib_pool { + struct radeon_mutex mutex; + struct radeon_sa_manager sa_manager; + struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; + bool ready; + unsigned head_id; }; struct radeon_ring { @@ -645,11 +668,10 @@ struct radeon_ring { unsigned ring_size; unsigned ring_free_dw; int count_dw; - unsigned long last_activity; - unsigned last_rptr; uint64_t gpu_addr; uint32_t align_mask; uint32_t ptr_mask; + struct mutex mutex; bool ready; u32 ptr_reg_shift; u32 ptr_reg_mask; @@ -666,7 +688,7 @@ struct radeon_vm { unsigned last_pfn; u64 pt_gpu_addr; u64 *pt; - struct radeon_sa_bo *sa_bo; + struct radeon_sa_bo sa_bo; struct mutex mutex; /* last fence for cs using this vm */ struct radeon_fence *fence; @@ -743,6 +765,7 @@ struct r600_blit_cp_primitives { }; struct r600_blit { + struct mutex mutex; struct radeon_bo *shader_obj; struct r600_blit_cp_primitives primitives; int max_dim; @@ -752,6 +775,8 @@ struct r600_blit { u32 vs_offset, ps_offset; u32 state_offset; u32 state_len; + u32 vb_used, vb_total; + struct radeon_ib *vb_ib; }; void r600_blit_suspend(struct radeon_device *rdev); @@ -769,14 +794,14 @@ struct si_rlc { }; int radeon_ib_get(struct radeon_device *rdev, int ring, - struct radeon_ib *ib, unsigned size); -void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib); + struct radeon_ib **ib, unsigned size); +void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib); +bool radeon_ib_try_free(struct radeon_device *rdev, struct radeon_ib *ib); int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib); int radeon_ib_pool_init(struct radeon_device *rdev); void radeon_ib_pool_fini(struct radeon_device *rdev); int radeon_ib_pool_start(struct radeon_device *rdev); int radeon_ib_pool_suspend(struct radeon_device *rdev); -int radeon_ib_ring_tests(struct radeon_device *rdev); /* Ring access between begin & end cannot sleep */ int radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *cp); void radeon_ring_free_size(struct radeon_device *rdev, struct radeon_ring *cp); @@ -784,12 +809,8 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *cp, unsign int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ndw); void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *cp); void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *cp); -void radeon_ring_undo(struct radeon_ring *ring); void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp); int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); -void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring); -void radeon_ring_lockup_update(struct radeon_ring *ring); -bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring); int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop); @@ -838,8 +859,8 @@ struct radeon_cs_parser { int chunk_relocs_idx; int chunk_flags_idx; int chunk_const_ib_idx; - struct radeon_ib ib; - struct radeon_ib const_ib; + struct radeon_ib *ib; + struct radeon_ib *const_ib; void *track; unsigned family; int parser_error; @@ -1141,6 +1162,7 @@ struct radeon_asic { int (*resume)(struct radeon_device *rdev); int (*suspend)(struct radeon_device *rdev); void (*vga_set_state)(struct radeon_device *rdev, bool state); + bool (*gpu_is_lockup)(struct radeon_device *rdev, struct radeon_ring *cp); int (*asic_reset)(struct radeon_device *rdev); /* ioctl hw specific callback. Some hw might want to perform special * operation on specific ioctl. For instance on wait idle some hw @@ -1169,7 +1191,6 @@ struct radeon_asic { void (*ring_start)(struct radeon_device *rdev, struct radeon_ring *cp); int (*ring_test)(struct radeon_device *rdev, struct radeon_ring *cp); int (*ib_test)(struct radeon_device *rdev, struct radeon_ring *cp); - bool (*is_lockup)(struct radeon_device *rdev, struct radeon_ring *cp); } ring[RADEON_NUM_RINGS]; /* irqs */ struct { @@ -1248,10 +1269,16 @@ struct radeon_asic { /* * Asic structures */ +struct r100_gpu_lockup { + unsigned long last_jiffies; + u32 last_cp_rptr; +}; + struct r100_asic { const unsigned *reg_safe_bm; unsigned reg_safe_bm_size; u32 hdp_cntl; + struct r100_gpu_lockup lockup; }; struct r300_asic { @@ -1259,6 +1286,7 @@ struct r300_asic { unsigned reg_safe_bm_size; u32 resync_scratch; u32 hdp_cntl; + struct r100_gpu_lockup lockup; }; struct r600_asic { @@ -1280,6 +1308,7 @@ struct r600_asic { unsigned tiling_group_size; unsigned tile_config; unsigned backend_map; + struct r100_gpu_lockup lockup; }; struct rv770_asic { @@ -1305,6 +1334,7 @@ struct rv770_asic { unsigned tiling_group_size; unsigned tile_config; unsigned backend_map; + struct r100_gpu_lockup lockup; }; struct evergreen_asic { @@ -1331,6 +1361,7 @@ struct evergreen_asic { unsigned tiling_group_size; unsigned tile_config; unsigned backend_map; + struct r100_gpu_lockup lockup; }; struct cayman_asic { @@ -1369,6 +1400,7 @@ struct cayman_asic { unsigned multi_gpu_tile_size; unsigned tile_config; + struct r100_gpu_lockup lockup; }; struct si_asic { @@ -1399,6 +1431,7 @@ struct si_asic { unsigned multi_gpu_tile_size; unsigned tile_config; + struct r100_gpu_lockup lockup; }; union radeon_asic_config { @@ -1501,12 +1534,11 @@ struct radeon_device { struct radeon_mode_info mode_info; struct radeon_scratch scratch; struct radeon_mman mman; + rwlock_t fence_lock; struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS]; - wait_queue_head_t fence_queue; - struct mutex ring_lock; + struct radeon_semaphore_driver semaphore_drv; struct radeon_ring ring[RADEON_NUM_RINGS]; - bool ib_pool_ready; - struct radeon_sa_manager ring_tmp_bo; + struct radeon_ib_pool ib_pool; struct radeon_irq irq; struct radeon_asic *asic; struct radeon_gem gem; @@ -1515,6 +1547,7 @@ struct radeon_device { struct radeon_mutex cs_mutex; struct radeon_wb wb; struct radeon_dummy_page dummy_page; + bool gpu_lockup; bool shutdown; bool suspend; bool need_dma32; @@ -1707,6 +1740,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); #define radeon_suspend(rdev) (rdev)->asic->suspend((rdev)) #define radeon_cs_parse(rdev, r, p) (rdev)->asic->ring[(r)].cs_parse((p)) #define radeon_vga_set_state(rdev, state) (rdev)->asic->vga_set_state((rdev), (state)) +#define radeon_gpu_is_lockup(rdev, cp) (rdev)->asic->gpu_is_lockup((rdev), (cp)) #define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) #define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev)) #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), (i), (p)) @@ -1715,7 +1749,6 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); #define radeon_ib_test(rdev, r, cp) (rdev)->asic->ring[(r)].ib_test((rdev), (cp)) #define radeon_ring_ib_execute(rdev, r, ib) (rdev)->asic->ring[(r)].ib_execute((rdev), (ib)) #define radeon_ring_ib_parse(rdev, r, ib) (rdev)->asic->ring[(r)].ib_parse((rdev), (ib)) -#define radeon_ring_is_lockup(rdev, r, cp) (rdev)->asic->ring[(r)].is_lockup((rdev), (cp)) #define radeon_irq_set(rdev) (rdev)->asic->irq.set((rdev)) #define radeon_irq_process(rdev) (rdev)->asic->irq.process((rdev)) #define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->display.get_vblank_counter((rdev), (crtc)) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.c b/trunk/drivers/gpu/drm/radeon/radeon_asic.c index f533df5f7d50..be4dc2ff0e40 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_asic.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.c @@ -134,6 +134,7 @@ static struct radeon_asic r100_asic = { .suspend = &r100_suspend, .resume = &r100_resume, .vga_set_state = &r100_vga_set_state, + .gpu_is_lockup = &r100_gpu_is_lockup, .asic_reset = &r100_asic_reset, .ioctl_wait_idle = NULL, .gui_idle = &r100_gui_idle, @@ -151,7 +152,6 @@ static struct radeon_asic r100_asic = { .ring_start = &r100_ring_start, .ring_test = &r100_ring_test, .ib_test = &r100_ib_test, - .is_lockup = &r100_gpu_is_lockup, } }, .irq = { @@ -208,6 +208,7 @@ static struct radeon_asic r200_asic = { .suspend = &r100_suspend, .resume = &r100_resume, .vga_set_state = &r100_vga_set_state, + .gpu_is_lockup = &r100_gpu_is_lockup, .asic_reset = &r100_asic_reset, .ioctl_wait_idle = NULL, .gui_idle = &r100_gui_idle, @@ -225,7 +226,6 @@ static struct radeon_asic r200_asic = { .ring_start = &r100_ring_start, .ring_test = &r100_ring_test, .ib_test = &r100_ib_test, - .is_lockup = &r100_gpu_is_lockup, } }, .irq = { @@ -282,6 +282,7 @@ static struct radeon_asic r300_asic = { .suspend = &r300_suspend, .resume = &r300_resume, .vga_set_state = &r100_vga_set_state, + .gpu_is_lockup = &r300_gpu_is_lockup, .asic_reset = &r300_asic_reset, .ioctl_wait_idle = NULL, .gui_idle = &r100_gui_idle, @@ -299,7 +300,6 @@ static struct radeon_asic r300_asic = { .ring_start = &r300_ring_start, .ring_test = &r100_ring_test, .ib_test = &r100_ib_test, - .is_lockup = &r100_gpu_is_lockup, } }, .irq = { @@ -356,6 +356,7 @@ static struct radeon_asic r300_asic_pcie = { .suspend = &r300_suspend, .resume = &r300_resume, .vga_set_state = &r100_vga_set_state, + .gpu_is_lockup = &r300_gpu_is_lockup, .asic_reset = &r300_asic_reset, .ioctl_wait_idle = NULL, .gui_idle = &r100_gui_idle, @@ -373,7 +374,6 @@ static struct radeon_asic r300_asic_pcie = { .ring_start = &r300_ring_start, .ring_test = &r100_ring_test, .ib_test = &r100_ib_test, - .is_lockup = &r100_gpu_is_lockup, } }, .irq = { @@ -430,6 +430,7 @@ static struct radeon_asic r420_asic = { .suspend = &r420_suspend, .resume = &r420_resume, .vga_set_state = &r100_vga_set_state, + .gpu_is_lockup = &r300_gpu_is_lockup, .asic_reset = &r300_asic_reset, .ioctl_wait_idle = NULL, .gui_idle = &r100_gui_idle, @@ -447,7 +448,6 @@ static struct radeon_asic r420_asic = { .ring_start = &r300_ring_start, .ring_test = &r100_ring_test, .ib_test = &r100_ib_test, - .is_lockup = &r100_gpu_is_lockup, } }, .irq = { @@ -504,6 +504,7 @@ static struct radeon_asic rs400_asic = { .suspend = &rs400_suspend, .resume = &rs400_resume, .vga_set_state = &r100_vga_set_state, + .gpu_is_lockup = &r300_gpu_is_lockup, .asic_reset = &r300_asic_reset, .ioctl_wait_idle = NULL, .gui_idle = &r100_gui_idle, @@ -521,7 +522,6 @@ static struct radeon_asic rs400_asic = { .ring_start = &r300_ring_start, .ring_test = &r100_ring_test, .ib_test = &r100_ib_test, - .is_lockup = &r100_gpu_is_lockup, } }, .irq = { @@ -578,6 +578,7 @@ static struct radeon_asic rs600_asic = { .suspend = &rs600_suspend, .resume = &rs600_resume, .vga_set_state = &r100_vga_set_state, + .gpu_is_lockup = &r300_gpu_is_lockup, .asic_reset = &rs600_asic_reset, .ioctl_wait_idle = NULL, .gui_idle = &r100_gui_idle, @@ -595,7 +596,6 @@ static struct radeon_asic rs600_asic = { .ring_start = &r300_ring_start, .ring_test = &r100_ring_test, .ib_test = &r100_ib_test, - .is_lockup = &r100_gpu_is_lockup, } }, .irq = { @@ -652,6 +652,7 @@ static struct radeon_asic rs690_asic = { .suspend = &rs690_suspend, .resume = &rs690_resume, .vga_set_state = &r100_vga_set_state, + .gpu_is_lockup = &r300_gpu_is_lockup, .asic_reset = &rs600_asic_reset, .ioctl_wait_idle = NULL, .gui_idle = &r100_gui_idle, @@ -669,7 +670,6 @@ static struct radeon_asic rs690_asic = { .ring_start = &r300_ring_start, .ring_test = &r100_ring_test, .ib_test = &r100_ib_test, - .is_lockup = &r100_gpu_is_lockup, } }, .irq = { @@ -726,6 +726,7 @@ static struct radeon_asic rv515_asic = { .suspend = &rv515_suspend, .resume = &rv515_resume, .vga_set_state = &r100_vga_set_state, + .gpu_is_lockup = &r300_gpu_is_lockup, .asic_reset = &rs600_asic_reset, .ioctl_wait_idle = NULL, .gui_idle = &r100_gui_idle, @@ -743,7 +744,6 @@ static struct radeon_asic rv515_asic = { .ring_start = &rv515_ring_start, .ring_test = &r100_ring_test, .ib_test = &r100_ib_test, - .is_lockup = &r100_gpu_is_lockup, } }, .irq = { @@ -800,6 +800,7 @@ static struct radeon_asic r520_asic = { .suspend = &rv515_suspend, .resume = &r520_resume, .vga_set_state = &r100_vga_set_state, + .gpu_is_lockup = &r300_gpu_is_lockup, .asic_reset = &rs600_asic_reset, .ioctl_wait_idle = NULL, .gui_idle = &r100_gui_idle, @@ -817,7 +818,6 @@ static struct radeon_asic r520_asic = { .ring_start = &rv515_ring_start, .ring_test = &r100_ring_test, .ib_test = &r100_ib_test, - .is_lockup = &r100_gpu_is_lockup, } }, .irq = { @@ -874,6 +874,7 @@ static struct radeon_asic r600_asic = { .suspend = &r600_suspend, .resume = &r600_resume, .vga_set_state = &r600_vga_set_state, + .gpu_is_lockup = &r600_gpu_is_lockup, .asic_reset = &r600_asic_reset, .ioctl_wait_idle = r600_ioctl_wait_idle, .gui_idle = &r600_gui_idle, @@ -890,7 +891,6 @@ static struct radeon_asic r600_asic = { .cs_parse = &r600_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &r600_gpu_is_lockup, } }, .irq = { @@ -946,6 +946,7 @@ static struct radeon_asic rs780_asic = { .fini = &r600_fini, .suspend = &r600_suspend, .resume = &r600_resume, + .gpu_is_lockup = &r600_gpu_is_lockup, .vga_set_state = &r600_vga_set_state, .asic_reset = &r600_asic_reset, .ioctl_wait_idle = r600_ioctl_wait_idle, @@ -963,7 +964,6 @@ static struct radeon_asic rs780_asic = { .cs_parse = &r600_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &r600_gpu_is_lockup, } }, .irq = { @@ -1020,6 +1020,7 @@ static struct radeon_asic rv770_asic = { .suspend = &rv770_suspend, .resume = &rv770_resume, .asic_reset = &r600_asic_reset, + .gpu_is_lockup = &r600_gpu_is_lockup, .vga_set_state = &r600_vga_set_state, .ioctl_wait_idle = r600_ioctl_wait_idle, .gui_idle = &r600_gui_idle, @@ -1036,7 +1037,6 @@ static struct radeon_asic rv770_asic = { .cs_parse = &r600_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &r600_gpu_is_lockup, } }, .irq = { @@ -1092,6 +1092,7 @@ static struct radeon_asic evergreen_asic = { .fini = &evergreen_fini, .suspend = &evergreen_suspend, .resume = &evergreen_resume, + .gpu_is_lockup = &evergreen_gpu_is_lockup, .asic_reset = &evergreen_asic_reset, .vga_set_state = &r600_vga_set_state, .ioctl_wait_idle = r600_ioctl_wait_idle, @@ -1109,7 +1110,6 @@ static struct radeon_asic evergreen_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, } }, .irq = { @@ -1165,6 +1165,7 @@ static struct radeon_asic sumo_asic = { .fini = &evergreen_fini, .suspend = &evergreen_suspend, .resume = &evergreen_resume, + .gpu_is_lockup = &evergreen_gpu_is_lockup, .asic_reset = &evergreen_asic_reset, .vga_set_state = &r600_vga_set_state, .ioctl_wait_idle = r600_ioctl_wait_idle, @@ -1182,7 +1183,6 @@ static struct radeon_asic sumo_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, }, }, .irq = { @@ -1238,6 +1238,7 @@ static struct radeon_asic btc_asic = { .fini = &evergreen_fini, .suspend = &evergreen_suspend, .resume = &evergreen_resume, + .gpu_is_lockup = &evergreen_gpu_is_lockup, .asic_reset = &evergreen_asic_reset, .vga_set_state = &r600_vga_set_state, .ioctl_wait_idle = r600_ioctl_wait_idle, @@ -1255,7 +1256,6 @@ static struct radeon_asic btc_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, } }, .irq = { @@ -1321,6 +1321,7 @@ static struct radeon_asic cayman_asic = { .fini = &cayman_fini, .suspend = &cayman_suspend, .resume = &cayman_resume, + .gpu_is_lockup = &cayman_gpu_is_lockup, .asic_reset = &cayman_asic_reset, .vga_set_state = &r600_vga_set_state, .ioctl_wait_idle = r600_ioctl_wait_idle, @@ -1339,7 +1340,6 @@ static struct radeon_asic cayman_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, }, [CAYMAN_RING_TYPE_CP1_INDEX] = { .ib_execute = &cayman_ring_ib_execute, @@ -1349,7 +1349,6 @@ static struct radeon_asic cayman_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, }, [CAYMAN_RING_TYPE_CP2_INDEX] = { .ib_execute = &cayman_ring_ib_execute, @@ -1359,7 +1358,6 @@ static struct radeon_asic cayman_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, } }, .irq = { @@ -1415,6 +1413,7 @@ static struct radeon_asic trinity_asic = { .fini = &cayman_fini, .suspend = &cayman_suspend, .resume = &cayman_resume, + .gpu_is_lockup = &cayman_gpu_is_lockup, .asic_reset = &cayman_asic_reset, .vga_set_state = &r600_vga_set_state, .ioctl_wait_idle = r600_ioctl_wait_idle, @@ -1433,7 +1432,6 @@ static struct radeon_asic trinity_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, }, [CAYMAN_RING_TYPE_CP1_INDEX] = { .ib_execute = &cayman_ring_ib_execute, @@ -1443,7 +1441,6 @@ static struct radeon_asic trinity_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, }, [CAYMAN_RING_TYPE_CP2_INDEX] = { .ib_execute = &cayman_ring_ib_execute, @@ -1453,7 +1450,6 @@ static struct radeon_asic trinity_asic = { .cs_parse = &evergreen_cs_parse, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &evergreen_gpu_is_lockup, } }, .irq = { @@ -1519,6 +1515,7 @@ static struct radeon_asic si_asic = { .fini = &si_fini, .suspend = &si_suspend, .resume = &si_resume, + .gpu_is_lockup = &si_gpu_is_lockup, .asic_reset = &si_asic_reset, .vga_set_state = &r600_vga_set_state, .ioctl_wait_idle = r600_ioctl_wait_idle, @@ -1537,7 +1534,6 @@ static struct radeon_asic si_asic = { .cs_parse = NULL, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &si_gpu_is_lockup, }, [CAYMAN_RING_TYPE_CP1_INDEX] = { .ib_execute = &si_ring_ib_execute, @@ -1547,7 +1543,6 @@ static struct radeon_asic si_asic = { .cs_parse = NULL, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &si_gpu_is_lockup, }, [CAYMAN_RING_TYPE_CP2_INDEX] = { .ib_execute = &si_ring_ib_execute, @@ -1557,7 +1552,6 @@ static struct radeon_asic si_asic = { .cs_parse = NULL, .ring_test = &r600_ring_test, .ib_test = &r600_ib_test, - .is_lockup = &si_gpu_is_lockup, } }, .irq = { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.h b/trunk/drivers/gpu/drm/radeon/radeon_asic.h index 05a4e15f5465..b135bec649d1 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_asic.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.h @@ -103,6 +103,11 @@ int r100_pci_gart_enable(struct radeon_device *rdev); void r100_pci_gart_disable(struct radeon_device *rdev); int r100_debugfs_mc_info_init(struct radeon_device *rdev); int r100_gui_wait_for_idle(struct radeon_device *rdev); +void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, + struct radeon_ring *cp); +bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, + struct r100_gpu_lockup *lockup, + struct radeon_ring *cp); void r100_ib_fini(struct radeon_device *rdev); int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); void r100_irq_disable(struct radeon_device *rdev); @@ -154,6 +159,7 @@ extern int r300_init(struct radeon_device *rdev); extern void r300_fini(struct radeon_device *rdev); extern int r300_suspend(struct radeon_device *rdev); extern int r300_resume(struct radeon_device *rdev); +extern bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); extern int r300_asic_reset(struct radeon_device *rdev); extern void r300_ring_start(struct radeon_device *rdev, struct radeon_ring *ring); extern void r300_fence_ring_emit(struct radeon_device *rdev, @@ -368,14 +374,11 @@ void r600_hdmi_init(struct drm_encoder *encoder); int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); /* r600 blit */ -int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages, - struct radeon_sa_bo **vb); -void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence, - struct radeon_sa_bo *vb); +int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_gpu_pages); +void r600_blit_done_copy(struct radeon_device *rdev, struct radeon_fence *fence); void r600_kms_blit_copy(struct radeon_device *rdev, u64 src_gpu_addr, u64 dst_gpu_addr, - unsigned num_gpu_pages, - struct radeon_sa_bo *vb); + unsigned num_gpu_pages); int r600_mc_wait_for_idle(struct radeon_device *rdev); /* @@ -440,6 +443,7 @@ int cayman_init(struct radeon_device *rdev); void cayman_fini(struct radeon_device *rdev); int cayman_suspend(struct radeon_device *rdev); int cayman_resume(struct radeon_device *rdev); +bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *cp); int cayman_asic_reset(struct radeon_device *rdev); void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib); int cayman_vm_init(struct radeon_device *rdev); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_combios.c b/trunk/drivers/gpu/drm/radeon/radeon_combios.c index 576f4f6919f2..2cad9fde92fc 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_combios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_combios.c @@ -1561,11 +1561,6 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) (rdev->pdev->subsystem_device == 0x4150)) { /* Mac G5 tower 9600 */ rdev->mode_info.connector_table = CT_MAC_G5_9600; - } else if ((rdev->pdev->device == 0x4c66) && - (rdev->pdev->subsystem_vendor == 0x1002) && - (rdev->pdev->subsystem_device == 0x4c66)) { - /* SAM440ep RV250 embedded board */ - rdev->mode_info.connector_table = CT_SAM440EP; } else #endif /* CONFIG_PPC_PMAC */ #ifdef CONFIG_PPC64 @@ -2139,67 +2134,6 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) CONNECTOR_OBJECT_ID_SVIDEO, &hpd); break; - case CT_SAM440EP: - DRM_INFO("Connector Table: %d (SAM440ep embedded board)\n", - rdev->mode_info.connector_table); - /* LVDS */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_LCD1_SUPPORT, - 0), - ATOM_DEVICE_LCD1_SUPPORT); - radeon_add_legacy_connector(dev, 0, ATOM_DEVICE_LCD1_SUPPORT, - DRM_MODE_CONNECTOR_LVDS, &ddc_i2c, - CONNECTOR_OBJECT_ID_LVDS, - &hpd); - /* DVI-I - secondary dac, int tmds */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); - hpd.hpd = RADEON_HPD_1; /* ??? */ - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_DFP1_SUPPORT, - 0), - ATOM_DEVICE_DFP1_SUPPORT); - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT2_SUPPORT, - 2), - ATOM_DEVICE_CRT2_SUPPORT); - radeon_add_legacy_connector(dev, 1, - ATOM_DEVICE_DFP1_SUPPORT | - ATOM_DEVICE_CRT2_SUPPORT, - DRM_MODE_CONNECTOR_DVII, &ddc_i2c, - CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, - &hpd); - /* VGA - primary dac */ - ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_CRT1_SUPPORT, - 1), - ATOM_DEVICE_CRT1_SUPPORT); - radeon_add_legacy_connector(dev, 2, - ATOM_DEVICE_CRT1_SUPPORT, - DRM_MODE_CONNECTOR_VGA, &ddc_i2c, - CONNECTOR_OBJECT_ID_VGA, - &hpd); - /* TV - TV DAC */ - ddc_i2c.valid = false; - hpd.hpd = RADEON_HPD_NONE; - radeon_add_legacy_encoder(dev, - radeon_get_encoder_enum(dev, - ATOM_DEVICE_TV1_SUPPORT, - 2), - ATOM_DEVICE_TV1_SUPPORT); - radeon_add_legacy_connector(dev, 3, ATOM_DEVICE_TV1_SUPPORT, - DRM_MODE_CONNECTOR_SVIDEO, - &ddc_i2c, - CONNECTOR_OBJECT_ID_SVIDEO, - &hpd); - break; default: DRM_INFO("Connector table: %d (invalid)\n", rdev->mode_info.connector_table); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c index 2914c5761cfc..71fa389e10fe 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1026,7 +1026,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) encoder = obj_to_encoder(obj); - if (encoder->encoder_type != DRM_MODE_ENCODER_DAC && + if (encoder->encoder_type != DRM_MODE_ENCODER_DAC || encoder->encoder_type != DRM_MODE_ENCODER_TVDAC) continue; @@ -1056,7 +1056,6 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) * cases the DVI port is actually a virtual KVM port connected to the service * processor. */ -out: if ((!rdev->is_atom_bios) && (ret == connector_status_disconnected) && rdev->mode_info.bios_hardcoded_edid_size) { @@ -1064,6 +1063,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) ret = connector_status_connected; } +out: /* updated in get modes as well since we need to know if it's analog or digital */ radeon_connector_update_scratch_regs(connector, ret); return ret; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cs.c b/trunk/drivers/gpu/drm/radeon/radeon_cs.c index c7d64a739033..e7b0b5d51bc3 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cs.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cs.c @@ -118,33 +118,44 @@ static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority static int radeon_cs_sync_rings(struct radeon_cs_parser *p) { bool sync_to_ring[RADEON_NUM_RINGS] = { }; - bool need_sync = false; int i, r; for (i = 0; i < p->nrelocs; i++) { - struct radeon_fence *fence; - if (!p->relocs[i].robj || !p->relocs[i].robj->tbo.sync_obj) continue; - fence = p->relocs[i].robj->tbo.sync_obj; - if (fence->ring != p->ring && !radeon_fence_signaled(fence)) { - sync_to_ring[fence->ring] = true; - need_sync = true; + if (!(p->relocs[i].flags & RADEON_RELOC_DONT_SYNC)) { + struct radeon_fence *fence = p->relocs[i].robj->tbo.sync_obj; + if (!radeon_fence_signaled(fence)) { + sync_to_ring[fence->ring] = true; + } } } - if (!need_sync) { - return 0; - } + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + /* no need to sync to our own or unused rings */ + if (i == p->ring || !sync_to_ring[i] || !p->rdev->ring[i].ready) + continue; - r = radeon_semaphore_create(p->rdev, &p->ib.semaphore); - if (r) { - return r; - } + if (!p->ib->fence->semaphore) { + r = radeon_semaphore_create(p->rdev, &p->ib->fence->semaphore); + if (r) + return r; + } + + r = radeon_ring_lock(p->rdev, &p->rdev->ring[i], 3); + if (r) + return r; + radeon_semaphore_emit_signal(p->rdev, i, p->ib->fence->semaphore); + radeon_ring_unlock_commit(p->rdev, &p->rdev->ring[i]); - return radeon_semaphore_sync_rings(p->rdev, p->ib.semaphore, - sync_to_ring, p->ring); + r = radeon_ring_lock(p->rdev, &p->rdev->ring[p->ring], 3); + if (r) + return r; + radeon_semaphore_emit_wait(p->rdev, p->ring, p->ib->fence->semaphore); + radeon_ring_unlock_commit(p->rdev, &p->rdev->ring[p->ring]); + } + return 0; } int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) @@ -161,10 +172,6 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) /* get chunks */ INIT_LIST_HEAD(&p->validated); p->idx = 0; - p->ib.sa_bo = NULL; - p->ib.semaphore = NULL; - p->const_ib.sa_bo = NULL; - p->const_ib.semaphore = NULL; p->chunk_ib_idx = -1; p->chunk_relocs_idx = -1; p->chunk_flags_idx = -1; @@ -303,9 +310,10 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) { unsigned i; - if (!error) + + if (!error && parser->ib) ttm_eu_fence_buffer_objects(&parser->validated, - parser->ib.fence); + parser->ib->fence); else ttm_eu_backoff_reservation(&parser->validated); @@ -328,7 +336,6 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) kfree(parser->chunks); kfree(parser->chunks_array); radeon_ib_free(parser->rdev, &parser->ib); - radeon_ib_free(parser->rdev, &parser->const_ib); } static int radeon_cs_ib_chunk(struct radeon_device *rdev, @@ -354,7 +361,7 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, DRM_ERROR("Failed to get ib !\n"); return r; } - parser->ib.length_dw = ib_chunk->length_dw; + parser->ib->length_dw = ib_chunk->length_dw; r = radeon_cs_parse(rdev, parser->ring, parser); if (r || parser->parser_error) { DRM_ERROR("Invalid command stream !\n"); @@ -369,8 +376,8 @@ static int radeon_cs_ib_chunk(struct radeon_device *rdev, if (r) { DRM_ERROR("Failed to synchronize rings !\n"); } - parser->ib.vm_id = 0; - r = radeon_ib_schedule(rdev, &parser->ib); + parser->ib->vm_id = 0; + r = radeon_ib_schedule(rdev, parser->ib); if (r) { DRM_ERROR("Failed to schedule IB !\n"); } @@ -421,14 +428,14 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, DRM_ERROR("Failed to get const ib !\n"); return r; } - parser->const_ib.is_const_ib = true; - parser->const_ib.length_dw = ib_chunk->length_dw; + parser->const_ib->is_const_ib = true; + parser->const_ib->length_dw = ib_chunk->length_dw; /* Copy the packet into the IB */ - if (DRM_COPY_FROM_USER(parser->const_ib.ptr, ib_chunk->user_ptr, + if (DRM_COPY_FROM_USER(parser->const_ib->ptr, ib_chunk->user_ptr, ib_chunk->length_dw * 4)) { return -EFAULT; } - r = radeon_ring_ib_parse(rdev, parser->ring, &parser->const_ib); + r = radeon_ring_ib_parse(rdev, parser->ring, parser->const_ib); if (r) { return r; } @@ -445,13 +452,13 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, DRM_ERROR("Failed to get ib !\n"); return r; } - parser->ib.length_dw = ib_chunk->length_dw; + parser->ib->length_dw = ib_chunk->length_dw; /* Copy the packet into the IB */ - if (DRM_COPY_FROM_USER(parser->ib.ptr, ib_chunk->user_ptr, + if (DRM_COPY_FROM_USER(parser->ib->ptr, ib_chunk->user_ptr, ib_chunk->length_dw * 4)) { return -EFAULT; } - r = radeon_ring_ib_parse(rdev, parser->ring, &parser->ib); + r = radeon_ring_ib_parse(rdev, parser->ring, parser->ib); if (r) { return r; } @@ -472,44 +479,34 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, if ((rdev->family >= CHIP_TAHITI) && (parser->chunk_const_ib_idx != -1)) { - parser->const_ib.vm_id = vm->id; + parser->const_ib->vm_id = vm->id; /* ib pool is bind at 0 in virtual address space to gpu_addr is the * offset inside the pool bo */ - parser->const_ib.gpu_addr = parser->const_ib.sa_bo->soffset; - r = radeon_ib_schedule(rdev, &parser->const_ib); + parser->const_ib->gpu_addr = parser->const_ib->sa_bo.offset; + r = radeon_ib_schedule(rdev, parser->const_ib); if (r) goto out; } - parser->ib.vm_id = vm->id; + parser->ib->vm_id = vm->id; /* ib pool is bind at 0 in virtual address space to gpu_addr is the * offset inside the pool bo */ - parser->ib.gpu_addr = parser->ib.sa_bo->soffset; - parser->ib.is_const_ib = false; - r = radeon_ib_schedule(rdev, &parser->ib); + parser->ib->gpu_addr = parser->ib->sa_bo.offset; + parser->ib->is_const_ib = false; + r = radeon_ib_schedule(rdev, parser->ib); out: if (!r) { if (vm->fence) { radeon_fence_unref(&vm->fence); } - vm->fence = radeon_fence_ref(parser->ib.fence); + vm->fence = radeon_fence_ref(parser->ib->fence); } mutex_unlock(&fpriv->vm.mutex); return r; } -static int radeon_cs_handle_lockup(struct radeon_device *rdev, int r) -{ - if (r == -EDEADLK) { - r = radeon_gpu_reset(rdev); - if (!r) - r = -EAGAIN; - } - return r; -} - int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { struct radeon_device *rdev = dev->dev_private; @@ -531,7 +528,6 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (r) { DRM_ERROR("Failed to initialize parser !\n"); radeon_cs_parser_fini(&parser, r); - r = radeon_cs_handle_lockup(rdev, r); radeon_mutex_unlock(&rdev->cs_mutex); return r; } @@ -540,7 +536,6 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) if (r != -ERESTARTSYS) DRM_ERROR("Failed to parse relocation %d!\n", r); radeon_cs_parser_fini(&parser, r); - r = radeon_cs_handle_lockup(rdev, r); radeon_mutex_unlock(&rdev->cs_mutex); return r; } @@ -554,7 +549,6 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) } out: radeon_cs_parser_fini(&parser, r); - r = radeon_cs_handle_lockup(rdev, r); radeon_mutex_unlock(&rdev->cs_mutex); return r; } @@ -572,7 +566,7 @@ int radeon_cs_finish_pages(struct radeon_cs_parser *p) size = PAGE_SIZE; } - if (DRM_COPY_FROM_USER(p->ib.ptr + (i * (PAGE_SIZE/4)), + if (DRM_COPY_FROM_USER(p->ib->ptr + (i * (PAGE_SIZE/4)), ibc->user_ptr + (i * PAGE_SIZE), size)) return -EFAULT; @@ -589,7 +583,7 @@ int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx) bool copy1 = (p->rdev->flags & RADEON_IS_AGP) ? false : true; for (i = ibc->last_copied_page + 1; i < pg_idx; i++) { - if (DRM_COPY_FROM_USER(p->ib.ptr + (i * (PAGE_SIZE/4)), + if (DRM_COPY_FROM_USER(p->ib->ptr + (i * (PAGE_SIZE/4)), ibc->user_ptr + (i * PAGE_SIZE), PAGE_SIZE)) { p->parser_error = -EFAULT; @@ -605,7 +599,7 @@ int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx) new_page = ibc->kpage_idx[0] < ibc->kpage_idx[1] ? 0 : 1; if (copy1) - ibc->kpage[new_page] = p->ib.ptr + (pg_idx * (PAGE_SIZE / 4)); + ibc->kpage[new_page] = p->ib->ptr + (pg_idx * (PAGE_SIZE / 4)); if (DRM_COPY_FROM_USER(ibc->kpage[new_page], ibc->user_ptr + (pg_idx * PAGE_SIZE), @@ -616,7 +610,7 @@ int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx) /* copy to IB for non single case */ if (!copy1) - memcpy((void *)(p->ib.ptr+(pg_idx*(PAGE_SIZE/4))), ibc->kpage[new_page], size); + memcpy((void *)(p->ib->ptr+(pg_idx*(PAGE_SIZE/4))), ibc->kpage[new_page], size); ibc->last_copied_page = pg_idx; ibc->kpage_idx[new_page] = pg_idx; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index e1bc7e96f29c..0fb4f8993cae 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -225,9 +225,9 @@ int radeon_wb_init(struct radeon_device *rdev) /* disable event_write fences */ rdev->wb.use_event = false; /* disabled via module param */ - if (radeon_no_wb == 1) { + if (radeon_no_wb == 1) rdev->wb.enabled = false; - } else { + else { if (rdev->flags & RADEON_IS_AGP) { /* often unreliable on AGP */ rdev->wb.enabled = false; @@ -237,13 +237,12 @@ int radeon_wb_init(struct radeon_device *rdev) } else { rdev->wb.enabled = true; /* event_write fences are only available on r600+ */ - if (rdev->family >= CHIP_R600) { + if (rdev->family >= CHIP_R600) rdev->wb.use_event = true; - } } } - /* always use writeback/events on NI, APUs */ - if (rdev->family >= CHIP_PALM) { + /* always use writeback/events on NI */ + if (ASIC_IS_DCE5(rdev)) { rdev->wb.enabled = true; rdev->wb.use_event = true; } @@ -715,6 +714,7 @@ int radeon_device_init(struct radeon_device *rdev, rdev->is_atom_bios = false; rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT; rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; + rdev->gpu_lockup = false; rdev->accel_working = false; DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", @@ -724,16 +724,21 @@ int radeon_device_init(struct radeon_device *rdev, /* mutex initialization are all done here so we * can recall function without having locking issues */ radeon_mutex_init(&rdev->cs_mutex); - mutex_init(&rdev->ring_lock); + radeon_mutex_init(&rdev->ib_pool.mutex); + for (i = 0; i < RADEON_NUM_RINGS; ++i) + mutex_init(&rdev->ring[i].mutex); mutex_init(&rdev->dc_hw_i2c_mutex); if (rdev->family >= CHIP_R600) spin_lock_init(&rdev->ih.lock); mutex_init(&rdev->gem.mutex); mutex_init(&rdev->pm.mutex); mutex_init(&rdev->vram_mutex); + rwlock_init(&rdev->fence_lock); + rwlock_init(&rdev->semaphore_drv.lock); INIT_LIST_HEAD(&rdev->gem.objects); init_waitqueue_head(&rdev->irq.vblank_queue); init_waitqueue_head(&rdev->irq.idle_queue); + INIT_LIST_HEAD(&rdev->semaphore_drv.bo); /* initialize vm here */ rdev->vm_manager.use_bitmap = 1; rdev->vm_manager.max_pfn = 1 << 20; @@ -909,12 +914,9 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) } /* evict vram memory */ radeon_bo_evict_vram(rdev); - - mutex_lock(&rdev->ring_lock); /* wait for gpu to finish processing current batch */ for (i = 0; i < RADEON_NUM_RINGS; i++) - radeon_fence_wait_empty_locked(rdev, i); - mutex_unlock(&rdev->ring_lock); + radeon_fence_wait_last(rdev, i); radeon_save_bios_scratch_regs(rdev); @@ -985,6 +987,9 @@ int radeon_gpu_reset(struct radeon_device *rdev) int r; int resched; + /* Prevent CS ioctl from interfering */ + radeon_mutex_lock(&rdev->cs_mutex); + radeon_save_bios_scratch_regs(rdev); /* block TTM */ resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); @@ -999,6 +1004,8 @@ int radeon_gpu_reset(struct radeon_device *rdev) ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched); } + radeon_mutex_unlock(&rdev->cs_mutex); + if (r) { /* bad news, how to tell it to userspace ? */ dev_info(rdev->dev, "GPU reset failed\n"); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_display.c b/trunk/drivers/gpu/drm/radeon/radeon_display.c index 0a1d4bd65edc..8086c96e0b06 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_display.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_display.c @@ -533,7 +533,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index) radeon_legacy_init_crtc(dev, radeon_crtc); } -static const char *encoder_names[37] = { +static const char *encoder_names[36] = { "NONE", "INTERNAL_LVDS", "INTERNAL_TMDS1", @@ -570,7 +570,6 @@ static const char *encoder_names[37] = { "INTERNAL_UNIPHY2", "NUTMEG", "TRAVIS", - "INTERNAL_VCE" }; static const char *connector_names[15] = { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index e62e56a57ee4..ef7bb3f6ecae 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -128,7 +128,6 @@ int radeon_disp_priority = 0; int radeon_hw_i2c = 0; int radeon_pcie_gen2 = 0; int radeon_msi = -1; -int radeon_lockup_timeout = 10000; MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); module_param_named(no_wb, radeon_no_wb, int, 0444); @@ -178,9 +177,6 @@ module_param_named(pcie_gen2, radeon_pcie_gen2, int, 0444); MODULE_PARM_DESC(msi, "MSI support (1 = enable, 0 = disable, -1 = auto)"); module_param_named(msi, radeon_msi, int, 0444); -MODULE_PARM_DESC(lockup_timeout, "GPU lockup timeout in ms (defaul 10000 = 10 seconds, 0 = disable)"); -module_param_named(lockup_timeout, radeon_lockup_timeout, int, 0444); - static int radeon_suspend(struct drm_device *dev, pm_message_t state) { drm_radeon_private_t *dev_priv = dev->dev_private; diff --git a/trunk/drivers/gpu/drm/radeon/radeon_fence.c b/trunk/drivers/gpu/drm/radeon/radeon_fence.c index 11f5f402d22c..4bd36a354fbe 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_fence.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_fence.c @@ -63,82 +63,98 @@ static u32 radeon_fence_read(struct radeon_device *rdev, int ring) int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) { - /* we are protected by the ring emission mutex */ - if (fence->seq && fence->seq < RADEON_FENCE_NOTEMITED_SEQ) { + unsigned long irq_flags; + + write_lock_irqsave(&rdev->fence_lock, irq_flags); + if (fence->emitted) { + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); return 0; } - fence->seq = ++rdev->fence_drv[fence->ring].seq; - radeon_fence_ring_emit(rdev, fence->ring, fence); + fence->seq = atomic_add_return(1, &rdev->fence_drv[fence->ring].seq); + if (!rdev->ring[fence->ring].ready) + /* FIXME: cp is not running assume everythings is done right + * away + */ + radeon_fence_write(rdev, fence->seq, fence->ring); + else + radeon_fence_ring_emit(rdev, fence->ring, fence); + trace_radeon_fence_emit(rdev->ddev, fence->seq); + fence->emitted = true; + list_move_tail(&fence->list, &rdev->fence_drv[fence->ring].emitted); + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); return 0; } -void radeon_fence_process(struct radeon_device *rdev, int ring) +static bool radeon_fence_poll_locked(struct radeon_device *rdev, int ring) { - uint64_t seq, last_seq; - unsigned count_loop = 0; + struct radeon_fence *fence; + struct list_head *i, *n; + uint32_t seq; bool wake = false; + unsigned long cjiffies; - /* Note there is a scenario here for an infinite loop but it's - * very unlikely to happen. For it to happen, the current polling - * process need to be interrupted by another process and another - * process needs to update the last_seq btw the atomic read and - * xchg of the current process. - * - * More over for this to go in infinite loop there need to be - * continuously new fence signaled ie radeon_fence_read needs - * to return a different value each time for both the currently - * polling process and the other process that xchg the last_seq - * btw atomic read and xchg of the current process. And the - * value the other process set as last seq must be higher than - * the seq value we just read. Which means that current process - * need to be interrupted after radeon_fence_read and before - * atomic xchg. - * - * To be even more safe we count the number of time we loop and - * we bail after 10 loop just accepting the fact that we might - * have temporarly set the last_seq not to the true real last - * seq but to an older one. - */ - last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq); - do { - seq = radeon_fence_read(rdev, ring); - seq |= last_seq & 0xffffffff00000000LL; - if (seq < last_seq) { - seq += 0x100000000LL; + seq = radeon_fence_read(rdev, ring); + if (seq != rdev->fence_drv[ring].last_seq) { + rdev->fence_drv[ring].last_seq = seq; + rdev->fence_drv[ring].last_jiffies = jiffies; + rdev->fence_drv[ring].last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; + } else { + cjiffies = jiffies; + if (time_after(cjiffies, rdev->fence_drv[ring].last_jiffies)) { + cjiffies -= rdev->fence_drv[ring].last_jiffies; + if (time_after(rdev->fence_drv[ring].last_timeout, cjiffies)) { + /* update the timeout */ + rdev->fence_drv[ring].last_timeout -= cjiffies; + } else { + /* the 500ms timeout is elapsed we should test + * for GPU lockup + */ + rdev->fence_drv[ring].last_timeout = 1; + } + } else { + /* wrap around update last jiffies, we will just wait + * a little longer + */ + rdev->fence_drv[ring].last_jiffies = cjiffies; } - - if (seq == last_seq) { + return false; + } + n = NULL; + list_for_each(i, &rdev->fence_drv[ring].emitted) { + fence = list_entry(i, struct radeon_fence, list); + if (fence->seq == seq) { + n = i; break; } - /* If we loop over we don't want to return without - * checking if a fence is signaled as it means that the - * seq we just read is different from the previous on. - */ + } + /* all fence previous to this one are considered as signaled */ + if (n) { + i = n; + do { + n = i->prev; + list_move_tail(i, &rdev->fence_drv[ring].signaled); + fence = list_entry(i, struct radeon_fence, list); + fence->signaled = true; + i = n; + } while (i != &rdev->fence_drv[ring].emitted); wake = true; - last_seq = seq; - if ((count_loop++) > 10) { - /* We looped over too many time leave with the - * fact that we might have set an older fence - * seq then the current real last seq as signaled - * by the hw. - */ - break; - } - } while (atomic64_xchg(&rdev->fence_drv[ring].last_seq, seq) > seq); - - if (wake) { - rdev->fence_drv[ring].last_activity = jiffies; - wake_up_all(&rdev->fence_queue); } + return wake; } static void radeon_fence_destroy(struct kref *kref) { - struct radeon_fence *fence; + unsigned long irq_flags; + struct radeon_fence *fence; fence = container_of(kref, struct radeon_fence, kref); - fence->seq = RADEON_FENCE_NOTEMITED_SEQ; + write_lock_irqsave(&fence->rdev->fence_lock, irq_flags); + list_del(&fence->list); + fence->emitted = false; + write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags); + if (fence->semaphore) + radeon_semaphore_free(fence->rdev, fence->semaphore); kfree(fence); } @@ -146,342 +162,171 @@ int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence **fence, int ring) { + unsigned long irq_flags; + *fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL); if ((*fence) == NULL) { return -ENOMEM; } kref_init(&((*fence)->kref)); (*fence)->rdev = rdev; - (*fence)->seq = RADEON_FENCE_NOTEMITED_SEQ; + (*fence)->emitted = false; + (*fence)->signaled = false; + (*fence)->seq = 0; (*fence)->ring = ring; + (*fence)->semaphore = NULL; + INIT_LIST_HEAD(&(*fence)->list); + + write_lock_irqsave(&rdev->fence_lock, irq_flags); + list_add_tail(&(*fence)->list, &rdev->fence_drv[ring].created); + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); return 0; } -static bool radeon_fence_seq_signaled(struct radeon_device *rdev, - u64 seq, unsigned ring) +bool radeon_fence_signaled(struct radeon_fence *fence) { - if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) { - return true; - } - /* poll new last sequence at least once */ - radeon_fence_process(rdev, ring); - if (atomic64_read(&rdev->fence_drv[ring].last_seq) >= seq) { + unsigned long irq_flags; + bool signaled = false; + + if (!fence) return true; - } - return false; -} -bool radeon_fence_signaled(struct radeon_fence *fence) -{ - if (!fence) { + if (fence->rdev->gpu_lockup) return true; + + write_lock_irqsave(&fence->rdev->fence_lock, irq_flags); + signaled = fence->signaled; + /* if we are shuting down report all fence as signaled */ + if (fence->rdev->shutdown) { + signaled = true; } - if (fence->seq == RADEON_FENCE_NOTEMITED_SEQ) { + if (!fence->emitted) { WARN(1, "Querying an unemitted fence : %p !\n", fence); - return true; + signaled = true; } - if (fence->seq == RADEON_FENCE_SIGNALED_SEQ) { - return true; - } - if (radeon_fence_seq_signaled(fence->rdev, fence->seq, fence->ring)) { - fence->seq = RADEON_FENCE_SIGNALED_SEQ; - return true; + if (!signaled) { + radeon_fence_poll_locked(fence->rdev, fence->ring); + signaled = fence->signaled; } - return false; -} - -static int radeon_fence_wait_seq(struct radeon_device *rdev, u64 target_seq, - unsigned ring, bool intr, bool lock_ring) -{ - unsigned long timeout, last_activity; - uint64_t seq; - unsigned i; - bool signaled; - int r; - - while (target_seq > atomic64_read(&rdev->fence_drv[ring].last_seq)) { - if (!rdev->ring[ring].ready) { - return -EBUSY; - } - - timeout = jiffies - RADEON_FENCE_JIFFIES_TIMEOUT; - if (time_after(rdev->fence_drv[ring].last_activity, timeout)) { - /* the normal case, timeout is somewhere before last_activity */ - timeout = rdev->fence_drv[ring].last_activity - timeout; - } else { - /* either jiffies wrapped around, or no fence was signaled in the last 500ms - * anyway we will just wait for the minimum amount and then check for a lockup - */ - timeout = 1; - } - seq = atomic64_read(&rdev->fence_drv[ring].last_seq); - /* Save current last activity valuee, used to check for GPU lockups */ - last_activity = rdev->fence_drv[ring].last_activity; - - trace_radeon_fence_wait_begin(rdev->ddev, seq); - radeon_irq_kms_sw_irq_get(rdev, ring); - if (intr) { - r = wait_event_interruptible_timeout(rdev->fence_queue, - (signaled = radeon_fence_seq_signaled(rdev, target_seq, ring)), - timeout); - } else { - r = wait_event_timeout(rdev->fence_queue, - (signaled = radeon_fence_seq_signaled(rdev, target_seq, ring)), - timeout); - } - radeon_irq_kms_sw_irq_put(rdev, ring); - if (unlikely(r < 0)) { - return r; - } - trace_radeon_fence_wait_end(rdev->ddev, seq); - - if (unlikely(!signaled)) { - /* we were interrupted for some reason and fence - * isn't signaled yet, resume waiting */ - if (r) { - continue; - } - - /* check if sequence value has changed since last_activity */ - if (seq != atomic64_read(&rdev->fence_drv[ring].last_seq)) { - continue; - } - - if (lock_ring) { - mutex_lock(&rdev->ring_lock); - } - - /* test if somebody else has already decided that this is a lockup */ - if (last_activity != rdev->fence_drv[ring].last_activity) { - if (lock_ring) { - mutex_unlock(&rdev->ring_lock); - } - continue; - } - - if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) { - /* good news we believe it's a lockup */ - dev_warn(rdev->dev, "GPU lockup (waiting for 0x%016llx last fence id 0x%016llx)\n", - target_seq, seq); - - /* change last activity so nobody else think there is a lockup */ - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - rdev->fence_drv[i].last_activity = jiffies; - } - - /* mark the ring as not ready any more */ - rdev->ring[ring].ready = false; - if (lock_ring) { - mutex_unlock(&rdev->ring_lock); - } - return -EDEADLK; - } - - if (lock_ring) { - mutex_unlock(&rdev->ring_lock); - } - } - } - return 0; + write_unlock_irqrestore(&fence->rdev->fence_lock, irq_flags); + return signaled; } int radeon_fence_wait(struct radeon_fence *fence, bool intr) { + struct radeon_device *rdev; + unsigned long irq_flags, timeout; + u32 seq; int r; if (fence == NULL) { WARN(1, "Querying an invalid fence : %p !\n", fence); - return -EINVAL; + return 0; } - - r = radeon_fence_wait_seq(fence->rdev, fence->seq, - fence->ring, intr, true); - if (r) { - return r; + rdev = fence->rdev; + if (radeon_fence_signaled(fence)) { + return 0; } - fence->seq = RADEON_FENCE_SIGNALED_SEQ; - return 0; -} - -bool radeon_fence_any_seq_signaled(struct radeon_device *rdev, u64 *seq) -{ - unsigned i; - - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - if (seq[i] && radeon_fence_seq_signaled(rdev, seq[i], i)) { - return true; + timeout = rdev->fence_drv[fence->ring].last_timeout; +retry: + /* save current sequence used to check for GPU lockup */ + seq = rdev->fence_drv[fence->ring].last_seq; + trace_radeon_fence_wait_begin(rdev->ddev, seq); + if (intr) { + radeon_irq_kms_sw_irq_get(rdev, fence->ring); + r = wait_event_interruptible_timeout(rdev->fence_drv[fence->ring].queue, + radeon_fence_signaled(fence), timeout); + radeon_irq_kms_sw_irq_put(rdev, fence->ring); + if (unlikely(r < 0)) { + return r; } + } else { + radeon_irq_kms_sw_irq_get(rdev, fence->ring); + r = wait_event_timeout(rdev->fence_drv[fence->ring].queue, + radeon_fence_signaled(fence), timeout); + radeon_irq_kms_sw_irq_put(rdev, fence->ring); } - return false; -} - -static int radeon_fence_wait_any_seq(struct radeon_device *rdev, - u64 *target_seq, bool intr) -{ - unsigned long timeout, last_activity, tmp; - unsigned i, ring = RADEON_NUM_RINGS; - bool signaled; - int r; - - for (i = 0, last_activity = 0; i < RADEON_NUM_RINGS; ++i) { - if (!target_seq[i]) { - continue; - } - - /* use the most recent one as indicator */ - if (time_after(rdev->fence_drv[i].last_activity, last_activity)) { - last_activity = rdev->fence_drv[i].last_activity; - } - - /* For lockup detection just pick the lowest ring we are - * actively waiting for + trace_radeon_fence_wait_end(rdev->ddev, seq); + if (unlikely(!radeon_fence_signaled(fence))) { + /* we were interrupted for some reason and fence isn't + * isn't signaled yet, resume wait */ - if (i < ring) { - ring = i; + if (r) { + timeout = r; + goto retry; } - } - - /* nothing to wait for ? */ - if (ring == RADEON_NUM_RINGS) { - return 0; - } - - while (!radeon_fence_any_seq_signaled(rdev, target_seq)) { - timeout = jiffies - RADEON_FENCE_JIFFIES_TIMEOUT; - if (time_after(last_activity, timeout)) { - /* the normal case, timeout is somewhere before last_activity */ - timeout = last_activity - timeout; - } else { - /* either jiffies wrapped around, or no fence was signaled in the last 500ms - * anyway we will just wait for the minimum amount and then check for a lockup + /* don't protect read access to rdev->fence_drv[t].last_seq + * if we experiencing a lockup the value doesn't change + */ + if (seq == rdev->fence_drv[fence->ring].last_seq && + radeon_gpu_is_lockup(rdev, &rdev->ring[fence->ring])) { + /* good news we believe it's a lockup */ + printk(KERN_WARNING "GPU lockup (waiting for 0x%08X last fence id 0x%08X)\n", + fence->seq, seq); + /* FIXME: what should we do ? marking everyone + * as signaled for now */ - timeout = 1; - } - - trace_radeon_fence_wait_begin(rdev->ddev, target_seq[ring]); - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - if (target_seq[i]) { - radeon_irq_kms_sw_irq_get(rdev, i); - } - } - if (intr) { - r = wait_event_interruptible_timeout(rdev->fence_queue, - (signaled = radeon_fence_any_seq_signaled(rdev, target_seq)), - timeout); - } else { - r = wait_event_timeout(rdev->fence_queue, - (signaled = radeon_fence_any_seq_signaled(rdev, target_seq)), - timeout); - } - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - if (target_seq[i]) { - radeon_irq_kms_sw_irq_put(rdev, i); - } - } - if (unlikely(r < 0)) { - return r; - } - trace_radeon_fence_wait_end(rdev->ddev, target_seq[ring]); - - if (unlikely(!signaled)) { - /* we were interrupted for some reason and fence - * isn't signaled yet, resume waiting */ - if (r) { - continue; - } - - mutex_lock(&rdev->ring_lock); - for (i = 0, tmp = 0; i < RADEON_NUM_RINGS; ++i) { - if (time_after(rdev->fence_drv[i].last_activity, tmp)) { - tmp = rdev->fence_drv[i].last_activity; - } - } - /* test if somebody else has already decided that this is a lockup */ - if (last_activity != tmp) { - last_activity = tmp; - mutex_unlock(&rdev->ring_lock); - continue; - } - - if (radeon_ring_is_lockup(rdev, ring, &rdev->ring[ring])) { - /* good news we believe it's a lockup */ - dev_warn(rdev->dev, "GPU lockup (waiting for 0x%016llx)\n", - target_seq[ring]); - - /* change last activity so nobody else think there is a lockup */ - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - rdev->fence_drv[i].last_activity = jiffies; - } - - /* mark the ring as not ready any more */ - rdev->ring[ring].ready = false; - mutex_unlock(&rdev->ring_lock); - return -EDEADLK; - } - mutex_unlock(&rdev->ring_lock); + rdev->gpu_lockup = true; + r = radeon_gpu_reset(rdev); + if (r) + return r; + radeon_fence_write(rdev, fence->seq, fence->ring); + rdev->gpu_lockup = false; } + timeout = RADEON_FENCE_JIFFIES_TIMEOUT; + write_lock_irqsave(&rdev->fence_lock, irq_flags); + rdev->fence_drv[fence->ring].last_timeout = RADEON_FENCE_JIFFIES_TIMEOUT; + rdev->fence_drv[fence->ring].last_jiffies = jiffies; + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); + goto retry; } return 0; } -int radeon_fence_wait_any(struct radeon_device *rdev, - struct radeon_fence **fences, - bool intr) +int radeon_fence_wait_next(struct radeon_device *rdev, int ring) { - uint64_t seq[RADEON_NUM_RINGS]; - unsigned i; + unsigned long irq_flags; + struct radeon_fence *fence; int r; - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - seq[i] = 0; - - if (!fences[i]) { - continue; - } - - if (fences[i]->seq == RADEON_FENCE_SIGNALED_SEQ) { - /* something was allready signaled */ - return 0; - } - - if (fences[i]->seq < RADEON_FENCE_NOTEMITED_SEQ) { - seq[i] = fences[i]->seq; - } + if (rdev->gpu_lockup) { + return 0; } - - r = radeon_fence_wait_any_seq(rdev, seq, intr); - if (r) { - return r; + write_lock_irqsave(&rdev->fence_lock, irq_flags); + if (list_empty(&rdev->fence_drv[ring].emitted)) { + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); + return 0; } - return 0; + fence = list_entry(rdev->fence_drv[ring].emitted.next, + struct radeon_fence, list); + radeon_fence_ref(fence); + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); + r = radeon_fence_wait(fence, false); + radeon_fence_unref(&fence); + return r; } -int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) +int radeon_fence_wait_last(struct radeon_device *rdev, int ring) { - uint64_t seq; - - /* We are not protected by ring lock when reading current seq but - * it's ok as worst case is we return to early while we could have - * wait. - */ - seq = atomic64_read(&rdev->fence_drv[ring].last_seq) + 1ULL; - if (seq >= rdev->fence_drv[ring].seq) { - /* nothing to wait for, last_seq is - already the last emited fence */ - return -ENOENT; - } - return radeon_fence_wait_seq(rdev, seq, ring, false, false); -} + unsigned long irq_flags; + struct radeon_fence *fence; + int r; -int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring) -{ - /* We are not protected by ring lock when reading current seq - * but it's ok as wait empty is call from place where no more - * activity can be scheduled so there won't be concurrent access - * to seq value. - */ - return radeon_fence_wait_seq(rdev, rdev->fence_drv[ring].seq, - ring, false, false); + if (rdev->gpu_lockup) { + return 0; + } + write_lock_irqsave(&rdev->fence_lock, irq_flags); + if (list_empty(&rdev->fence_drv[ring].emitted)) { + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); + return 0; + } + fence = list_entry(rdev->fence_drv[ring].emitted.prev, + struct radeon_fence, list); + radeon_fence_ref(fence); + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); + r = radeon_fence_wait(fence, false); + radeon_fence_unref(&fence); + return r; } struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence) @@ -500,27 +345,49 @@ void radeon_fence_unref(struct radeon_fence **fence) } } -unsigned radeon_fence_count_emitted(struct radeon_device *rdev, int ring) +void radeon_fence_process(struct radeon_device *rdev, int ring) +{ + unsigned long irq_flags; + bool wake; + + write_lock_irqsave(&rdev->fence_lock, irq_flags); + wake = radeon_fence_poll_locked(rdev, ring); + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); + if (wake) { + wake_up_all(&rdev->fence_drv[ring].queue); + } +} + +int radeon_fence_count_emitted(struct radeon_device *rdev, int ring) { - uint64_t emitted; - - /* We are not protected by ring lock when reading the last sequence - * but it's ok to report slightly wrong fence count here. - */ - radeon_fence_process(rdev, ring); - emitted = rdev->fence_drv[ring].seq - atomic64_read(&rdev->fence_drv[ring].last_seq); - /* to avoid 32bits warp around */ - if (emitted > 0x10000000) { - emitted = 0x10000000; + unsigned long irq_flags; + int not_processed = 0; + + read_lock_irqsave(&rdev->fence_lock, irq_flags); + if (!rdev->fence_drv[ring].initialized) { + read_unlock_irqrestore(&rdev->fence_lock, irq_flags); + return 0; } - return (unsigned)emitted; + + if (!list_empty(&rdev->fence_drv[ring].emitted)) { + struct list_head *ptr; + list_for_each(ptr, &rdev->fence_drv[ring].emitted) { + /* count up to 3, that's enought info */ + if (++not_processed >= 3) + break; + } + } + read_unlock_irqrestore(&rdev->fence_lock, irq_flags); + return not_processed; } int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) { + unsigned long irq_flags; uint64_t index; int r; + write_lock_irqsave(&rdev->fence_lock, irq_flags); radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); if (rdev->wb.use_event) { rdev->fence_drv[ring].scratch_reg = 0; @@ -529,6 +396,7 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) r = radeon_scratch_get(rdev, &rdev->fence_drv[ring].scratch_reg); if (r) { dev_err(rdev->dev, "fence failed to get scratch register\n"); + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); return r; } index = RADEON_WB_SCRATCH_OFFSET + @@ -537,10 +405,11 @@ int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring) } rdev->fence_drv[ring].cpu_addr = &rdev->wb.wb[index/4]; rdev->fence_drv[ring].gpu_addr = rdev->wb.gpu_addr + index; - radeon_fence_write(rdev, rdev->fence_drv[ring].seq, ring); + radeon_fence_write(rdev, atomic_read(&rdev->fence_drv[ring].seq), ring); rdev->fence_drv[ring].initialized = true; - dev_info(rdev->dev, "fence driver on ring %d use gpu addr 0x%016llx and cpu addr 0x%p\n", + DRM_INFO("fence driver on ring %d use gpu addr 0x%08Lx and cpu addr 0x%p\n", ring, rdev->fence_drv[ring].gpu_addr, rdev->fence_drv[ring].cpu_addr); + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); return 0; } @@ -549,20 +418,24 @@ static void radeon_fence_driver_init_ring(struct radeon_device *rdev, int ring) rdev->fence_drv[ring].scratch_reg = -1; rdev->fence_drv[ring].cpu_addr = NULL; rdev->fence_drv[ring].gpu_addr = 0; - rdev->fence_drv[ring].seq = 0; - atomic64_set(&rdev->fence_drv[ring].last_seq, 0); - rdev->fence_drv[ring].last_activity = jiffies; + atomic_set(&rdev->fence_drv[ring].seq, 0); + INIT_LIST_HEAD(&rdev->fence_drv[ring].created); + INIT_LIST_HEAD(&rdev->fence_drv[ring].emitted); + INIT_LIST_HEAD(&rdev->fence_drv[ring].signaled); + init_waitqueue_head(&rdev->fence_drv[ring].queue); rdev->fence_drv[ring].initialized = false; } int radeon_fence_driver_init(struct radeon_device *rdev) { + unsigned long irq_flags; int ring; - init_waitqueue_head(&rdev->fence_queue); + write_lock_irqsave(&rdev->fence_lock, irq_flags); for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { radeon_fence_driver_init_ring(rdev, ring); } + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); if (radeon_debugfs_fence_init(rdev)) { dev_err(rdev->dev, "fence debugfs file creation failed\n"); } @@ -571,18 +444,19 @@ int radeon_fence_driver_init(struct radeon_device *rdev) void radeon_fence_driver_fini(struct radeon_device *rdev) { + unsigned long irq_flags; int ring; - mutex_lock(&rdev->ring_lock); for (ring = 0; ring < RADEON_NUM_RINGS; ring++) { if (!rdev->fence_drv[ring].initialized) continue; - radeon_fence_wait_empty_locked(rdev, ring); - wake_up_all(&rdev->fence_queue); + radeon_fence_wait_last(rdev, ring); + wake_up_all(&rdev->fence_drv[ring].queue); + write_lock_irqsave(&rdev->fence_lock, irq_flags); radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg); + write_unlock_irqrestore(&rdev->fence_lock, irq_flags); rdev->fence_drv[ring].initialized = false; } - mutex_unlock(&rdev->ring_lock); } @@ -595,6 +469,7 @@ static int radeon_debugfs_fence_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *)m->private; struct drm_device *dev = node->minor->dev; struct radeon_device *rdev = dev->dev_private; + struct radeon_fence *fence; int i; for (i = 0; i < RADEON_NUM_RINGS; ++i) { @@ -602,10 +477,14 @@ static int radeon_debugfs_fence_info(struct seq_file *m, void *data) continue; seq_printf(m, "--- ring %d ---\n", i); - seq_printf(m, "Last signaled fence 0x%016llx\n", - (unsigned long long)atomic64_read(&rdev->fence_drv[i].last_seq)); - seq_printf(m, "Last emitted 0x%016llx\n", - rdev->fence_drv[i].seq); + seq_printf(m, "Last signaled fence 0x%08X\n", + radeon_fence_read(rdev, i)); + if (!list_empty(&rdev->fence_drv[i].emitted)) { + fence = list_entry(rdev->fence_drv[i].emitted.prev, + struct radeon_fence, list); + seq_printf(m, "Last emitted fence %p with 0x%08X\n", + fence, fence->seq); + } } return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_gart.c b/trunk/drivers/gpu/drm/radeon/radeon_gart.c index 8e9ef3403acd..c58a036233fb 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_gart.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_gart.c @@ -326,7 +326,7 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev, rdev->vm_manager.use_bitmap &= ~(1 << vm->id); list_del_init(&vm->list); vm->id = -1; - radeon_sa_bo_free(rdev, &vm->sa_bo, NULL); + radeon_sa_bo_free(rdev, &vm->sa_bo); vm->pt = NULL; list_for_each_entry(bo_va, &vm->va, vm_list) { @@ -395,7 +395,7 @@ int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm) retry: r = radeon_sa_bo_new(rdev, &rdev->vm_manager.sa_manager, &vm->sa_bo, RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8), - RADEON_GPU_PAGE_SIZE, false); + RADEON_GPU_PAGE_SIZE); if (r) { if (list_empty(&rdev->vm_manager.lru_vm)) { return r; @@ -404,8 +404,10 @@ int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm) radeon_vm_unbind(rdev, vm_evict); goto retry; } - vm->pt = radeon_sa_bo_cpu_addr(vm->sa_bo); - vm->pt_gpu_addr = radeon_sa_bo_gpu_addr(vm->sa_bo); + vm->pt = rdev->vm_manager.sa_manager.cpu_ptr; + vm->pt += (vm->sa_bo.offset >> 3); + vm->pt_gpu_addr = rdev->vm_manager.sa_manager.gpu_addr; + vm->pt_gpu_addr += vm->sa_bo.offset; memset(vm->pt, 0, RADEON_GPU_PAGE_ALIGN(vm->last_pfn * 8)); retry_id: @@ -426,14 +428,14 @@ int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm) /* do hw bind */ r = rdev->vm_manager.funcs->bind(rdev, vm, id); if (r) { - radeon_sa_bo_free(rdev, &vm->sa_bo, NULL); + radeon_sa_bo_free(rdev, &vm->sa_bo); return r; } rdev->vm_manager.use_bitmap |= 1 << id; vm->id = id; list_add_tail(&vm->list, &rdev->vm_manager.lru_vm); - return radeon_vm_bo_update_pte(rdev, vm, rdev->ring_tmp_bo.bo, - &rdev->ring_tmp_bo.bo->tbo.mem); + return radeon_vm_bo_update_pte(rdev, vm, rdev->ib_pool.sa_manager.bo, + &rdev->ib_pool.sa_manager.bo->tbo.mem); } /* object have to be reserved */ @@ -631,7 +633,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) /* map the ib pool buffer at 0 in virtual address space, set * read only */ - r = radeon_vm_bo_add(rdev, vm, rdev->ring_tmp_bo.bo, 0, + r = radeon_vm_bo_add(rdev, vm, rdev->ib_pool.sa_manager.bo, 0, RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_SNOOPED); return r; } @@ -648,12 +650,12 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) radeon_mutex_unlock(&rdev->cs_mutex); /* remove all bo */ - r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); + r = radeon_bo_reserve(rdev->ib_pool.sa_manager.bo, false); if (!r) { - bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); + bo_va = radeon_bo_va(rdev->ib_pool.sa_manager.bo, vm); list_del_init(&bo_va->bo_list); list_del_init(&bo_va->vm_list); - radeon_bo_unreserve(rdev->ring_tmp_bo.bo); + radeon_bo_unreserve(rdev->ib_pool.sa_manager.bo); kfree(bo_va); } if (!list_empty(&vm->va)) { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_gem.c b/trunk/drivers/gpu/drm/radeon/radeon_gem.c index e15cb1fe2c39..c7008b5210f7 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_gem.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_gem.c @@ -154,17 +154,6 @@ void radeon_gem_object_close(struct drm_gem_object *obj, radeon_bo_unreserve(rbo); } -static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r) -{ - if (r == -EDEADLK) { - radeon_mutex_lock(&rdev->cs_mutex); - r = radeon_gpu_reset(rdev); - if (!r) - r = -EAGAIN; - radeon_mutex_unlock(&rdev->cs_mutex); - } - return r; -} /* * GEM ioctls. @@ -221,14 +210,12 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, args->initial_domain, false, false, &gobj); if (r) { - r = radeon_gem_handle_lockup(rdev, r); return r; } r = drm_gem_handle_create(filp, gobj, &handle); /* drop reference from allocate - handle holds it now */ drm_gem_object_unreference_unlocked(gobj); if (r) { - r = radeon_gem_handle_lockup(rdev, r); return r; } args->handle = handle; @@ -258,7 +245,6 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain); drm_gem_object_unreference_unlocked(gobj); - r = radeon_gem_handle_lockup(robj->rdev, r); return r; } @@ -315,7 +301,6 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, break; } drm_gem_object_unreference_unlocked(gobj); - r = radeon_gem_handle_lockup(robj->rdev, r); return r; } @@ -337,7 +322,6 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, if (robj->rdev->asic->ioctl_wait_idle) robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj); drm_gem_object_unreference_unlocked(gobj); - r = radeon_gem_handle_lockup(robj->rdev, r); return r; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c index 5df58d1aba06..170f1718d92a 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -149,12 +149,6 @@ static bool radeon_msi_ok(struct radeon_device *rdev) (rdev->pdev->subsystem_device == 0x01fd)) return true; - /* RV515 seems to have MSI issues where it loses - * MSI rearms occasionally. This leads to lockups and freezes. - * disable it by default. - */ - if (rdev->family == CHIP_RV515) - return false; if (rdev->flags & RADEON_IS_IGP) { /* APUs work fine with MSIs */ if (rdev->family >= CHIP_PALM) diff --git a/trunk/drivers/gpu/drm/radeon/radeon_mode.h b/trunk/drivers/gpu/drm/radeon/radeon_mode.h index 499a5fed8b26..0c3cdbd614d2 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_mode.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_mode.h @@ -210,7 +210,6 @@ enum radeon_connector_table { CT_RN50_POWER, CT_MAC_X800, CT_MAC_G5_9600, - CT_SAM440EP }; enum radeon_dvo_chip { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_object.h b/trunk/drivers/gpu/drm/radeon/radeon_object.h index befec7d12132..f9104be88d7c 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_object.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_object.h @@ -146,17 +146,6 @@ extern struct radeon_bo_va *radeon_bo_va(struct radeon_bo *rbo, /* * sub allocation */ - -static inline uint64_t radeon_sa_bo_gpu_addr(struct radeon_sa_bo *sa_bo) -{ - return sa_bo->manager->gpu_addr + sa_bo->soffset; -} - -static inline void * radeon_sa_bo_cpu_addr(struct radeon_sa_bo *sa_bo) -{ - return sa_bo->manager->cpu_ptr + sa_bo->soffset; -} - extern int radeon_sa_bo_manager_init(struct radeon_device *rdev, struct radeon_sa_manager *sa_manager, unsigned size, u32 domain); @@ -168,15 +157,9 @@ extern int radeon_sa_bo_manager_suspend(struct radeon_device *rdev, struct radeon_sa_manager *sa_manager); extern int radeon_sa_bo_new(struct radeon_device *rdev, struct radeon_sa_manager *sa_manager, - struct radeon_sa_bo **sa_bo, - unsigned size, unsigned align, bool block); + struct radeon_sa_bo *sa_bo, + unsigned size, unsigned align); extern void radeon_sa_bo_free(struct radeon_device *rdev, - struct radeon_sa_bo **sa_bo, - struct radeon_fence *fence); -#if defined(CONFIG_DEBUG_FS) -extern void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager, - struct seq_file *m); -#endif - + struct radeon_sa_bo *sa_bo); #endif diff --git a/trunk/drivers/gpu/drm/radeon/radeon_pm.c b/trunk/drivers/gpu/drm/radeon/radeon_pm.c index 08825548ee69..caa55d68f319 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_pm.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_pm.c @@ -252,7 +252,10 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) mutex_lock(&rdev->ddev->struct_mutex); mutex_lock(&rdev->vram_mutex); - mutex_lock(&rdev->ring_lock); + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + if (rdev->ring[i].ring_obj) + mutex_lock(&rdev->ring[i].mutex); + } /* gui idle int has issues on older chips it seems */ if (rdev->family >= CHIP_R600) { @@ -270,7 +273,13 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) } else { struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; if (ring->ready) { - radeon_fence_wait_empty_locked(rdev, RADEON_RING_TYPE_GFX_INDEX); + struct radeon_fence *fence; + radeon_ring_alloc(rdev, ring, 64); + radeon_fence_create(rdev, &fence, radeon_ring_index(rdev, ring)); + radeon_fence_emit(rdev, fence); + radeon_ring_commit(rdev, ring); + radeon_fence_wait(fence, false); + radeon_fence_unref(&fence); } } radeon_unmap_vram_bos(rdev); @@ -302,7 +311,10 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) rdev->pm.dynpm_planned_action = DYNPM_ACTION_NONE; - mutex_unlock(&rdev->ring_lock); + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + if (rdev->ring[i].ring_obj) + mutex_unlock(&rdev->ring[i].mutex); + } mutex_unlock(&rdev->vram_mutex); mutex_unlock(&rdev->ddev->struct_mutex); } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_ring.c b/trunk/drivers/gpu/drm/radeon/radeon_ring.c index a5dee76f4ebb..cc33b3d7c33b 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_ring.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_ring.c @@ -24,7 +24,6 @@ * Authors: Dave Airlie * Alex Deucher * Jerome Glisse - * Christian König */ #include #include @@ -34,10 +33,8 @@ #include "radeon.h" #include "atom.h" -/* - * IB. - */ -int radeon_debugfs_sa_init(struct radeon_device *rdev); +int radeon_debugfs_ib_init(struct radeon_device *rdev); +int radeon_debugfs_ring_init(struct radeon_device *rdev); u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) { @@ -64,37 +61,123 @@ u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) return idx_value; } -int radeon_ib_get(struct radeon_device *rdev, int ring, - struct radeon_ib *ib, unsigned size) +void radeon_ring_write(struct radeon_ring *ring, uint32_t v) { - int r; +#if DRM_DEBUG_CODE + if (ring->count_dw <= 0) { + DRM_ERROR("radeon: writting more dword to ring than expected !\n"); + } +#endif + ring->ring[ring->wptr++] = v; + ring->wptr &= ring->ptr_mask; + ring->count_dw--; + ring->ring_free_dw--; +} - r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, &ib->sa_bo, size, 256, true); - if (r) { - dev_err(rdev->dev, "failed to get a new IB (%d)\n", r); - return r; +/* + * IB. + */ +bool radeon_ib_try_free(struct radeon_device *rdev, struct radeon_ib *ib) +{ + bool done = false; + + /* only free ib which have been emited */ + if (ib->fence && ib->fence->emitted) { + if (radeon_fence_signaled(ib->fence)) { + radeon_fence_unref(&ib->fence); + radeon_sa_bo_free(rdev, &ib->sa_bo); + done = true; + } } - r = radeon_fence_create(rdev, &ib->fence, ring); + return done; +} + +int radeon_ib_get(struct radeon_device *rdev, int ring, + struct radeon_ib **ib, unsigned size) +{ + struct radeon_fence *fence; + unsigned cretry = 0; + int r = 0, i, idx; + + *ib = NULL; + /* align size on 256 bytes */ + size = ALIGN(size, 256); + + r = radeon_fence_create(rdev, &fence, ring); if (r) { - dev_err(rdev->dev, "failed to create fence for new IB (%d)\n", r); - radeon_sa_bo_free(rdev, &ib->sa_bo, NULL); + dev_err(rdev->dev, "failed to create fence for new IB\n"); return r; } - ib->ptr = radeon_sa_bo_cpu_addr(ib->sa_bo); - ib->gpu_addr = radeon_sa_bo_gpu_addr(ib->sa_bo); - ib->vm_id = 0; - ib->is_const_ib = false; - ib->semaphore = NULL; - - return 0; + radeon_mutex_lock(&rdev->ib_pool.mutex); + idx = rdev->ib_pool.head_id; +retry: + if (cretry > 5) { + dev_err(rdev->dev, "failed to get an ib after 5 retry\n"); + radeon_mutex_unlock(&rdev->ib_pool.mutex); + radeon_fence_unref(&fence); + return -ENOMEM; + } + cretry++; + for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { + radeon_ib_try_free(rdev, &rdev->ib_pool.ibs[idx]); + if (rdev->ib_pool.ibs[idx].fence == NULL) { + r = radeon_sa_bo_new(rdev, &rdev->ib_pool.sa_manager, + &rdev->ib_pool.ibs[idx].sa_bo, + size, 256); + if (!r) { + *ib = &rdev->ib_pool.ibs[idx]; + (*ib)->ptr = rdev->ib_pool.sa_manager.cpu_ptr; + (*ib)->ptr += ((*ib)->sa_bo.offset >> 2); + (*ib)->gpu_addr = rdev->ib_pool.sa_manager.gpu_addr; + (*ib)->gpu_addr += (*ib)->sa_bo.offset; + (*ib)->fence = fence; + (*ib)->vm_id = 0; + (*ib)->is_const_ib = false; + /* ib are most likely to be allocated in a ring fashion + * thus rdev->ib_pool.head_id should be the id of the + * oldest ib + */ + rdev->ib_pool.head_id = (1 + idx); + rdev->ib_pool.head_id &= (RADEON_IB_POOL_SIZE - 1); + radeon_mutex_unlock(&rdev->ib_pool.mutex); + return 0; + } + } + idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); + } + /* this should be rare event, ie all ib scheduled none signaled yet. + */ + for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { + if (rdev->ib_pool.ibs[idx].fence && rdev->ib_pool.ibs[idx].fence->emitted) { + r = radeon_fence_wait(rdev->ib_pool.ibs[idx].fence, false); + if (!r) { + goto retry; + } + /* an error happened */ + break; + } + idx = (idx + 1) & (RADEON_IB_POOL_SIZE - 1); + } + radeon_mutex_unlock(&rdev->ib_pool.mutex); + radeon_fence_unref(&fence); + return r; } -void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib *ib) +void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) { - radeon_semaphore_free(rdev, ib->semaphore, ib->fence); - radeon_sa_bo_free(rdev, &ib->sa_bo, ib->fence); - radeon_fence_unref(&ib->fence); + struct radeon_ib *tmp = *ib; + + *ib = NULL; + if (tmp == NULL) { + return; + } + radeon_mutex_lock(&rdev->ib_pool.mutex); + if (tmp->fence && !tmp->fence->emitted) { + radeon_sa_bo_free(rdev, &tmp->sa_bo); + radeon_fence_unref(&tmp->fence); + } + radeon_mutex_unlock(&rdev->ib_pool.mutex); } int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) @@ -104,14 +187,14 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) if (!ib->length_dw || !ring->ready) { /* TODO: Nothings in the ib we should report. */ - dev_err(rdev->dev, "couldn't schedule ib\n"); + DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx); return -EINVAL; } /* 64 dwords should be enough for fence too */ r = radeon_ring_lock(rdev, ring, 64); if (r) { - dev_err(rdev->dev, "scheduling IB failed (%d).\n", r); + DRM_ERROR("radeon: scheduling IB failed (%d).\n", r); return r; } radeon_ring_ib_execute(rdev, ib->fence->ring, ib); @@ -122,90 +205,74 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib) int radeon_ib_pool_init(struct radeon_device *rdev) { - int r; + struct radeon_sa_manager tmp; + int i, r; - if (rdev->ib_pool_ready) { - return 0; - } - r = radeon_sa_bo_manager_init(rdev, &rdev->ring_tmp_bo, + r = radeon_sa_bo_manager_init(rdev, &tmp, RADEON_IB_POOL_SIZE*64*1024, RADEON_GEM_DOMAIN_GTT); if (r) { return r; } - rdev->ib_pool_ready = true; - if (radeon_debugfs_sa_init(rdev)) { - dev_err(rdev->dev, "failed to register debugfs file for SA\n"); + + radeon_mutex_lock(&rdev->ib_pool.mutex); + if (rdev->ib_pool.ready) { + radeon_mutex_unlock(&rdev->ib_pool.mutex); + radeon_sa_bo_manager_fini(rdev, &tmp); + return 0; + } + + rdev->ib_pool.sa_manager = tmp; + INIT_LIST_HEAD(&rdev->ib_pool.sa_manager.sa_bo); + for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { + rdev->ib_pool.ibs[i].fence = NULL; + rdev->ib_pool.ibs[i].idx = i; + rdev->ib_pool.ibs[i].length_dw = 0; + INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].sa_bo.list); + } + rdev->ib_pool.head_id = 0; + rdev->ib_pool.ready = true; + DRM_INFO("radeon: ib pool ready.\n"); + + if (radeon_debugfs_ib_init(rdev)) { + DRM_ERROR("Failed to register debugfs file for IB !\n"); + } + if (radeon_debugfs_ring_init(rdev)) { + DRM_ERROR("Failed to register debugfs file for rings !\n"); } + radeon_mutex_unlock(&rdev->ib_pool.mutex); return 0; } void radeon_ib_pool_fini(struct radeon_device *rdev) { - if (rdev->ib_pool_ready) { - radeon_sa_bo_manager_fini(rdev, &rdev->ring_tmp_bo); - rdev->ib_pool_ready = false; + unsigned i; + + radeon_mutex_lock(&rdev->ib_pool.mutex); + if (rdev->ib_pool.ready) { + for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { + radeon_sa_bo_free(rdev, &rdev->ib_pool.ibs[i].sa_bo); + radeon_fence_unref(&rdev->ib_pool.ibs[i].fence); + } + radeon_sa_bo_manager_fini(rdev, &rdev->ib_pool.sa_manager); + rdev->ib_pool.ready = false; } + radeon_mutex_unlock(&rdev->ib_pool.mutex); } int radeon_ib_pool_start(struct radeon_device *rdev) { - return radeon_sa_bo_manager_start(rdev, &rdev->ring_tmp_bo); + return radeon_sa_bo_manager_start(rdev, &rdev->ib_pool.sa_manager); } int radeon_ib_pool_suspend(struct radeon_device *rdev) { - return radeon_sa_bo_manager_suspend(rdev, &rdev->ring_tmp_bo); -} - -int radeon_ib_ring_tests(struct radeon_device *rdev) -{ - unsigned i; - int r; - - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - struct radeon_ring *ring = &rdev->ring[i]; - - if (!ring->ready) - continue; - - r = radeon_ib_test(rdev, i, ring); - if (r) { - ring->ready = false; - - if (i == RADEON_RING_TYPE_GFX_INDEX) { - /* oh, oh, that's really bad */ - DRM_ERROR("radeon: failed testing IB on GFX ring (%d).\n", r); - rdev->accel_working = false; - return r; - - } else { - /* still not good, but we can live with it */ - DRM_ERROR("radeon: failed testing IB on ring %d (%d).\n", i, r); - } - } - } - return 0; + return radeon_sa_bo_manager_suspend(rdev, &rdev->ib_pool.sa_manager); } /* * Ring. */ -int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring); - -void radeon_ring_write(struct radeon_ring *ring, uint32_t v) -{ -#if DRM_DEBUG_CODE - if (ring->count_dw <= 0) { - DRM_ERROR("radeon: writting more dword to ring than expected !\n"); - } -#endif - ring->ring[ring->wptr++] = v; - ring->wptr &= ring->ptr_mask; - ring->count_dw--; - ring->ring_free_dw--; -} - int radeon_ring_index(struct radeon_device *rdev, struct radeon_ring *ring) { /* r1xx-r5xx only has CP ring */ @@ -252,7 +319,7 @@ int radeon_ring_alloc(struct radeon_device *rdev, struct radeon_ring *ring, unsi if (ndw < ring->ring_free_dw) { break; } - r = radeon_fence_wait_next_locked(rdev, radeon_ring_index(rdev, ring)); + r = radeon_fence_wait_next(rdev, radeon_ring_index(rdev, ring)); if (r) return r; } @@ -265,10 +332,10 @@ int radeon_ring_lock(struct radeon_device *rdev, struct radeon_ring *ring, unsig { int r; - mutex_lock(&rdev->ring_lock); + mutex_lock(&ring->mutex); r = radeon_ring_alloc(rdev, ring, ndw); if (r) { - mutex_unlock(&rdev->ring_lock); + mutex_unlock(&ring->mutex); return r; } return 0; @@ -293,85 +360,13 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *ring) void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *ring) { radeon_ring_commit(rdev, ring); - mutex_unlock(&rdev->ring_lock); -} - -void radeon_ring_undo(struct radeon_ring *ring) -{ - ring->wptr = ring->wptr_old; + mutex_unlock(&ring->mutex); } void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *ring) { - radeon_ring_undo(ring); - mutex_unlock(&rdev->ring_lock); -} - -void radeon_ring_force_activity(struct radeon_device *rdev, struct radeon_ring *ring) -{ - int r; - - radeon_ring_free_size(rdev, ring); - if (ring->rptr == ring->wptr) { - r = radeon_ring_alloc(rdev, ring, 1); - if (!r) { - radeon_ring_write(ring, ring->nop); - radeon_ring_commit(rdev, ring); - } - } -} - -void radeon_ring_lockup_update(struct radeon_ring *ring) -{ - ring->last_rptr = ring->rptr; - ring->last_activity = jiffies; -} - -/** - * radeon_ring_test_lockup() - check if ring is lockedup by recording information - * @rdev: radeon device structure - * @ring: radeon_ring structure holding ring information - * - * We don't need to initialize the lockup tracking information as we will either - * have CP rptr to a different value of jiffies wrap around which will force - * initialization of the lockup tracking informations. - * - * A possible false positivie is if we get call after while and last_cp_rptr == - * the current CP rptr, even if it's unlikely it might happen. To avoid this - * if the elapsed time since last call is bigger than 2 second than we return - * false and update the tracking information. Due to this the caller must call - * radeon_ring_test_lockup several time in less than 2sec for lockup to be reported - * the fencing code should be cautious about that. - * - * Caller should write to the ring to force CP to do something so we don't get - * false positive when CP is just gived nothing to do. - * - **/ -bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring) -{ - unsigned long cjiffies, elapsed; - uint32_t rptr; - - cjiffies = jiffies; - if (!time_after(cjiffies, ring->last_activity)) { - /* likely a wrap around */ - radeon_ring_lockup_update(ring); - return false; - } - rptr = RREG32(ring->rptr_reg); - ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; - if (ring->rptr != ring->last_rptr) { - /* CP is still working no lockup */ - radeon_ring_lockup_update(ring); - return false; - } - elapsed = jiffies_to_msecs(cjiffies - ring->last_activity); - if (radeon_lockup_timeout && elapsed >= radeon_lockup_timeout) { - dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); - return true; - } - /* give a chance to the GPU ... */ - return false; + ring->wptr = ring->wptr_old; + mutex_unlock(&ring->mutex); } int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, @@ -416,9 +411,6 @@ int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsig } ring->ptr_mask = (ring->ring_size / 4) - 1; ring->ring_free_dw = ring->ring_size / 4; - if (radeon_debugfs_ring_init(rdev, ring)) { - DRM_ERROR("Failed to register debugfs file for rings !\n"); - } return 0; } @@ -427,12 +419,11 @@ void radeon_ring_fini(struct radeon_device *rdev, struct radeon_ring *ring) int r; struct radeon_bo *ring_obj; - mutex_lock(&rdev->ring_lock); + mutex_lock(&ring->mutex); ring_obj = ring->ring_obj; - ring->ready = false; ring->ring = NULL; ring->ring_obj = NULL; - mutex_unlock(&rdev->ring_lock); + mutex_unlock(&ring->mutex); if (ring_obj) { r = radeon_bo_reserve(ring_obj, false); @@ -485,48 +476,59 @@ static struct drm_info_list radeon_debugfs_ring_info_list[] = { {"radeon_ring_cp2", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp2_index}, }; -static int radeon_debugfs_sa_info(struct seq_file *m, void *data) +static int radeon_debugfs_ib_info(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct radeon_device *rdev = dev->dev_private; + struct radeon_ib *ib = &rdev->ib_pool.ibs[*((unsigned*)node->info_ent->data)]; + unsigned i; - radeon_sa_bo_dump_debug_info(&rdev->ring_tmp_bo, m); - + if (ib == NULL) { + return 0; + } + seq_printf(m, "IB %04u\n", ib->idx); + seq_printf(m, "IB fence %p\n", ib->fence); + seq_printf(m, "IB size %05u dwords\n", ib->length_dw); + for (i = 0; i < ib->length_dw; i++) { + seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]); + } return 0; - } -static struct drm_info_list radeon_debugfs_sa_list[] = { - {"radeon_sa_info", &radeon_debugfs_sa_info, 0, NULL}, -}; - +static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE]; +static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32]; +static unsigned radeon_debugfs_ib_idx[RADEON_IB_POOL_SIZE]; #endif -int radeon_debugfs_ring_init(struct radeon_device *rdev, struct radeon_ring *ring) +int radeon_debugfs_ring_init(struct radeon_device *rdev) { #if defined(CONFIG_DEBUG_FS) - unsigned i; - for (i = 0; i < ARRAY_SIZE(radeon_debugfs_ring_info_list); ++i) { - struct drm_info_list *info = &radeon_debugfs_ring_info_list[i]; - int ridx = *(int*)radeon_debugfs_ring_info_list[i].data; - unsigned r; - - if (&rdev->ring[ridx] != ring) - continue; - - r = radeon_debugfs_add_files(rdev, info, 1); - if (r) - return r; - } -#endif + if (rdev->family >= CHIP_CAYMAN) + return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, + ARRAY_SIZE(radeon_debugfs_ring_info_list)); + else + return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, 1); +#else return 0; +#endif } -int radeon_debugfs_sa_init(struct radeon_device *rdev) +int radeon_debugfs_ib_init(struct radeon_device *rdev) { #if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, radeon_debugfs_sa_list, 1); + unsigned i; + + for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { + sprintf(radeon_debugfs_ib_names[i], "radeon_ib_%04u", i); + radeon_debugfs_ib_idx[i] = i; + radeon_debugfs_ib_list[i].name = radeon_debugfs_ib_names[i]; + radeon_debugfs_ib_list[i].show = &radeon_debugfs_ib_info; + radeon_debugfs_ib_list[i].driver_features = 0; + radeon_debugfs_ib_list[i].data = &radeon_debugfs_ib_idx[i]; + } + return radeon_debugfs_add_files(rdev, radeon_debugfs_ib_list, + RADEON_IB_POOL_SIZE); #else return 0; #endif diff --git a/trunk/drivers/gpu/drm/radeon/radeon_sa.c b/trunk/drivers/gpu/drm/radeon/radeon_sa.c index c3ac7f4c7b70..4cce47e7dc0d 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_sa.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_sa.c @@ -27,42 +27,20 @@ * Authors: * Jerome Glisse */ -/* Algorithm: - * - * We store the last allocated bo in "hole", we always try to allocate - * after the last allocated bo. Principle is that in a linear GPU ring - * progression was is after last is the oldest bo we allocated and thus - * the first one that should no longer be in use by the GPU. - * - * If it's not the case we skip over the bo after last to the closest - * done bo if such one exist. If none exist and we are not asked to - * block we report failure to allocate. - * - * If we are asked to block we wait on all the oldest fence of all - * rings. We just wait for any of those fence to complete. - */ #include "drmP.h" #include "drm.h" #include "radeon.h" -static void radeon_sa_bo_remove_locked(struct radeon_sa_bo *sa_bo); -static void radeon_sa_bo_try_free(struct radeon_sa_manager *sa_manager); - int radeon_sa_bo_manager_init(struct radeon_device *rdev, struct radeon_sa_manager *sa_manager, unsigned size, u32 domain) { - int i, r; + int r; - spin_lock_init(&sa_manager->lock); sa_manager->bo = NULL; sa_manager->size = size; sa_manager->domain = domain; - sa_manager->hole = &sa_manager->olist; - INIT_LIST_HEAD(&sa_manager->olist); - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - INIT_LIST_HEAD(&sa_manager->flist[i]); - } + INIT_LIST_HEAD(&sa_manager->sa_bo); r = radeon_bo_create(rdev, size, RADEON_GPU_PAGE_SIZE, true, RADEON_GEM_DOMAIN_CPU, &sa_manager->bo); @@ -79,15 +57,11 @@ void radeon_sa_bo_manager_fini(struct radeon_device *rdev, { struct radeon_sa_bo *sa_bo, *tmp; - if (!list_empty(&sa_manager->olist)) { - sa_manager->hole = &sa_manager->olist, - radeon_sa_bo_try_free(sa_manager); - if (!list_empty(&sa_manager->olist)) { - dev_err(rdev->dev, "sa_manager is not empty, clearing anyway\n"); - } + if (!list_empty(&sa_manager->sa_bo)) { + dev_err(rdev->dev, "sa_manager is not empty, clearing anyway\n"); } - list_for_each_entry_safe(sa_bo, tmp, &sa_manager->olist, olist) { - radeon_sa_bo_remove_locked(sa_bo); + list_for_each_entry_safe(sa_bo, tmp, &sa_manager->sa_bo, list) { + list_del_init(&sa_bo->list); } radeon_bo_unref(&sa_manager->bo); sa_manager->size = 0; @@ -139,248 +113,77 @@ int radeon_sa_bo_manager_suspend(struct radeon_device *rdev, return r; } -static void radeon_sa_bo_remove_locked(struct radeon_sa_bo *sa_bo) -{ - struct radeon_sa_manager *sa_manager = sa_bo->manager; - if (sa_manager->hole == &sa_bo->olist) { - sa_manager->hole = sa_bo->olist.prev; - } - list_del_init(&sa_bo->olist); - list_del_init(&sa_bo->flist); - radeon_fence_unref(&sa_bo->fence); - kfree(sa_bo); -} - -static void radeon_sa_bo_try_free(struct radeon_sa_manager *sa_manager) -{ - struct radeon_sa_bo *sa_bo, *tmp; - - if (sa_manager->hole->next == &sa_manager->olist) - return; - - sa_bo = list_entry(sa_manager->hole->next, struct radeon_sa_bo, olist); - list_for_each_entry_safe_from(sa_bo, tmp, &sa_manager->olist, olist) { - if (sa_bo->fence == NULL || !radeon_fence_signaled(sa_bo->fence)) { - return; - } - radeon_sa_bo_remove_locked(sa_bo); - } -} - -static inline unsigned radeon_sa_bo_hole_soffset(struct radeon_sa_manager *sa_manager) -{ - struct list_head *hole = sa_manager->hole; - - if (hole != &sa_manager->olist) { - return list_entry(hole, struct radeon_sa_bo, olist)->eoffset; - } - return 0; -} - -static inline unsigned radeon_sa_bo_hole_eoffset(struct radeon_sa_manager *sa_manager) -{ - struct list_head *hole = sa_manager->hole; - - if (hole->next != &sa_manager->olist) { - return list_entry(hole->next, struct radeon_sa_bo, olist)->soffset; - } - return sa_manager->size; -} - -static bool radeon_sa_bo_try_alloc(struct radeon_sa_manager *sa_manager, - struct radeon_sa_bo *sa_bo, - unsigned size, unsigned align) -{ - unsigned soffset, eoffset, wasted; - - soffset = radeon_sa_bo_hole_soffset(sa_manager); - eoffset = radeon_sa_bo_hole_eoffset(sa_manager); - wasted = (align - (soffset % align)) % align; - - if ((eoffset - soffset) >= (size + wasted)) { - soffset += wasted; - - sa_bo->manager = sa_manager; - sa_bo->soffset = soffset; - sa_bo->eoffset = soffset + size; - list_add(&sa_bo->olist, sa_manager->hole); - INIT_LIST_HEAD(&sa_bo->flist); - sa_manager->hole = &sa_bo->olist; - return true; - } - return false; -} - -static bool radeon_sa_bo_next_hole(struct radeon_sa_manager *sa_manager, - struct radeon_fence **fences, - unsigned *tries) -{ - struct radeon_sa_bo *best_bo = NULL; - unsigned i, soffset, best, tmp; - - /* if hole points to the end of the buffer */ - if (sa_manager->hole->next == &sa_manager->olist) { - /* try again with its beginning */ - sa_manager->hole = &sa_manager->olist; - return true; - } - - soffset = radeon_sa_bo_hole_soffset(sa_manager); - /* to handle wrap around we add sa_manager->size */ - best = sa_manager->size * 2; - /* go over all fence list and try to find the closest sa_bo - * of the current last - */ - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - struct radeon_sa_bo *sa_bo; - - if (list_empty(&sa_manager->flist[i])) { - continue; - } - - sa_bo = list_first_entry(&sa_manager->flist[i], - struct radeon_sa_bo, flist); - - if (!radeon_fence_signaled(sa_bo->fence)) { - fences[i] = sa_bo->fence; - continue; - } - - /* limit the number of tries each ring gets */ - if (tries[i] > 2) { - continue; - } - - tmp = sa_bo->soffset; - if (tmp < soffset) { - /* wrap around, pretend it's after */ - tmp += sa_manager->size; - } - tmp -= soffset; - if (tmp < best) { - /* this sa bo is the closest one */ - best = tmp; - best_bo = sa_bo; - } - } - - if (best_bo) { - ++tries[best_bo->fence->ring]; - sa_manager->hole = best_bo->olist.prev; - - /* we knew that this one is signaled, - so it's save to remote it */ - radeon_sa_bo_remove_locked(best_bo); - return true; - } - return false; -} - +/* + * Principe is simple, we keep a list of sub allocation in offset + * order (first entry has offset == 0, last entry has the highest + * offset). + * + * When allocating new object we first check if there is room at + * the end total_size - (last_object_offset + last_object_size) >= + * alloc_size. If so we allocate new object there. + * + * When there is not enough room at the end, we start waiting for + * each sub object until we reach object_offset+object_size >= + * alloc_size, this object then become the sub object we return. + * + * Alignment can't be bigger than page size + */ int radeon_sa_bo_new(struct radeon_device *rdev, struct radeon_sa_manager *sa_manager, - struct radeon_sa_bo **sa_bo, - unsigned size, unsigned align, bool block) + struct radeon_sa_bo *sa_bo, + unsigned size, unsigned align) { - struct radeon_fence *fences[RADEON_NUM_RINGS]; - unsigned tries[RADEON_NUM_RINGS]; - int i, r = -ENOMEM; + struct radeon_sa_bo *tmp; + struct list_head *head; + unsigned offset = 0, wasted = 0; BUG_ON(align > RADEON_GPU_PAGE_SIZE); BUG_ON(size > sa_manager->size); - *sa_bo = kmalloc(sizeof(struct radeon_sa_bo), GFP_KERNEL); - if ((*sa_bo) == NULL) { - return -ENOMEM; + /* no one ? */ + head = sa_manager->sa_bo.prev; + if (list_empty(&sa_manager->sa_bo)) { + goto out; } - (*sa_bo)->manager = sa_manager; - (*sa_bo)->fence = NULL; - INIT_LIST_HEAD(&(*sa_bo)->olist); - INIT_LIST_HEAD(&(*sa_bo)->flist); - spin_lock(&sa_manager->lock); - do { - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - fences[i] = NULL; - tries[i] = 0; + /* look for a hole big enough */ + offset = 0; + list_for_each_entry(tmp, &sa_manager->sa_bo, list) { + /* room before this object ? */ + if ((tmp->offset - offset) >= size) { + head = tmp->list.prev; + goto out; } - - do { - radeon_sa_bo_try_free(sa_manager); - - if (radeon_sa_bo_try_alloc(sa_manager, *sa_bo, - size, align)) { - spin_unlock(&sa_manager->lock); - return 0; - } - - /* see if we can skip over some allocations */ - } while (radeon_sa_bo_next_hole(sa_manager, fences, tries)); - - if (block) { - spin_unlock(&sa_manager->lock); - r = radeon_fence_wait_any(rdev, fences, false); - spin_lock(&sa_manager->lock); - if (r) { - /* if we have nothing to wait for we - are practically out of memory */ - if (r == -ENOENT) { - r = -ENOMEM; - } - goto out_err; - } + offset = tmp->offset + tmp->size; + wasted = offset % align; + if (wasted) { + wasted = align - wasted; } - } while (block); - -out_err: - spin_unlock(&sa_manager->lock); - kfree(*sa_bo); - *sa_bo = NULL; - return r; -} - -void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo **sa_bo, - struct radeon_fence *fence) -{ - struct radeon_sa_manager *sa_manager; - - if (sa_bo == NULL || *sa_bo == NULL) { - return; + offset += wasted; + } + /* room at the end ? */ + head = sa_manager->sa_bo.prev; + tmp = list_entry(head, struct radeon_sa_bo, list); + offset = tmp->offset + tmp->size; + wasted = offset % align; + if (wasted) { + wasted = align - wasted; + } + offset += wasted; + if ((sa_manager->size - offset) < size) { + /* failed to find somethings big enough */ + return -ENOMEM; } - sa_manager = (*sa_bo)->manager; - spin_lock(&sa_manager->lock); - if (fence && fence->seq && fence->seq < RADEON_FENCE_NOTEMITED_SEQ) { - (*sa_bo)->fence = radeon_fence_ref(fence); - list_add_tail(&(*sa_bo)->flist, - &sa_manager->flist[fence->ring]); - } else { - radeon_sa_bo_remove_locked(*sa_bo); - } - spin_unlock(&sa_manager->lock); - *sa_bo = NULL; +out: + sa_bo->manager = sa_manager; + sa_bo->offset = offset; + sa_bo->size = size; + list_add(&sa_bo->list, head); + return 0; } -#if defined(CONFIG_DEBUG_FS) -void radeon_sa_bo_dump_debug_info(struct radeon_sa_manager *sa_manager, - struct seq_file *m) +void radeon_sa_bo_free(struct radeon_device *rdev, struct radeon_sa_bo *sa_bo) { - struct radeon_sa_bo *i; - - spin_lock(&sa_manager->lock); - list_for_each_entry(i, &sa_manager->olist, olist) { - if (&i->olist == sa_manager->hole) { - seq_printf(m, ">"); - } else { - seq_printf(m, " "); - } - seq_printf(m, "[0x%08x 0x%08x] size %8d", - i->soffset, i->eoffset, i->eoffset - i->soffset); - if (i->fence) { - seq_printf(m, " protected by 0x%016llx on ring %d", - i->fence->seq, i->fence->ring); - } - seq_printf(m, "\n"); - } - spin_unlock(&sa_manager->lock); + list_del_init(&sa_bo->list); } -#endif diff --git a/trunk/drivers/gpu/drm/radeon/radeon_semaphore.c b/trunk/drivers/gpu/drm/radeon/radeon_semaphore.c index e2ace5dce117..61dd4e3c9209 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_semaphore.c @@ -31,107 +31,148 @@ #include "drm.h" #include "radeon.h" - -int radeon_semaphore_create(struct radeon_device *rdev, - struct radeon_semaphore **semaphore) +static int radeon_semaphore_add_bo(struct radeon_device *rdev) { - int r; + struct radeon_semaphore_bo *bo; + unsigned long irq_flags; + uint64_t gpu_addr; + uint32_t *cpu_ptr; + int r, i; - *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); - if (*semaphore == NULL) { + + bo = kmalloc(sizeof(struct radeon_semaphore_bo), GFP_KERNEL); + if (bo == NULL) { return -ENOMEM; } - r = radeon_sa_bo_new(rdev, &rdev->ring_tmp_bo, - &(*semaphore)->sa_bo, 8, 8, true); + INIT_LIST_HEAD(&bo->free); + INIT_LIST_HEAD(&bo->list); + bo->nused = 0; + + r = radeon_ib_get(rdev, 0, &bo->ib, RADEON_SEMAPHORE_BO_SIZE); if (r) { - kfree(*semaphore); - *semaphore = NULL; + dev_err(rdev->dev, "failed to get a bo after 5 retry\n"); + kfree(bo); return r; } - (*semaphore)->waiters = 0; - (*semaphore)->gpu_addr = radeon_sa_bo_gpu_addr((*semaphore)->sa_bo); - *((uint64_t*)radeon_sa_bo_cpu_addr((*semaphore)->sa_bo)) = 0; + gpu_addr = rdev->ib_pool.sa_manager.gpu_addr; + gpu_addr += bo->ib->sa_bo.offset; + cpu_ptr = rdev->ib_pool.sa_manager.cpu_ptr; + cpu_ptr += (bo->ib->sa_bo.offset >> 2); + for (i = 0; i < (RADEON_SEMAPHORE_BO_SIZE/8); i++) { + bo->semaphores[i].gpu_addr = gpu_addr; + bo->semaphores[i].cpu_ptr = cpu_ptr; + bo->semaphores[i].bo = bo; + list_add_tail(&bo->semaphores[i].list, &bo->free); + gpu_addr += 8; + cpu_ptr += 2; + } + write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags); + list_add_tail(&bo->list, &rdev->semaphore_drv.bo); + write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags); return 0; } -void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, - struct radeon_semaphore *semaphore) +static void radeon_semaphore_del_bo_locked(struct radeon_device *rdev, + struct radeon_semaphore_bo *bo) { - --semaphore->waiters; - radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, false); + radeon_sa_bo_free(rdev, &bo->ib->sa_bo); + radeon_fence_unref(&bo->ib->fence); + list_del(&bo->list); + kfree(bo); } -void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, - struct radeon_semaphore *semaphore) +void radeon_semaphore_shrink_locked(struct radeon_device *rdev) { - ++semaphore->waiters; - radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true); + struct radeon_semaphore_bo *bo, *n; + + if (list_empty(&rdev->semaphore_drv.bo)) { + return; + } + /* only shrink if first bo has free semaphore */ + bo = list_first_entry(&rdev->semaphore_drv.bo, struct radeon_semaphore_bo, list); + if (list_empty(&bo->free)) { + return; + } + list_for_each_entry_safe_continue(bo, n, &rdev->semaphore_drv.bo, list) { + if (bo->nused) + continue; + radeon_semaphore_del_bo_locked(rdev, bo); + } } -int radeon_semaphore_sync_rings(struct radeon_device *rdev, - struct radeon_semaphore *semaphore, - bool sync_to[RADEON_NUM_RINGS], - int dst_ring) +int radeon_semaphore_create(struct radeon_device *rdev, + struct radeon_semaphore **semaphore) { - int i = 0, r; - - mutex_lock(&rdev->ring_lock); - r = radeon_ring_alloc(rdev, &rdev->ring[dst_ring], RADEON_NUM_RINGS * 8); - if (r) { - goto error; - } + struct radeon_semaphore_bo *bo; + unsigned long irq_flags; + bool do_retry = true; + int r; - for (i = 0; i < RADEON_NUM_RINGS; ++i) { - /* no need to sync to our own or unused rings */ - if (!sync_to[i] || i == dst_ring) +retry: + *semaphore = NULL; + write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags); + list_for_each_entry(bo, &rdev->semaphore_drv.bo, list) { + if (list_empty(&bo->free)) continue; + *semaphore = list_first_entry(&bo->free, struct radeon_semaphore, list); + (*semaphore)->cpu_ptr[0] = 0; + (*semaphore)->cpu_ptr[1] = 0; + list_del(&(*semaphore)->list); + bo->nused++; + break; + } + write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags); - /* prevent GPU deadlocks */ - if (!rdev->ring[i].ready) { - dev_err(rdev->dev, "Trying to sync to a disabled ring!"); - r = -EINVAL; - goto error; - } - - r = radeon_ring_alloc(rdev, &rdev->ring[i], 8); - if (r) { - goto error; + if (*semaphore == NULL) { + if (do_retry) { + do_retry = false; + r = radeon_semaphore_add_bo(rdev); + if (r) + return r; + goto retry; } - - radeon_semaphore_emit_signal(rdev, i, semaphore); - radeon_semaphore_emit_wait(rdev, dst_ring, semaphore); - - radeon_ring_commit(rdev, &rdev->ring[i]); + return -ENOMEM; } - radeon_ring_commit(rdev, &rdev->ring[dst_ring]); - mutex_unlock(&rdev->ring_lock); - return 0; +} -error: - /* unlock all locks taken so far */ - for (--i; i >= 0; --i) { - if (sync_to[i] || i == dst_ring) { - radeon_ring_undo(&rdev->ring[i]); - } - } - radeon_ring_undo(&rdev->ring[dst_ring]); - mutex_unlock(&rdev->ring_lock); - return r; +void radeon_semaphore_emit_signal(struct radeon_device *rdev, int ring, + struct radeon_semaphore *semaphore) +{ + radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, false); +} + +void radeon_semaphore_emit_wait(struct radeon_device *rdev, int ring, + struct radeon_semaphore *semaphore) +{ + radeon_semaphore_ring_emit(rdev, ring, &rdev->ring[ring], semaphore, true); } void radeon_semaphore_free(struct radeon_device *rdev, - struct radeon_semaphore *semaphore, - struct radeon_fence *fence) + struct radeon_semaphore *semaphore) { - if (semaphore == NULL) { - return; - } - if (semaphore->waiters > 0) { - dev_err(rdev->dev, "semaphore %p has more waiters than signalers," - " hardware lockup imminent!\n", semaphore); + unsigned long irq_flags; + + write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags); + semaphore->bo->nused--; + list_add_tail(&semaphore->list, &semaphore->bo->free); + radeon_semaphore_shrink_locked(rdev); + write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags); +} + +void radeon_semaphore_driver_fini(struct radeon_device *rdev) +{ + struct radeon_semaphore_bo *bo, *n; + unsigned long irq_flags; + + write_lock_irqsave(&rdev->semaphore_drv.lock, irq_flags); + /* we force to free everything */ + list_for_each_entry_safe(bo, n, &rdev->semaphore_drv.bo, list) { + if (!list_empty(&bo->free)) { + dev_err(rdev->dev, "still in use semaphore\n"); + } + radeon_semaphore_del_bo_locked(rdev, bo); } - radeon_sa_bo_free(rdev, &semaphore->sa_bo, fence); - kfree(semaphore); + write_unlock_irqrestore(&rdev->semaphore_drv.lock, irq_flags); } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_test.c b/trunk/drivers/gpu/drm/radeon/radeon_test.c index b05738762790..dc5dcf483aa3 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_test.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_test.c @@ -317,7 +317,7 @@ void radeon_test_ring_sync(struct radeon_device *rdev, out_cleanup: if (semaphore) - radeon_semaphore_free(rdev, semaphore, NULL); + radeon_semaphore_free(rdev, semaphore); if (fence1) radeon_fence_unref(&fence1); @@ -437,7 +437,7 @@ void radeon_test_ring_sync2(struct radeon_device *rdev, out_cleanup: if (semaphore) - radeon_semaphore_free(rdev, semaphore, NULL); + radeon_semaphore_free(rdev, semaphore); if (fenceA) radeon_fence_unref(&fenceA); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_ttm.c b/trunk/drivers/gpu/drm/radeon/radeon_ttm.c index 0f6aee8aa152..f493c6403af5 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_ttm.c @@ -222,9 +222,8 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, { struct radeon_device *rdev; uint64_t old_start, new_start; - struct radeon_fence *fence, *old_fence; - struct radeon_semaphore *sem = NULL; - int r; + struct radeon_fence *fence; + int r, i; rdev = radeon_get_rdev(bo->bdev); r = radeon_fence_create(rdev, &fence, radeon_copy_ring_index(rdev)); @@ -243,7 +242,6 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, break; default: DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); - radeon_fence_unref(&fence); return -EINVAL; } switch (new_mem->mem_type) { @@ -255,36 +253,42 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, break; default: DRM_ERROR("Unknown placement %d\n", old_mem->mem_type); - radeon_fence_unref(&fence); return -EINVAL; } if (!rdev->ring[radeon_copy_ring_index(rdev)].ready) { DRM_ERROR("Trying to move memory with ring turned off.\n"); - radeon_fence_unref(&fence); return -EINVAL; } BUILD_BUG_ON((PAGE_SIZE % RADEON_GPU_PAGE_SIZE) != 0); /* sync other rings */ - old_fence = bo->sync_obj; - if (old_fence && old_fence->ring != fence->ring - && !radeon_fence_signaled(old_fence)) { - bool sync_to_ring[RADEON_NUM_RINGS] = { }; - sync_to_ring[old_fence->ring] = true; - - r = radeon_semaphore_create(rdev, &sem); - if (r) { - radeon_fence_unref(&fence); - return r; - } + if (rdev->family >= CHIP_R600) { + for (i = 0; i < RADEON_NUM_RINGS; ++i) { + /* no need to sync to our own or unused rings */ + if (i == radeon_copy_ring_index(rdev) || !rdev->ring[i].ready) + continue; + + if (!fence->semaphore) { + r = radeon_semaphore_create(rdev, &fence->semaphore); + /* FIXME: handle semaphore error */ + if (r) + continue; + } - r = radeon_semaphore_sync_rings(rdev, sem, - sync_to_ring, fence->ring); - if (r) { - radeon_semaphore_free(rdev, sem, NULL); - radeon_fence_unref(&fence); - return r; + r = radeon_ring_lock(rdev, &rdev->ring[i], 3); + /* FIXME: handle ring lock error */ + if (r) + continue; + radeon_semaphore_emit_signal(rdev, i, fence->semaphore); + radeon_ring_unlock_commit(rdev, &rdev->ring[i]); + + r = radeon_ring_lock(rdev, &rdev->ring[radeon_copy_ring_index(rdev)], 3); + /* FIXME: handle ring lock error */ + if (r) + continue; + radeon_semaphore_emit_wait(rdev, radeon_copy_ring_index(rdev), fence->semaphore); + radeon_ring_unlock_commit(rdev, &rdev->ring[radeon_copy_ring_index(rdev)]); } } @@ -294,7 +298,6 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, /* FIXME: handle copy error */ r = ttm_bo_move_accel_cleanup(bo, (void *)fence, NULL, evict, no_wait_reserve, no_wait_gpu, new_mem); - radeon_semaphore_free(rdev, sem, fence); radeon_fence_unref(&fence); return r; } diff --git a/trunk/drivers/gpu/drm/radeon/rs400.c b/trunk/drivers/gpu/drm/radeon/rs400.c index a464eb5e2df2..4cf381b3a6d8 100644 --- a/trunk/drivers/gpu/drm/radeon/rs400.c +++ b/trunk/drivers/gpu/drm/radeon/rs400.c @@ -430,9 +430,12 @@ static int rs400_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_ring_tests(rdev); - if (r) + r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + if (r) { + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; + } return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/rs600.c b/trunk/drivers/gpu/drm/radeon/rs600.c index 25f9eef12c42..10706c66b84b 100644 --- a/trunk/drivers/gpu/drm/radeon/rs600.c +++ b/trunk/drivers/gpu/drm/radeon/rs600.c @@ -396,6 +396,7 @@ int rs600_asic_reset(struct radeon_device *rdev) /* Check if GPU is idle */ if (G_000E40_GA_BUSY(status) || G_000E40_VAP_BUSY(status)) { dev_err(rdev->dev, "failed to reset GPU\n"); + rdev->gpu_lockup = true; ret = -1; } else dev_info(rdev->dev, "GPU reset succeed\n"); @@ -918,9 +919,12 @@ static int rs600_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_ring_tests(rdev); - if (r) + r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + if (r) { + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; + } return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/rs690.c b/trunk/drivers/gpu/drm/radeon/rs690.c index 3277ddecfe9f..f2c3b9d75f18 100644 --- a/trunk/drivers/gpu/drm/radeon/rs690.c +++ b/trunk/drivers/gpu/drm/radeon/rs690.c @@ -647,9 +647,12 @@ static int rs690_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_ring_tests(rdev); - if (r) + r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + if (r) { + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; + } return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/rv515.c b/trunk/drivers/gpu/drm/radeon/rv515.c index 7f08cedb5333..d8d78fe17946 100644 --- a/trunk/drivers/gpu/drm/radeon/rv515.c +++ b/trunk/drivers/gpu/drm/radeon/rv515.c @@ -412,10 +412,12 @@ static int rv515_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_ring_tests(rdev); - if (r) + r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + if (r) { + dev_err(rdev->dev, "failed testing IB (%d).\n", r); + rdev->accel_working = false; return r; - + } return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/rv770.c b/trunk/drivers/gpu/drm/radeon/rv770.c index 40f82e22a621..c62ae4be3845 100644 --- a/trunk/drivers/gpu/drm/radeon/rv770.c +++ b/trunk/drivers/gpu/drm/radeon/rv770.c @@ -969,7 +969,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) } if (rdev->flags & RADEON_IS_AGP) { size_bf = mc->gtt_start; - size_af = 0xFFFFFFFF - mc->gtt_end; + size_af = 0xFFFFFFFF - mc->gtt_end + 1; if (size_bf > size_af) { if (mc->mc_vram_size > size_bf) { dev_warn(rdev->dev, "limiting VRAM\n"); @@ -983,7 +983,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) mc->real_vram_size = size_af; mc->mc_vram_size = size_af; } - mc->vram_start = mc->gtt_end + 1; + mc->vram_start = mc->gtt_end; } mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", @@ -1114,9 +1114,12 @@ static int rv770_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_ib_ring_tests(rdev); - if (r) + r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); + if (r) { + dev_err(rdev->dev, "IB test failed (%d).\n", r); + rdev->accel_working = false; return r; + } return 0; } @@ -1278,6 +1281,7 @@ void rv770_fini(struct radeon_device *rdev) rv770_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); radeon_gem_fini(rdev); + radeon_semaphore_driver_fini(rdev); radeon_fence_driver_fini(rdev); radeon_agp_fini(rdev); radeon_bo_fini(rdev); diff --git a/trunk/drivers/gpu/drm/radeon/si.c b/trunk/drivers/gpu/drm/radeon/si.c index be3b9fd6c931..14919e1539fa 100644 --- a/trunk/drivers/gpu/drm/radeon/si.c +++ b/trunk/drivers/gpu/drm/radeon/si.c @@ -2217,6 +2217,8 @@ bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) u32 srbm_status; u32 grbm_status, grbm_status2; u32 grbm_status_se0, grbm_status_se1; + struct r100_gpu_lockup *lockup = &rdev->config.si.lockup; + int r; srbm_status = RREG32(SRBM_STATUS); grbm_status = RREG32(GRBM_STATUS); @@ -2224,12 +2226,20 @@ bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) grbm_status_se0 = RREG32(GRBM_STATUS_SE0); grbm_status_se1 = RREG32(GRBM_STATUS_SE1); if (!(grbm_status & GUI_ACTIVE)) { - radeon_ring_lockup_update(ring); + r100_gpu_lockup_update(lockup, ring); return false; } /* force CP activities */ - radeon_ring_force_activity(rdev, ring); - return radeon_ring_test_lockup(rdev, ring); + r = radeon_ring_lock(rdev, ring, 2); + if (!r) { + /* PACKET2 NOP */ + radeon_ring_write(ring, 0x80000000); + radeon_ring_write(ring, 0x80000000); + radeon_ring_unlock_commit(rdev, ring); + } + /* XXX deal with CP0,1,2 */ + ring->rptr = RREG32(ring->rptr_reg); + return r100_gpu_cp_is_lockup(rdev, lockup, ring); } static int si_gpu_soft_reset(struct radeon_device *rdev) @@ -2989,8 +2999,8 @@ int si_rlc_init(struct radeon_device *rdev) } r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.save_restore_gpu_addr); - radeon_bo_unreserve(rdev->rlc.save_restore_obj); if (r) { + radeon_bo_unreserve(rdev->rlc.save_restore_obj); dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r); si_rlc_fini(rdev); return r; @@ -3013,8 +3023,9 @@ int si_rlc_init(struct radeon_device *rdev) } r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.clear_state_gpu_addr); - radeon_bo_unreserve(rdev->rlc.clear_state_obj); if (r) { + + radeon_bo_unreserve(rdev->rlc.clear_state_obj); dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r); si_rlc_fini(rdev); return r; @@ -4109,6 +4120,7 @@ void si_fini(struct radeon_device *rdev) si_pcie_gart_fini(rdev); r600_vram_scratch_fini(rdev); radeon_gem_fini(rdev); + radeon_semaphore_driver_fini(rdev); radeon_fence_driver_fini(rdev); radeon_bo_fini(rdev); radeon_atombios_fini(rdev); diff --git a/trunk/drivers/hid/Kconfig b/trunk/drivers/hid/Kconfig index ffddcba32af6..a3d033252995 100644 --- a/trunk/drivers/hid/Kconfig +++ b/trunk/drivers/hid/Kconfig @@ -34,7 +34,7 @@ config HID config HID_BATTERY_STRENGTH bool depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY - default n + default y config HIDRAW bool "/dev/hidraw raw HID device support" diff --git a/trunk/drivers/hid/hid-tivo.c b/trunk/drivers/hid/hid-tivo.c index 9f85f827607f..de47039c708c 100644 --- a/trunk/drivers/hid/hid-tivo.c +++ b/trunk/drivers/hid/hid-tivo.c @@ -62,7 +62,7 @@ static int tivo_input_mapping(struct hid_device *hdev, struct hid_input *hi, static const struct hid_device_id tivo_devices[] = { /* TiVo Slide Bluetooth remote, pairs with a Broadcom dongle */ - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, + { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE_BT) }, { HID_USB_DEVICE(USB_VENDOR_ID_TIVO, USB_DEVICE_ID_TIVO_SLIDE) }, { } }; diff --git a/trunk/drivers/hsi/clients/hsi_char.c b/trunk/drivers/hsi/clients/hsi_char.c index 3ad91f6447d8..88a050df2389 100644 --- a/trunk/drivers/hsi/clients/hsi_char.c +++ b/trunk/drivers/hsi/clients/hsi_char.c @@ -123,7 +123,7 @@ struct hsc_client_data { static unsigned int hsc_major; /* Maximum buffer size that hsi_char will accept from userspace */ static unsigned int max_data_size = 0x1000; -module_param(max_data_size, uint, 0); +module_param(max_data_size, uint, S_IRUSR | S_IWUSR); MODULE_PARM_DESC(max_data_size, "max read/write data size [4,8..65536] (^2)"); static void hsc_add_tail(struct hsc_channel *channel, struct hsi_msg *msg, diff --git a/trunk/drivers/hsi/hsi.c b/trunk/drivers/hsi/hsi.c index 2d58f939d27f..4e2d79b79334 100644 --- a/trunk/drivers/hsi/hsi.c +++ b/trunk/drivers/hsi/hsi.c @@ -21,13 +21,26 @@ */ #include #include +#include #include +#include #include #include #include -#include #include "hsi_core.h" +static struct device_type hsi_ctrl = { + .name = "hsi_controller", +}; + +static struct device_type hsi_cl = { + .name = "hsi_client", +}; + +static struct device_type hsi_port = { + .name = "hsi_port", +}; + static ssize_t modalias_show(struct device *dev, struct device_attribute *a __maybe_unused, char *buf) { @@ -41,7 +54,8 @@ static struct device_attribute hsi_bus_dev_attrs[] = { static int hsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env) { - add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev)); + if (dev->type == &hsi_cl) + add_uevent_var(env, "MODALIAS=hsi:%s", dev_name(dev)); return 0; } @@ -66,10 +80,12 @@ static void hsi_client_release(struct device *dev) static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info) { struct hsi_client *cl; + unsigned long flags; cl = kzalloc(sizeof(*cl), GFP_KERNEL); if (!cl) return; + cl->device.type = &hsi_cl; cl->tx_cfg = info->tx_cfg; cl->rx_cfg = info->rx_cfg; cl->device.bus = &hsi_bus_type; @@ -77,11 +93,14 @@ static void hsi_new_client(struct hsi_port *port, struct hsi_board_info *info) cl->device.release = hsi_client_release; dev_set_name(&cl->device, info->name); cl->device.platform_data = info->platform_data; + spin_lock_irqsave(&port->clock, flags); + list_add_tail(&cl->link, &port->clients); + spin_unlock_irqrestore(&port->clock, flags); if (info->archdata) cl->device.archdata = *info->archdata; if (device_register(&cl->device) < 0) { pr_err("hsi: failed to register client: %s\n", info->name); - put_device(&cl->device); + kfree(cl); } } @@ -101,6 +120,13 @@ static void hsi_scan_board_info(struct hsi_controller *hsi) static int hsi_remove_client(struct device *dev, void *data __maybe_unused) { + struct hsi_client *cl = to_hsi_client(dev); + struct hsi_port *port = to_hsi_port(dev->parent); + unsigned long flags; + + spin_lock_irqsave(&port->clock, flags); + list_del(&cl->link); + spin_unlock_irqrestore(&port->clock, flags); device_unregister(dev); return 0; @@ -114,17 +140,12 @@ static int hsi_remove_port(struct device *dev, void *data __maybe_unused) return 0; } -static void hsi_controller_release(struct device *dev) +static void hsi_controller_release(struct device *dev __maybe_unused) { - struct hsi_controller *hsi = to_hsi_controller(dev); - - kfree(hsi->port); - kfree(hsi); } -static void hsi_port_release(struct device *dev) +static void hsi_port_release(struct device *dev __maybe_unused) { - kfree(to_hsi_port(dev)); } /** @@ -149,12 +170,20 @@ int hsi_register_controller(struct hsi_controller *hsi) unsigned int i; int err; - err = device_add(&hsi->device); + hsi->device.type = &hsi_ctrl; + hsi->device.bus = &hsi_bus_type; + hsi->device.release = hsi_controller_release; + err = device_register(&hsi->device); if (err < 0) return err; for (i = 0; i < hsi->num_ports; i++) { - hsi->port[i]->device.parent = &hsi->device; - err = device_add(&hsi->port[i]->device); + hsi->port[i].device.parent = &hsi->device; + hsi->port[i].device.bus = &hsi_bus_type; + hsi->port[i].device.release = hsi_port_release; + hsi->port[i].device.type = &hsi_port; + INIT_LIST_HEAD(&hsi->port[i].clients); + spin_lock_init(&hsi->port[i].clock); + err = device_register(&hsi->port[i].device); if (err < 0) goto out; } @@ -163,9 +192,7 @@ int hsi_register_controller(struct hsi_controller *hsi) return 0; out: - while (i-- > 0) - device_del(&hsi->port[i]->device); - device_del(&hsi->device); + hsi_unregister_controller(hsi); return err; } @@ -195,29 +222,6 @@ static inline int hsi_dummy_cl(struct hsi_client *cl __maybe_unused) return 0; } -/** - * hsi_put_controller - Free an HSI controller - * - * @hsi: Pointer to the HSI controller to freed - * - * HSI controller drivers should only use this function if they need - * to free their allocated hsi_controller structures before a successful - * call to hsi_register_controller. Other use is not allowed. - */ -void hsi_put_controller(struct hsi_controller *hsi) -{ - unsigned int i; - - if (!hsi) - return; - - for (i = 0; i < hsi->num_ports; i++) - if (hsi->port && hsi->port[i]) - put_device(&hsi->port[i]->device); - put_device(&hsi->device); -} -EXPORT_SYMBOL_GPL(hsi_put_controller); - /** * hsi_alloc_controller - Allocate an HSI controller and its ports * @n_ports: Number of ports on the HSI controller @@ -228,51 +232,54 @@ EXPORT_SYMBOL_GPL(hsi_put_controller); struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags) { struct hsi_controller *hsi; - struct hsi_port **port; + struct hsi_port *port; unsigned int i; if (!n_ports) return NULL; - hsi = kzalloc(sizeof(*hsi), flags); - if (!hsi) - return NULL; port = kzalloc(sizeof(*port)*n_ports, flags); - if (!port) { - kfree(hsi); + if (!port) return NULL; + hsi = kzalloc(sizeof(*hsi), flags); + if (!hsi) + goto out; + for (i = 0; i < n_ports; i++) { + dev_set_name(&port[i].device, "port%d", i); + port[i].num = i; + port[i].async = hsi_dummy_msg; + port[i].setup = hsi_dummy_cl; + port[i].flush = hsi_dummy_cl; + port[i].start_tx = hsi_dummy_cl; + port[i].stop_tx = hsi_dummy_cl; + port[i].release = hsi_dummy_cl; + mutex_init(&port[i].lock); } hsi->num_ports = n_ports; hsi->port = port; - hsi->device.release = hsi_controller_release; - device_initialize(&hsi->device); - - for (i = 0; i < n_ports; i++) { - port[i] = kzalloc(sizeof(**port), flags); - if (port[i] == NULL) - goto out; - port[i]->num = i; - port[i]->async = hsi_dummy_msg; - port[i]->setup = hsi_dummy_cl; - port[i]->flush = hsi_dummy_cl; - port[i]->start_tx = hsi_dummy_cl; - port[i]->stop_tx = hsi_dummy_cl; - port[i]->release = hsi_dummy_cl; - mutex_init(&port[i]->lock); - ATOMIC_INIT_NOTIFIER_HEAD(&port[i]->n_head); - dev_set_name(&port[i]->device, "port%d", i); - hsi->port[i]->device.release = hsi_port_release; - device_initialize(&hsi->port[i]->device); - } return hsi; out: - hsi_put_controller(hsi); + kfree(port); return NULL; } EXPORT_SYMBOL_GPL(hsi_alloc_controller); +/** + * hsi_free_controller - Free an HSI controller + * @hsi: Pointer to HSI controller + */ +void hsi_free_controller(struct hsi_controller *hsi) +{ + if (!hsi) + return; + + kfree(hsi->port); + kfree(hsi); +} +EXPORT_SYMBOL_GPL(hsi_free_controller); + /** * hsi_free_msg - Free an HSI message * @msg: Pointer to the HSI message @@ -407,67 +414,37 @@ void hsi_release_port(struct hsi_client *cl) } EXPORT_SYMBOL_GPL(hsi_release_port); -static int hsi_event_notifier_call(struct notifier_block *nb, - unsigned long event, void *data __maybe_unused) +static int hsi_start_rx(struct hsi_client *cl, void *data __maybe_unused) { - struct hsi_client *cl = container_of(nb, struct hsi_client, nb); - - (*cl->ehandler)(cl, event); + if (cl->hsi_start_rx) + (*cl->hsi_start_rx)(cl); return 0; } -/** - * hsi_register_port_event - Register a client to receive port events - * @cl: HSI client that wants to receive port events - * @cb: Event handler callback - * - * Clients should register a callback to be able to receive - * events from the ports. Registration should happen after - * claiming the port. - * The handler can be called in interrupt context. - * - * Returns -errno on error, or 0 on success. - */ -int hsi_register_port_event(struct hsi_client *cl, - void (*handler)(struct hsi_client *, unsigned long)) +static int hsi_stop_rx(struct hsi_client *cl, void *data __maybe_unused) { - struct hsi_port *port = hsi_get_port(cl); - - if (!handler || cl->ehandler) - return -EINVAL; - if (!hsi_port_claimed(cl)) - return -EACCES; - cl->ehandler = handler; - cl->nb.notifier_call = hsi_event_notifier_call; + if (cl->hsi_stop_rx) + (*cl->hsi_stop_rx)(cl); - return atomic_notifier_chain_register(&port->n_head, &cl->nb); + return 0; } -EXPORT_SYMBOL_GPL(hsi_register_port_event); -/** - * hsi_unregister_port_event - Stop receiving port events for a client - * @cl: HSI client that wants to stop receiving port events - * - * Clients should call this function before releasing their associated - * port. - * - * Returns -errno on error, or 0 on success. - */ -int hsi_unregister_port_event(struct hsi_client *cl) +static int hsi_port_for_each_client(struct hsi_port *port, void *data, + int (*fn)(struct hsi_client *cl, void *data)) { - struct hsi_port *port = hsi_get_port(cl); - int err; - - WARN_ON(!hsi_port_claimed(cl)); + struct hsi_client *cl; - err = atomic_notifier_chain_unregister(&port->n_head, &cl->nb); - if (!err) - cl->ehandler = NULL; + spin_lock(&port->clock); + list_for_each_entry(cl, &port->clients, link) { + spin_unlock(&port->clock); + (*fn)(cl, data); + spin_lock(&port->clock); + } + spin_unlock(&port->clock); - return err; + return 0; } -EXPORT_SYMBOL_GPL(hsi_unregister_port_event); /** * hsi_event -Notifies clients about port events @@ -481,12 +458,22 @@ EXPORT_SYMBOL_GPL(hsi_unregister_port_event); * Events: * HSI_EVENT_START_RX - Incoming wake line high * HSI_EVENT_STOP_RX - Incoming wake line down - * - * Returns -errno on error, or 0 on success. */ -int hsi_event(struct hsi_port *port, unsigned long event) +void hsi_event(struct hsi_port *port, unsigned int event) { - return atomic_notifier_call_chain(&port->n_head, event, NULL); + int (*fn)(struct hsi_client *cl, void *data); + + switch (event) { + case HSI_EVENT_START_RX: + fn = hsi_start_rx; + break; + case HSI_EVENT_STOP_RX: + fn = hsi_stop_rx; + break; + default: + return; + } + hsi_port_for_each_client(port, NULL, fn); } EXPORT_SYMBOL_GPL(hsi_event); diff --git a/trunk/drivers/hwmon/ad7314.c b/trunk/drivers/hwmon/ad7314.c index f85ce70d9677..ce43642ef03e 100644 --- a/trunk/drivers/hwmon/ad7314.c +++ b/trunk/drivers/hwmon/ad7314.c @@ -47,7 +47,7 @@ struct ad7314_data { u16 rx ____cacheline_aligned; }; -static int ad7314_spi_read(struct ad7314_data *chip) +static int ad7314_spi_read(struct ad7314_data *chip, s16 *data) { int ret; @@ -57,7 +57,9 @@ static int ad7314_spi_read(struct ad7314_data *chip) return ret; } - return be16_to_cpu(chip->rx); + *data = be16_to_cpu(chip->rx); + + return ret; } static ssize_t ad7314_show_temperature(struct device *dev, @@ -68,12 +70,12 @@ static ssize_t ad7314_show_temperature(struct device *dev, s16 data; int ret; - ret = ad7314_spi_read(chip); + ret = ad7314_spi_read(chip, &data); if (ret < 0) return ret; switch (spi_get_device_id(chip->spi_dev)->driver_data) { case ad7314: - data = (ret & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET; + data = (data & AD7314_TEMP_MASK) >> AD7314_TEMP_OFFSET; data = (data << 6) >> 6; return sprintf(buf, "%d\n", 250 * data); @@ -84,7 +86,7 @@ static ssize_t ad7314_show_temperature(struct device *dev, * with a sign bit - which is a 14 bit 2's complement * register. 1lsb - 31.25 milli degrees centigrade */ - data = ret & ADT7301_TEMP_MASK; + data &= ADT7301_TEMP_MASK; data = (data << 2) >> 2; return sprintf(buf, "%d\n", diff --git a/trunk/drivers/hwmon/ads1015.c b/trunk/drivers/hwmon/ads1015.c index 1958f03efd7a..7765e4f74ec5 100644 --- a/trunk/drivers/hwmon/ads1015.c +++ b/trunk/drivers/hwmon/ads1015.c @@ -59,11 +59,14 @@ struct ads1015_data { struct ads1015_channel_data channel_data[ADS1015_CHANNELS]; }; -static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) +static int ads1015_read_value(struct i2c_client *client, unsigned int channel, + int *value) { u16 config; + s16 conversion; struct ads1015_data *data = i2c_get_clientdata(client); unsigned int pga = data->channel_data[channel].pga; + int fullscale; unsigned int data_rate = data->channel_data[channel].data_rate; unsigned int conversion_time_ms; int res; @@ -75,6 +78,7 @@ static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) if (res < 0) goto err_unlock; config = res; + fullscale = fullscale_table[pga]; conversion_time_ms = DIV_ROUND_UP(1000, data_rate_table[data_rate]); /* setup and start single conversion */ @@ -101,20 +105,19 @@ static int ads1015_read_adc(struct i2c_client *client, unsigned int channel) } res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION); + if (res < 0) + goto err_unlock; + conversion = res; -err_unlock: mutex_unlock(&data->update_lock); - return res; -} -static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel, - s16 reg) -{ - struct ads1015_data *data = i2c_get_clientdata(client); - unsigned int pga = data->channel_data[channel].pga; - int fullscale = fullscale_table[pga]; + *value = DIV_ROUND_CLOSEST(conversion * fullscale, 0x7ff0); + + return 0; - return DIV_ROUND_CLOSEST(reg * fullscale, 0x7ff0); +err_unlock: + mutex_unlock(&data->update_lock); + return res; } /* sysfs callback function */ @@ -123,14 +126,12 @@ static ssize_t show_in(struct device *dev, struct device_attribute *da, { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); struct i2c_client *client = to_i2c_client(dev); + int in; int res; - int index = attr->index; - res = ads1015_read_adc(client, index); - if (res < 0) - return res; + res = ads1015_read_value(client, attr->index, &in); - return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res)); + return (res < 0) ? res : sprintf(buf, "%d\n", in); } static const struct sensor_device_attribute ads1015_in[] = { diff --git a/trunk/drivers/hwmon/coretemp.c b/trunk/drivers/hwmon/coretemp.c index b9d512331ed4..0d3141fbbc20 100644 --- a/trunk/drivers/hwmon/coretemp.c +++ b/trunk/drivers/hwmon/coretemp.c @@ -52,7 +52,7 @@ module_param_named(tjmax, force_tjmax, int, 0444); MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius"); #define BASE_SYSFS_ATTR_NO 2 /* Sysfs Base attr no for coretemp */ -#define NUM_REAL_CORES 32 /* Number of Real cores per cpu */ +#define NUM_REAL_CORES 16 /* Number of Real cores per cpu */ #define CORETEMP_NAME_LENGTH 17 /* String Length of attrs */ #define MAX_CORE_ATTRS 4 /* Maximum no of basic attrs */ #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1) @@ -709,10 +709,6 @@ static void __cpuinit put_core_offline(unsigned int cpu) indx = TO_ATTR_NO(cpu); - /* The core id is too big, just return */ - if (indx > MAX_CORE_DATA - 1) - return; - if (pdata->core_data[indx] && pdata->core_data[indx]->cpu == cpu) coretemp_remove_core(pdata, &pdev->dev, indx); diff --git a/trunk/drivers/hwmon/fam15h_power.c b/trunk/drivers/hwmon/fam15h_power.c index e8e18cab1fb8..b7494af1e4a9 100644 --- a/trunk/drivers/hwmon/fam15h_power.c +++ b/trunk/drivers/hwmon/fam15h_power.c @@ -122,41 +122,6 @@ static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4) return true; } -/* - * Newer BKDG versions have an updated recommendation on how to properly - * initialize the running average range (was: 0xE, now: 0x9). This avoids - * counter saturations resulting in bogus power readings. - * We correct this value ourselves to cope with older BIOSes. - */ -static DEFINE_PCI_DEVICE_TABLE(affected_device) = { - { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) }, - { 0 } -}; - -static void __devinit tweak_runavg_range(struct pci_dev *pdev) -{ - u32 val; - - /* - * let this quirk apply only to the current version of the - * northbridge, since future versions may change the behavior - */ - if (!pci_match_id(affected_device, pdev)) - return; - - pci_bus_read_config_dword(pdev->bus, - PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), - REG_TDP_RUNNING_AVERAGE, &val); - if ((val & 0xf) != 0xe) - return; - - val &= ~0xf; - val |= 0x9; - pci_bus_write_config_dword(pdev->bus, - PCI_DEVFN(PCI_SLOT(pdev->devfn), 5), - REG_TDP_RUNNING_AVERAGE, val); -} - static void __devinit fam15h_power_init_data(struct pci_dev *f4, struct fam15h_power_data *data) { @@ -190,13 +155,6 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev, struct device *dev; int err; - /* - * though we ignore every other northbridge, we still have to - * do the tweaking on _each_ node in MCM processors as the counters - * are working hand-in-hand - */ - tweak_runavg_range(pdev); - if (!fam15h_power_is_internal_node0(pdev)) { err = -ENODEV; goto exit; diff --git a/trunk/drivers/i2c/busses/i2c-eg20t.c b/trunk/drivers/i2c/busses/i2c-eg20t.c index c811289b61e2..f086131cb1c7 100644 --- a/trunk/drivers/i2c/busses/i2c-eg20t.c +++ b/trunk/drivers/i2c/busses/i2c-eg20t.c @@ -324,7 +324,7 @@ static s32 pch_i2c_wait_for_xfer_complete(struct i2c_algo_pch_data *adap) { long ret; ret = wait_event_timeout(pch_event, - (adap->pch_event_flag != 0), msecs_to_jiffies(1000)); + (adap->pch_event_flag != 0), msecs_to_jiffies(50)); if (ret == 0) { pch_err(adap, "timeout: %x\n", adap->pch_event_flag); @@ -1063,6 +1063,6 @@ module_exit(pch_pci_exit); MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semico ML7213/ML7223/ML7831 IOH I2C"); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Tomoya MORINAGA. "); +MODULE_AUTHOR("Tomoya MORINAGA. "); module_param(pch_i2c_speed, int, (S_IRUSR | S_IWUSR)); module_param(pch_clk, int, (S_IRUSR | S_IWUSR)); diff --git a/trunk/drivers/i2c/busses/i2c-mxs.c b/trunk/drivers/i2c/busses/i2c-mxs.c index 76b8af44f634..3d471d56bf15 100644 --- a/trunk/drivers/i2c/busses/i2c-mxs.c +++ b/trunk/drivers/i2c/busses/i2c-mxs.c @@ -227,7 +227,6 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, return -EINVAL; init_completion(&i2c->cmd_complete); - i2c->cmd_err = 0; flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; @@ -253,9 +252,6 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, if (i2c->cmd_err == -ENXIO) mxs_i2c_reset(i2c); - else - writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, - i2c->regs + MXS_I2C_QUEUECTRL_CLR); dev_dbg(i2c->dev, "Done with err=%d\n", i2c->cmd_err); @@ -303,6 +299,8 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) MXS_I2C_CTRL1_SLAVE_STOP_IRQ | MXS_I2C_CTRL1_SLAVE_IRQ)) /* MXS_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ is only for slaves */ i2c->cmd_err = -EIO; + else + i2c->cmd_err = 0; is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; @@ -386,6 +384,8 @@ static int __devexit mxs_i2c_remove(struct platform_device *pdev) if (ret) return -EBUSY; + writel(MXS_I2C_QUEUECTRL_QUEUE_RUN, + i2c->regs + MXS_I2C_QUEUECTRL_CLR); writel(MXS_I2C_CTRL0_SFTRST, i2c->regs + MXS_I2C_CTRL0_SET); platform_set_drvdata(pdev, NULL); diff --git a/trunk/drivers/i2c/busses/i2c-pnx.c b/trunk/drivers/i2c/busses/i2c-pnx.c index eb8ad538c79f..04be9f82e14b 100644 --- a/trunk/drivers/i2c/busses/i2c-pnx.c +++ b/trunk/drivers/i2c/busses/i2c-pnx.c @@ -546,7 +546,8 @@ static int i2c_pnx_controller_suspend(struct platform_device *pdev, { struct i2c_pnx_algo_data *alg_data = platform_get_drvdata(pdev); - clk_disable(alg_data->clk); + /* FIXME: shouldn't this be clk_disable? */ + clk_enable(alg_data->clk); return 0; } diff --git a/trunk/drivers/i2c/busses/i2c-tegra.c b/trunk/drivers/i2c/busses/i2c-tegra.c index 55e5ea62ccee..e978635e60f0 100644 --- a/trunk/drivers/i2c/busses/i2c-tegra.c +++ b/trunk/drivers/i2c/busses/i2c-tegra.c @@ -516,14 +516,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, if (likely(i2c_dev->msg_err == I2C_ERR_NONE)) return 0; - /* - * NACK interrupt is generated before the I2C controller generates the - * STOP condition on the bus. So wait for 2 clock periods before resetting - * the controller so that STOP condition has been delivered properly. - */ - if (i2c_dev->msg_err == I2C_ERR_NO_ACK) - udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->bus_clk_rate)); - tegra_i2c_init(i2c_dev); if (i2c_dev->msg_err == I2C_ERR_NO_ACK) { if (msg->flags & I2C_M_IGNORE_NAK) diff --git a/trunk/drivers/infiniband/core/mad.c b/trunk/drivers/infiniband/core/mad.c index b0d0bc8a6fb6..426bb7617ec6 100644 --- a/trunk/drivers/infiniband/core/mad.c +++ b/trunk/drivers/infiniband/core/mad.c @@ -1854,8 +1854,6 @@ static bool generate_unmatched_resp(struct ib_mad_private *recv, response->mad.mad.mad_hdr.method = IB_MGMT_METHOD_GET_RESP; response->mad.mad.mad_hdr.status = cpu_to_be16(IB_MGMT_MAD_STATUS_UNSUPPORTED_METHOD_ATTRIB); - if (recv->mad.mad.mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) - response->mad.mad.mad_hdr.status |= IB_SMP_DIRECTION; return true; } else { @@ -1871,7 +1869,6 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, struct ib_mad_list_head *mad_list; struct ib_mad_agent_private *mad_agent; int port_num; - int ret = IB_MAD_RESULT_SUCCESS; mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id; qp_info = mad_list->mad_queue->qp_info; @@ -1955,6 +1952,8 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, local: /* Give driver "right of first refusal" on incoming MAD */ if (port_priv->device->process_mad) { + int ret; + ret = port_priv->device->process_mad(port_priv->device, 0, port_priv->port_num, wc, &recv->grh, @@ -1982,8 +1981,7 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, * or via recv_handler in ib_mad_complete_recv() */ recv = NULL; - } else if ((ret & IB_MAD_RESULT_SUCCESS) && - generate_unmatched_resp(recv, response)) { + } else if (generate_unmatched_resp(recv, response)) { agent_send_response(&response->mad.mad, &recv->grh, wc, port_priv->device, port_num, qp_info->qp->qp_num); } diff --git a/trunk/drivers/infiniband/hw/mlx4/main.c b/trunk/drivers/infiniband/hw/mlx4/main.c index b948b6dd5d55..669673e81439 100644 --- a/trunk/drivers/infiniband/hw/mlx4/main.c +++ b/trunk/drivers/infiniband/hw/mlx4/main.c @@ -247,7 +247,7 @@ static int ib_link_query_port(struct ib_device *ibdev, u8 port, err = mlx4_MAD_IFC(to_mdev(ibdev), 1, 1, port, NULL, NULL, in_mad, out_mad); if (err) - goto out; + return err; /* Checking LinkSpeedActive for FDR-10 */ if (out_mad->data[15] & 0x1) diff --git a/trunk/drivers/input/misc/Kconfig b/trunk/drivers/input/misc/Kconfig index 7faf4a7fcaa9..2d787796bf50 100644 --- a/trunk/drivers/input/misc/Kconfig +++ b/trunk/drivers/input/misc/Kconfig @@ -380,7 +380,8 @@ config INPUT_TWL4030_VIBRA config INPUT_TWL6040_VIBRA tristate "Support for TWL6040 Vibrator" - depends on TWL6040_CORE + depends on TWL4030_CORE + select TWL6040_CORE select INPUT_FF_MEMLESS help This option enables support for TWL6040 Vibrator Driver. diff --git a/trunk/drivers/input/misc/twl6040-vibra.c b/trunk/drivers/input/misc/twl6040-vibra.c index 14e94f56cb7d..45874fed523a 100644 --- a/trunk/drivers/input/misc/twl6040-vibra.c +++ b/trunk/drivers/input/misc/twl6040-vibra.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -257,7 +257,7 @@ static SIMPLE_DEV_PM_OPS(twl6040_vibra_pm_ops, twl6040_vibra_suspend, NULL); static int __devinit twl6040_vibra_probe(struct platform_device *pdev) { - struct twl6040_vibra_data *pdata = pdev->dev.platform_data; + struct twl4030_vibra_data *pdata = pdev->dev.platform_data; struct vibra_info *info; int ret; diff --git a/trunk/drivers/input/mouse/synaptics.c b/trunk/drivers/input/mouse/synaptics.c index a4b14a41cbf4..8081a0a5d602 100644 --- a/trunk/drivers/input/mouse/synaptics.c +++ b/trunk/drivers/input/mouse/synaptics.c @@ -274,8 +274,7 @@ static int synaptics_set_advanced_gesture_mode(struct psmouse *psmouse) static unsigned char param = 0xc8; struct synaptics_data *priv = psmouse->private; - if (!(SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) || - SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c))) + if (!SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) return 0; if (psmouse_sliced_command(psmouse, SYN_QUE_MODEL)) diff --git a/trunk/drivers/leds/leds-atmel-pwm.c b/trunk/drivers/leds/leds-atmel-pwm.c index 64ad702a2ecc..800243b6037e 100644 --- a/trunk/drivers/leds/leds-atmel-pwm.c +++ b/trunk/drivers/leds/leds-atmel-pwm.c @@ -35,7 +35,7 @@ static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b) * NOTE: we reuse the platform_data structure of GPIO leds, * but repurpose its "gpio" number as a PWM channel number. */ -static int __devinit pwmled_probe(struct platform_device *pdev) +static int __init pwmled_probe(struct platform_device *pdev) { const struct gpio_led_platform_data *pdata; struct pwmled *leds; diff --git a/trunk/drivers/md/bitmap.c b/trunk/drivers/md/bitmap.c index 17e2b472e16d..97e73e555d11 100644 --- a/trunk/drivers/md/bitmap.c +++ b/trunk/drivers/md/bitmap.c @@ -1727,7 +1727,8 @@ int bitmap_create(struct mddev *mddev) bitmap->chunkshift = (ffz(~mddev->bitmap_info.chunksize) - BITMAP_BLOCK_SHIFT); - chunks = (blocks + (1 << bitmap->chunkshift) - 1) >> + /* now that chunksize and chunkshift are set, we can use these macros */ + chunks = (blocks + bitmap->chunkshift - 1) >> bitmap->chunkshift; pages = (chunks + PAGE_COUNTER_RATIO - 1) / PAGE_COUNTER_RATIO; diff --git a/trunk/drivers/md/bitmap.h b/trunk/drivers/md/bitmap.h index b44b0aba2d47..55ca5aec84e4 100644 --- a/trunk/drivers/md/bitmap.h +++ b/trunk/drivers/md/bitmap.h @@ -101,6 +101,9 @@ typedef __u16 bitmap_counter_t; #define BITMAP_BLOCK_SHIFT 9 +/* how many blocks per chunk? (this is variable) */ +#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->mddev->bitmap_info.chunksize >> BITMAP_BLOCK_SHIFT) + #endif /* diff --git a/trunk/drivers/md/dm-raid.c b/trunk/drivers/md/dm-raid.c index 68965e663248..b0ba52459ed7 100644 --- a/trunk/drivers/md/dm-raid.c +++ b/trunk/drivers/md/dm-raid.c @@ -859,7 +859,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) int ret; unsigned redundancy = 0; struct raid_dev *dev; - struct md_rdev *rdev, *tmp, *freshest; + struct md_rdev *rdev, *freshest; struct mddev *mddev = &rs->md; switch (rs->raid_type->level) { @@ -877,7 +877,7 @@ static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) } freshest = NULL; - rdev_for_each_safe(rdev, tmp, mddev) { + rdev_for_each(rdev, mddev) { if (!rdev->meta_bdev) continue; diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 477eb2e180c0..b572e1e386ce 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -7560,14 +7560,14 @@ void md_check_recovery(struct mddev *mddev) * any transients in the value of "sync_action". */ set_bit(MD_RECOVERY_RUNNING, &mddev->recovery); + clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery); /* Clear some bits that don't mean anything, but * might be left set */ clear_bit(MD_RECOVERY_INTR, &mddev->recovery); clear_bit(MD_RECOVERY_DONE, &mddev->recovery); - if (!test_and_clear_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || - test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) + if (test_bit(MD_RECOVERY_FROZEN, &mddev->recovery)) goto unlock; /* no recovery is running. * remove any failed drives, then @@ -8140,8 +8140,7 @@ static int md_notify_reboot(struct notifier_block *this, for_each_mddev(mddev, tmp) { if (mddev_trylock(mddev)) { - if (mddev->pers) - __md_stop_writes(mddev); + __md_stop_writes(mddev); mddev->safemode = 2; mddev_unlock(mddev); } diff --git a/trunk/drivers/media/common/tuners/xc5000.c b/trunk/drivers/media/common/tuners/xc5000.c index eab2ea424200..7f98984e4fad 100644 --- a/trunk/drivers/media/common/tuners/xc5000.c +++ b/trunk/drivers/media/common/tuners/xc5000.c @@ -54,7 +54,6 @@ struct xc5000_priv { struct list_head hybrid_tuner_instance_list; u32 if_khz; - u32 xtal_khz; u32 freq_hz; u32 bandwidth; u8 video_standard; @@ -215,9 +214,9 @@ static const struct xc5000_fw_cfg xc5000a_1_6_114 = { .size = 12401, }; -static const struct xc5000_fw_cfg xc5000c_41_024_5 = { - .name = "dvb-fe-xc5000c-41.024.5.fw", - .size = 16497, +static const struct xc5000_fw_cfg xc5000c_41_024_5_31875 = { + .name = "dvb-fe-xc5000c-41.024.5-31875.fw", + .size = 16503, }; static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id) @@ -227,7 +226,7 @@ static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id) case XC5000A: return &xc5000a_1_6_114; case XC5000C: - return &xc5000c_41_024_5; + return &xc5000c_41_024_5_31875; } } @@ -573,31 +572,6 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode) return found; } -static int xc_set_xtal(struct dvb_frontend *fe) -{ - struct xc5000_priv *priv = fe->tuner_priv; - int ret = XC_RESULT_SUCCESS; - - switch (priv->chip_id) { - default: - case XC5000A: - /* 32.000 MHz xtal is default */ - break; - case XC5000C: - switch (priv->xtal_khz) { - default: - case 32000: - /* 32.000 MHz xtal is default */ - break; - case 31875: - /* 31.875 MHz xtal configuration */ - ret = xc_write_reg(priv, 0x000f, 0x8081); - break; - } - break; - } - return ret; -} static int xc5000_fwupload(struct dvb_frontend *fe) { @@ -629,8 +603,6 @@ static int xc5000_fwupload(struct dvb_frontend *fe) } else { printk(KERN_INFO "xc5000: firmware uploading...\n"); ret = xc_load_i2c_sequence(fe, fw->data); - if (XC_RESULT_SUCCESS == ret) - ret = xc_set_xtal(fe); printk(KERN_INFO "xc5000: firmware upload complete...\n"); } @@ -1192,9 +1164,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe, priv->if_khz = cfg->if_khz; } - if (priv->xtal_khz == 0) - priv->xtal_khz = cfg->xtal_khz; - if (priv->radio_input == 0) priv->radio_input = cfg->radio_input; diff --git a/trunk/drivers/media/common/tuners/xc5000.h b/trunk/drivers/media/common/tuners/xc5000.h index 39a73bf01406..3396f8e02b40 100644 --- a/trunk/drivers/media/common/tuners/xc5000.h +++ b/trunk/drivers/media/common/tuners/xc5000.h @@ -34,7 +34,6 @@ struct xc5000_config { u8 i2c_address; u32 if_khz; u8 radio_input; - u32 xtal_khz; int chip_id; }; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index 0f64d7182657..39696c6a4ed7 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -1446,28 +1446,6 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) __func__); return -EINVAL; } - /* - * Get a delivery system that is compatible with DVBv3 - * NOTE: in order for this to work with softwares like Kaffeine that - * uses a DVBv5 call for DVB-S2 and a DVBv3 call to go back to - * DVB-S, drivers that support both should put the SYS_DVBS entry - * before the SYS_DVBS2, otherwise it won't switch back to DVB-S. - * The real fix is that userspace applications should not use DVBv3 - * and not trust on calling FE_SET_FRONTEND to switch the delivery - * system. - */ - ncaps = 0; - while (fe->ops.delsys[ncaps] && ncaps < MAX_DELSYS) { - if (fe->ops.delsys[ncaps] == desired_system) { - delsys = desired_system; - break; - } - ncaps++; - } - if (delsys == SYS_UNDEFINED) { - dprintk("%s() Couldn't find a delivery system that matches %d\n", - __func__, desired_system); - } } else { /* * This is a DVBv5 call. So, it likely knows the supported @@ -1516,10 +1494,9 @@ static int set_delivery_system(struct dvb_frontend *fe, u32 desired_system) __func__); return -EINVAL; } + c->delivery_system = delsys; } - c->delivery_system = delsys; - /* * The DVBv3 or DVBv5 call is requesting a different system. So, * emulation is needed. diff --git a/trunk/drivers/media/dvb/frontends/drxk_hard.c b/trunk/drivers/media/dvb/frontends/drxk_hard.c index a414b1f2b6a5..36d11756492f 100644 --- a/trunk/drivers/media/dvb/frontends/drxk_hard.c +++ b/trunk/drivers/media/dvb/frontends/drxk_hard.c @@ -1520,10 +1520,8 @@ static int scu_command(struct drxk_state *state, dprintk(1, "\n"); if ((cmd == 0) || ((parameterLen > 0) && (parameter == NULL)) || - ((resultLen > 0) && (result == NULL))) { - printk(KERN_ERR "drxk: Error %d on %s\n", status, __func__); - return status; - } + ((resultLen > 0) && (result == NULL))) + goto error; mutex_lock(&state->mutex); diff --git a/trunk/drivers/media/rc/winbond-cir.c b/trunk/drivers/media/rc/winbond-cir.c index af526586fa26..b09c5fae489b 100644 --- a/trunk/drivers/media/rc/winbond-cir.c +++ b/trunk/drivers/media/rc/winbond-cir.c @@ -1046,7 +1046,6 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) goto exit_unregister_led; } - data->dev->driver_type = RC_DRIVER_IR_RAW; data->dev->driver_name = WBCIR_NAME; data->dev->input_name = WBCIR_NAME; data->dev->input_phys = "wbcir/cir0"; diff --git a/trunk/drivers/media/video/Kconfig b/trunk/drivers/media/video/Kconfig index ce1e7ba940f6..f2479c5c0eb2 100644 --- a/trunk/drivers/media/video/Kconfig +++ b/trunk/drivers/media/video/Kconfig @@ -492,7 +492,7 @@ config VIDEO_VS6624 config VIDEO_MT9M032 tristate "MT9M032 camera sensor support" - depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on I2C && VIDEO_V4L2 select VIDEO_APTINA_PLL ---help--- This driver supports MT9M032 camera sensors from Aptina, monochrome diff --git a/trunk/drivers/media/video/mt9m032.c b/trunk/drivers/media/video/mt9m032.c index 645973c5feb0..7636672c3548 100644 --- a/trunk/drivers/media/video/mt9m032.c +++ b/trunk/drivers/media/video/mt9m032.c @@ -392,11 +392,10 @@ static int mt9m032_set_pad_format(struct v4l2_subdev *subdev, } /* Scaling is not supported, the format is thus fixed. */ - fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which); - ret = 0; + ret = mt9m032_get_pad_format(subdev, fh, fmt); done: - mutex_unlock(&sensor->lock); + mutex_lock(&sensor->lock); return ret; } diff --git a/trunk/drivers/mfd/Kconfig b/trunk/drivers/mfd/Kconfig index 11e44386fa9b..29f463cc09cb 100644 --- a/trunk/drivers/mfd/Kconfig +++ b/trunk/drivers/mfd/Kconfig @@ -268,17 +268,10 @@ config TWL6030_PWM This is used to control charging LED brightness. config TWL6040_CORE - bool "Support for TWL6040 audio codec" - depends on I2C=y && GENERIC_HARDIRQS + bool + depends on TWL4030_CORE && GENERIC_HARDIRQS select MFD_CORE - select REGMAP_I2C default n - help - Say yes here if you want support for Texas Instruments TWL6040 audio - codec. - This driver provides common support for accessing the device, - additional drivers must be enabled in order to use the - functionality of the device (audio, vibra). config MFD_STMPE bool "Support STMicroelectronics STMPE" diff --git a/trunk/drivers/mfd/asic3.c b/trunk/drivers/mfd/asic3.c index 1582c3d95257..1895cf9fab8c 100644 --- a/trunk/drivers/mfd/asic3.c +++ b/trunk/drivers/mfd/asic3.c @@ -527,9 +527,7 @@ static void asic3_gpio_set(struct gpio_chip *chip, static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset) { - struct asic3 *asic = container_of(chip, struct asic3, gpio); - - return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO; + return (offset < ASIC3_NUM_GPIOS) ? IRQ_BOARD_START + offset : -ENXIO; } static __init int asic3_gpio_probe(struct platform_device *pdev, diff --git a/trunk/drivers/mfd/omap-usb-host.c b/trunk/drivers/mfd/omap-usb-host.c index 7e96bb229724..95a2e546a489 100644 --- a/trunk/drivers/mfd/omap-usb-host.c +++ b/trunk/drivers/mfd/omap-usb-host.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -502,6 +502,19 @@ static void omap_usbhs_init(struct device *dev) pm_runtime_get_sync(dev); spin_lock_irqsave(&omap->lock, flags); + if (pdata->ehci_data->phy_reset) { + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_request_one(pdata->ehci_data->reset_gpio_port[0], + GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_request_one(pdata->ehci_data->reset_gpio_port[1], + GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); + + /* Hold the PHY in RESET for enough time till DIR is high */ + udelay(10); + } + omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); @@ -580,10 +593,39 @@ static void omap_usbhs_init(struct device *dev) usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT); } + if (pdata->ehci_data->phy_reset) { + /* Hold the PHY in RESET for enough time till + * PHY is settled and ready + */ + udelay(10); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_set_value + (pdata->ehci_data->reset_gpio_port[0], 1); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_set_value + (pdata->ehci_data->reset_gpio_port[1], 1); + } + spin_unlock_irqrestore(&omap->lock, flags); pm_runtime_put_sync(dev); } +static void omap_usbhs_deinit(struct device *dev) +{ + struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); + struct usbhs_omap_platform_data *pdata = &omap->platdata; + + if (pdata->ehci_data->phy_reset) { + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_free(pdata->ehci_data->reset_gpio_port[0]); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_free(pdata->ehci_data->reset_gpio_port[1]); + } +} + /** * usbhs_omap_probe - initialize TI-based HCDs @@ -818,6 +860,7 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev) { struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); + omap_usbhs_deinit(&pdev->dev); iounmap(omap->tll_base); iounmap(omap->uhh_base); clk_put(omap->init_60m_fclk); diff --git a/trunk/drivers/mfd/rc5t583.c b/trunk/drivers/mfd/rc5t583.c index 44afae0a69ce..99ef944c621d 100644 --- a/trunk/drivers/mfd/rc5t583.c +++ b/trunk/drivers/mfd/rc5t583.c @@ -80,6 +80,44 @@ static struct mfd_cell rc5t583_subdevs[] = { {.name = "rc5t583-key", } }; +int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_write(rc5t583->regmap, reg, val); +} + +int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + unsigned int ival; + int ret; + ret = regmap_read(rc5t583->regmap, reg, &ival); + if (!ret) + *val = (uint8_t)ival; + return ret; +} + +int rc5t583_set_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask); +} + +int rc5t583_clear_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0); +} + +int rc5t583_update(struct device *dev, unsigned int reg, + unsigned int val, unsigned int mask) +{ + struct rc5t583 *rc5t583 = dev_get_drvdata(dev); + return regmap_update_bits(rc5t583->regmap, reg, mask, val); +} + static int __rc5t583_set_ext_pwrreq1_control(struct device *dev, int id, int ext_pwr, int slots) { @@ -159,7 +197,6 @@ int rc5t583_ext_power_req_config(struct device *dev, int ds_id, ds_id, ext_pwr_req); return 0; } -EXPORT_SYMBOL(rc5t583_ext_power_req_config); static int rc5t583_clear_ext_power_req(struct rc5t583 *rc5t583, struct rc5t583_platform_data *pdata) diff --git a/trunk/drivers/mfd/twl6040-core.c b/trunk/drivers/mfd/twl6040-core.c index 2d6bedadca09..b2d8e512d3cb 100644 --- a/trunk/drivers/mfd/twl6040-core.c +++ b/trunk/drivers/mfd/twl6040-core.c @@ -30,9 +30,7 @@ #include #include #include -#include -#include -#include +#include #include #include @@ -41,7 +39,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) { int ret; - unsigned int val; + u8 val = 0; mutex_lock(&twl6040->io_mutex); /* Vibra control registers from cache */ @@ -49,7 +47,7 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) reg == TWL6040_REG_VIBCTLR)) { val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)]; } else { - ret = regmap_read(twl6040->regmap, reg, &val); + ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); if (ret < 0) { mutex_unlock(&twl6040->io_mutex); return ret; @@ -66,7 +64,7 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val) int ret; mutex_lock(&twl6040->io_mutex); - ret = regmap_write(twl6040->regmap, reg, val); + ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); /* Cache the vibra control registers */ if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR) twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val; @@ -79,9 +77,16 @@ EXPORT_SYMBOL(twl6040_reg_write); int twl6040_set_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask) { int ret; + u8 val; mutex_lock(&twl6040->io_mutex); - ret = regmap_update_bits(twl6040->regmap, reg, mask, mask); + ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); + if (ret) + goto out; + + val |= mask; + ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); +out: mutex_unlock(&twl6040->io_mutex); return ret; } @@ -90,9 +95,16 @@ EXPORT_SYMBOL(twl6040_set_bits); int twl6040_clear_bits(struct twl6040 *twl6040, unsigned int reg, u8 mask) { int ret; + u8 val; mutex_lock(&twl6040->io_mutex); - ret = regmap_update_bits(twl6040->regmap, reg, mask, 0); + ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); + if (ret) + goto out; + + val &= ~mask; + ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); +out: mutex_unlock(&twl6040->io_mutex); return ret; } @@ -482,58 +494,32 @@ static struct resource twl6040_codec_rsrc[] = { }, }; -static bool twl6040_readable_reg(struct device *dev, unsigned int reg) +static int __devinit twl6040_probe(struct platform_device *pdev) { - /* Register 0 is not readable */ - if (!reg) - return false; - return true; -} - -static struct regmap_config twl6040_regmap_config = { - .reg_bits = 8, - .val_bits = 8, - .max_register = TWL6040_REG_STATUS, /* 0x2e */ - - .readable_reg = twl6040_readable_reg, -}; - -static int __devinit twl6040_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct twl6040_platform_data *pdata = client->dev.platform_data; + struct twl4030_audio_data *pdata = pdev->dev.platform_data; struct twl6040 *twl6040; struct mfd_cell *cell = NULL; int ret, children = 0; if (!pdata) { - dev_err(&client->dev, "Platform data is missing\n"); + dev_err(&pdev->dev, "Platform data is missing\n"); return -EINVAL; } /* In order to operate correctly we need valid interrupt config */ - if (!client->irq || !pdata->irq_base) { - dev_err(&client->dev, "Invalid IRQ configuration\n"); + if (!pdata->naudint_irq || !pdata->irq_base) { + dev_err(&pdev->dev, "Invalid IRQ configuration\n"); return -EINVAL; } - twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), - GFP_KERNEL); - if (!twl6040) { - ret = -ENOMEM; - goto err; - } - - twl6040->regmap = regmap_init_i2c(client, &twl6040_regmap_config); - if (IS_ERR(twl6040->regmap)) { - ret = PTR_ERR(twl6040->regmap); - goto err; - } + twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL); + if (!twl6040) + return -ENOMEM; - i2c_set_clientdata(client, twl6040); + platform_set_drvdata(pdev, twl6040); - twl6040->dev = &client->dev; - twl6040->irq = client->irq; + twl6040->dev = &pdev->dev; + twl6040->irq = pdata->naudint_irq; twl6040->irq_base = pdata->irq_base; mutex_init(&twl6040->mutex); @@ -602,12 +588,12 @@ static int __devinit twl6040_probe(struct i2c_client *client, } if (children) { - ret = mfd_add_devices(&client->dev, -1, twl6040->cells, + ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells, children, NULL, 0); if (ret) goto mfd_err; } else { - dev_err(&client->dev, "No platform data found for children\n"); + dev_err(&pdev->dev, "No platform data found for children\n"); ret = -ENODEV; goto mfd_err; } @@ -622,15 +608,14 @@ static int __devinit twl6040_probe(struct i2c_client *client, if (gpio_is_valid(twl6040->audpwron)) gpio_free(twl6040->audpwron); gpio1_err: - i2c_set_clientdata(client, NULL); - regmap_exit(twl6040->regmap); -err: + platform_set_drvdata(pdev, NULL); + kfree(twl6040); return ret; } -static int __devexit twl6040_remove(struct i2c_client *client) +static int __devexit twl6040_remove(struct platform_device *pdev) { - struct twl6040 *twl6040 = i2c_get_clientdata(client); + struct twl6040 *twl6040 = platform_get_drvdata(pdev); if (twl6040->power_count) twl6040_power(twl6040, 0); @@ -641,30 +626,23 @@ static int __devexit twl6040_remove(struct i2c_client *client) free_irq(twl6040->irq_base + TWL6040_IRQ_READY, twl6040); twl6040_irq_exit(twl6040); - mfd_remove_devices(&client->dev); - i2c_set_clientdata(client, NULL); - regmap_exit(twl6040->regmap); + mfd_remove_devices(&pdev->dev); + platform_set_drvdata(pdev, NULL); + kfree(twl6040); return 0; } -static const struct i2c_device_id twl6040_i2c_id[] = { - { "twl6040", 0, }, - { }, -}; -MODULE_DEVICE_TABLE(i2c, twl6040_i2c_id); - -static struct i2c_driver twl6040_driver = { - .driver = { - .name = "twl6040", - .owner = THIS_MODULE, - }, +static struct platform_driver twl6040_driver = { .probe = twl6040_probe, .remove = __devexit_p(twl6040_remove), - .id_table = twl6040_i2c_id, + .driver = { + .owner = THIS_MODULE, + .name = "twl6040", + }, }; -module_i2c_driver(twl6040_driver); +module_platform_driver(twl6040_driver); MODULE_DESCRIPTION("TWL6040 MFD"); MODULE_AUTHOR("Misael Lopez Cruz "); diff --git a/trunk/drivers/mmc/card/block.c b/trunk/drivers/mmc/card/block.c index dabec556ebb8..b1809650b7aa 100644 --- a/trunk/drivers/mmc/card/block.c +++ b/trunk/drivers/mmc/card/block.c @@ -873,7 +873,7 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, { struct mmc_blk_data *md = mq->data; struct mmc_card *card = md->queue.card; - unsigned int from, nr, arg, trim_arg, erase_arg; + unsigned int from, nr, arg; int err = 0, type = MMC_BLK_SECDISCARD; if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) { @@ -881,26 +881,20 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, goto out; } - from = blk_rq_pos(req); - nr = blk_rq_sectors(req); - /* The sanitize operation is supported at v4.5 only */ if (mmc_can_sanitize(card)) { - erase_arg = MMC_ERASE_ARG; - trim_arg = MMC_TRIM_ARG; - } else { - erase_arg = MMC_SECURE_ERASE_ARG; - trim_arg = MMC_SECURE_TRIM1_ARG; - } - - if (mmc_erase_group_aligned(card, from, nr)) - arg = erase_arg; - else if (mmc_can_trim(card)) - arg = trim_arg; - else { - err = -EINVAL; + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_SANITIZE_START, 1, 0); goto out; } + + from = blk_rq_pos(req); + nr = blk_rq_sectors(req); + + if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) + arg = MMC_SECURE_TRIM1_ARG; + else + arg = MMC_SECURE_ERASE_ARG; retry: if (card->quirks & MMC_QUIRK_INAND_CMD38) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, @@ -910,41 +904,25 @@ static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, INAND_CMD38_ARG_SECERASE, 0); if (err) - goto out_retry; + goto out; } - err = mmc_erase(card, from, nr, arg); - if (err == -EIO) - goto out_retry; - if (err) - goto out; - - if (arg == MMC_SECURE_TRIM1_ARG) { + if (!err && arg == MMC_SECURE_TRIM1_ARG) { if (card->quirks & MMC_QUIRK_INAND_CMD38) { err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, INAND_CMD38_ARG_EXT_CSD, INAND_CMD38_ARG_SECTRIM2, 0); if (err) - goto out_retry; + goto out; } - err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); - if (err == -EIO) - goto out_retry; - if (err) - goto out; } - - if (mmc_can_sanitize(card)) - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_SANITIZE_START, 1, 0); -out_retry: - if (err && !mmc_blk_reset(md, card->host, type)) +out: + if (err == -EIO && !mmc_blk_reset(md, card->host, type)) goto retry; if (!err) mmc_blk_reset_success(md, type); -out: spin_lock_irq(&md->lock); __blk_end_request(req, err, blk_rq_bytes(req)); spin_unlock_irq(&md->lock); @@ -1824,7 +1802,7 @@ static void mmc_blk_remove(struct mmc_card *card) } #ifdef CONFIG_PM -static int mmc_blk_suspend(struct mmc_card *card) +static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state) { struct mmc_blk_data *part_md; struct mmc_blk_data *md = mmc_get_drvdata(card); diff --git a/trunk/drivers/mmc/card/queue.c b/trunk/drivers/mmc/card/queue.c index 996f8e36e23d..2517547b4366 100644 --- a/trunk/drivers/mmc/card/queue.c +++ b/trunk/drivers/mmc/card/queue.c @@ -139,7 +139,7 @@ static void mmc_queue_setup_discard(struct request_queue *q, queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); q->limits.max_discard_sectors = max_discard; - if (card->erased_byte == 0 && !mmc_can_discard(card)) + if (card->erased_byte == 0) q->limits.discard_zeroes_data = 1; q->limits.discard_granularity = card->pref_erase << 9; /* granularity must not be greater than max. discard */ diff --git a/trunk/drivers/mmc/core/bus.c b/trunk/drivers/mmc/core/bus.c index c60cee92a2b2..3f606068d552 100644 --- a/trunk/drivers/mmc/core/bus.c +++ b/trunk/drivers/mmc/core/bus.c @@ -122,14 +122,14 @@ static int mmc_bus_remove(struct device *dev) return 0; } -static int mmc_bus_suspend(struct device *dev) +static int mmc_bus_suspend(struct device *dev, pm_message_t state) { struct mmc_driver *drv = to_mmc_driver(dev->driver); struct mmc_card *card = mmc_dev_to_card(dev); int ret = 0; if (dev->driver && drv->suspend) - ret = drv->suspend(card); + ret = drv->suspend(card, state); return ret; } @@ -165,14 +165,20 @@ static int mmc_runtime_idle(struct device *dev) return pm_runtime_suspend(dev); } -#endif /* !CONFIG_PM_RUNTIME */ - static const struct dev_pm_ops mmc_bus_pm_ops = { - SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, - mmc_runtime_idle) - SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume) + .runtime_suspend = mmc_runtime_suspend, + .runtime_resume = mmc_runtime_resume, + .runtime_idle = mmc_runtime_idle, }; +#define MMC_PM_OPS_PTR (&mmc_bus_pm_ops) + +#else /* !CONFIG_PM_RUNTIME */ + +#define MMC_PM_OPS_PTR NULL + +#endif /* !CONFIG_PM_RUNTIME */ + static struct bus_type mmc_bus_type = { .name = "mmc", .dev_attrs = mmc_dev_attrs, @@ -180,7 +186,9 @@ static struct bus_type mmc_bus_type = { .uevent = mmc_bus_uevent, .probe = mmc_bus_probe, .remove = mmc_bus_remove, - .pm = &mmc_bus_pm_ops, + .suspend = mmc_bus_suspend, + .resume = mmc_bus_resume, + .pm = MMC_PM_OPS_PTR, }; int mmc_register_bus(void) diff --git a/trunk/drivers/mmc/core/cd-gpio.c b/trunk/drivers/mmc/core/cd-gpio.c index 2c14be73254c..29de31e260dd 100644 --- a/trunk/drivers/mmc/core/cd-gpio.c +++ b/trunk/drivers/mmc/core/cd-gpio.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/mmc/core/core.c b/trunk/drivers/mmc/core/core.c index ba821fe70bca..7474c47b9c08 100644 --- a/trunk/drivers/mmc/core/core.c +++ b/trunk/drivers/mmc/core/core.c @@ -1409,10 +1409,7 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card, { unsigned int erase_timeout; - if (arg == MMC_DISCARD_ARG || - (arg == MMC_TRIM_ARG && card->ext_csd.rev >= 6)) { - erase_timeout = card->ext_csd.trim_timeout; - } else if (card->ext_csd.erase_group_def & 1) { + if (card->ext_csd.erase_group_def & 1) { /* High Capacity Erase Group Size uses HC timeouts */ if (arg == MMC_TRIM_ARG) erase_timeout = card->ext_csd.trim_timeout; @@ -1684,6 +1681,8 @@ int mmc_can_trim(struct mmc_card *card) { if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) return 1; + if (mmc_can_discard(card)) + return 1; return 0; } EXPORT_SYMBOL(mmc_can_trim); @@ -1702,8 +1701,6 @@ EXPORT_SYMBOL(mmc_can_discard); int mmc_can_sanitize(struct mmc_card *card) { - if (!mmc_can_trim(card) && !mmc_can_erase(card)) - return 0; if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_SANITIZE) return 1; return 0; @@ -2238,7 +2235,6 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) mmc_card_is_removable(host)) return err; - mmc_claim_host(host); if (card && mmc_card_mmc(card) && (card->ext_csd.cache_size > 0)) { enable = !!enable; @@ -2256,7 +2252,6 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) card->ext_csd.cache_ctrl = enable; } } - mmc_release_host(host); return err; } @@ -2274,32 +2269,49 @@ int mmc_suspend_host(struct mmc_host *host) cancel_delayed_work(&host->detect); mmc_flush_scheduled_work(); + if (mmc_try_claim_host(host)) { + err = mmc_cache_ctrl(host, 0); + mmc_release_host(host); + } else { + err = -EBUSY; + } - err = mmc_cache_ctrl(host, 0); if (err) goto out; mmc_bus_get(host); if (host->bus_ops && !host->bus_dead) { - if (host->bus_ops->suspend) - err = host->bus_ops->suspend(host); - - if (err == -ENOSYS || !host->bus_ops->resume) { - /* - * We simply "remove" the card in this case. - * It will be redetected on resume. (Calling - * bus_ops->remove() with a claimed host can - * deadlock.) - */ - if (host->bus_ops->remove) - host->bus_ops->remove(host); - mmc_claim_host(host); - mmc_detach_bus(host); - mmc_power_off(host); + /* + * A long response time is not acceptable for device drivers + * when doing suspend. Prevent mmc_claim_host in the suspend + * sequence, to potentially wait "forever" by trying to + * pre-claim the host. + */ + if (mmc_try_claim_host(host)) { + if (host->bus_ops->suspend) { + err = host->bus_ops->suspend(host); + } mmc_release_host(host); - host->pm_flags = 0; - err = 0; + + if (err == -ENOSYS || !host->bus_ops->resume) { + /* + * We simply "remove" the card in this case. + * It will be redetected on resume. (Calling + * bus_ops->remove() with a claimed host can + * deadlock.) + */ + if (host->bus_ops->remove) + host->bus_ops->remove(host); + mmc_claim_host(host); + mmc_detach_bus(host); + mmc_power_off(host); + mmc_release_host(host); + host->pm_flags = 0; + err = 0; + } + } else { + err = -EBUSY; } } mmc_bus_put(host); diff --git a/trunk/drivers/mmc/host/dw_mmc.c b/trunk/drivers/mmc/host/dw_mmc.c index ab3fc4617107..bf3c9b456aaf 100644 --- a/trunk/drivers/mmc/host/dw_mmc.c +++ b/trunk/drivers/mmc/host/dw_mmc.c @@ -526,10 +526,8 @@ static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) return -ENODEV; sg_len = dw_mci_pre_dma_transfer(host, data, 0); - if (sg_len < 0) { - host->dma_ops->stop(host); + if (sg_len < 0) return sg_len; - } host->using_dma = 1; @@ -1881,8 +1879,7 @@ static void dw_mci_init_dma(struct dw_mci *host) if (!host->dma_ops) goto no_dma; - if (host->dma_ops->init && host->dma_ops->start && - host->dma_ops->stop && host->dma_ops->cleanup) { + if (host->dma_ops->init) { if (host->dma_ops->init(host)) { dev_err(&host->dev, "%s: Unable to initialize " "DMA Controller.\n", __func__); diff --git a/trunk/drivers/mmc/host/mxs-mmc.c b/trunk/drivers/mmc/host/mxs-mmc.c index e3f5af96ab87..b0f2ef988188 100644 --- a/trunk/drivers/mmc/host/mxs-mmc.c +++ b/trunk/drivers/mmc/host/mxs-mmc.c @@ -363,7 +363,6 @@ static void mxs_mmc_bc(struct mxs_mmc_host *host) goto out; dmaengine_submit(desc); - dma_async_issue_pending(host->dmach); return; out: @@ -404,7 +403,6 @@ static void mxs_mmc_ac(struct mxs_mmc_host *host) goto out; dmaengine_submit(desc); - dma_async_issue_pending(host->dmach); return; out: @@ -533,7 +531,6 @@ static void mxs_mmc_adtc(struct mxs_mmc_host *host) goto out; dmaengine_submit(desc); - dma_async_issue_pending(host->dmach); return; out: dev_warn(mmc_dev(host->mmc), diff --git a/trunk/drivers/mmc/host/omap_hsmmc.c b/trunk/drivers/mmc/host/omap_hsmmc.c index 56d4499d4388..5c2b1c10af9c 100644 --- a/trunk/drivers/mmc/host/omap_hsmmc.c +++ b/trunk/drivers/mmc/host/omap_hsmmc.c @@ -249,7 +249,7 @@ static int omap_hsmmc_set_power(struct device *dev, int slot, int power_on, * the pbias cell programming support is still missing when * booting with Device tree */ - if (dev->of_node && !vdd) + if (of_have_populated_dt() && !vdd) return 0; if (mmc_slot(host).before_set_reg) @@ -1549,7 +1549,7 @@ static void omap_hsmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * can't be allowed when booting with device * tree. */ - !host->dev->of_node) { + (!of_have_populated_dt())) { /* * The mmc_select_voltage fn of the core does * not seem to set the power_mode to @@ -1741,7 +1741,7 @@ static const struct of_device_id omap_mmc_of_match[] = { .data = &omap4_reg_offset, }, {}, -}; +} MODULE_DEVICE_TABLE(of, omap_mmc_of_match); static struct omap_mmc_platform_data *of_get_hsmmc_pdata(struct device *dev) diff --git a/trunk/drivers/mmc/host/sdhci-esdhc-imx.c b/trunk/drivers/mmc/host/sdhci-esdhc-imx.c index 8abdaf6697a8..6193a0d7bde5 100644 --- a/trunk/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/trunk/drivers/mmc/host/sdhci-esdhc-imx.c @@ -467,7 +467,8 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) clk_prepare_enable(clk); pltfm_host->clk = clk; - host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; + if (!is_imx25_esdhc(imx_data)) + host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data)) /* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */ diff --git a/trunk/drivers/mmc/host/sdhci.c b/trunk/drivers/mmc/host/sdhci.c index ccefdebeff14..9aa77f3f04a8 100644 --- a/trunk/drivers/mmc/host/sdhci.c +++ b/trunk/drivers/mmc/host/sdhci.c @@ -147,7 +147,7 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) u32 present, irqs; if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || - (host->mmc->caps & MMC_CAP_NONREMOVABLE)) + !mmc_card_is_removable(host->mmc)) return; present = sdhci_readl(host, SDHCI_PRESENT_STATE) & diff --git a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 9ec51cec2e14..75b1dde16358 100644 --- a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -266,7 +266,6 @@ int start_dma_without_bch_irq(struct gpmi_nand_data *this, desc->callback = dma_irq_callback; desc->callback_param = this; dmaengine_submit(desc); - dma_async_issue_pending(get_dma_chan(this)); /* Wait for the interrupt from the DMA block. */ err = wait_for_completion_timeout(dma_c, msecs_to_jiffies(1000)); diff --git a/trunk/drivers/net/arcnet/arc-rimi.c b/trunk/drivers/net/arcnet/arc-rimi.c index b8b4c7ba884f..25197b698dd6 100644 --- a/trunk/drivers/net/arcnet/arc-rimi.c +++ b/trunk/drivers/net/arcnet/arc-rimi.c @@ -89,16 +89,16 @@ static int __init arcrimi_probe(struct net_device *dev) BUGLVL(D_NORMAL) printk(VERSION); BUGLVL(D_NORMAL) printk("E-mail me if you actually test the RIM I driver, please!\n"); - BUGLVL(D_NORMAL) printk("Given: node %02Xh, shmem %lXh, irq %d\n", + BUGMSG(D_NORMAL, "Given: node %02Xh, shmem %lXh, irq %d\n", dev->dev_addr[0], dev->mem_start, dev->irq); if (dev->mem_start <= 0 || dev->irq <= 0) { - BUGLVL(D_NORMAL) printk("No autoprobe for RIM I; you " + BUGMSG(D_NORMAL, "No autoprobe for RIM I; you " "must specify the shmem and irq!\n"); return -ENODEV; } if (dev->dev_addr[0] == 0) { - BUGLVL(D_NORMAL) printk("You need to specify your card's station " + BUGMSG(D_NORMAL, "You need to specify your card's station " "ID!\n"); return -ENODEV; } @@ -109,7 +109,7 @@ static int __init arcrimi_probe(struct net_device *dev) * will be taken. */ if (!request_mem_region(dev->mem_start, MIRROR_SIZE, "arcnet (90xx)")) { - BUGLVL(D_NORMAL) printk("Card memory already allocated\n"); + BUGMSG(D_NORMAL, "Card memory already allocated\n"); return -ENODEV; } return arcrimi_found(dev); diff --git a/trunk/drivers/net/caif/caif_hsi.c b/trunk/drivers/net/caif/caif_hsi.c index 9c1c8cd5223f..9a66e2a910ae 100644 --- a/trunk/drivers/net/caif/caif_hsi.c +++ b/trunk/drivers/net/caif/caif_hsi.c @@ -744,14 +744,14 @@ static void cfhsi_wake_up(struct work_struct *work) size_t fifo_occupancy = 0; /* Wakeup timeout */ - dev_dbg(&cfhsi->ndev->dev, "%s: Timeout.\n", + dev_err(&cfhsi->ndev->dev, "%s: Timeout.\n", __func__); /* Check FIFO to check if modem has sent something. */ WARN_ON(cfhsi->dev->cfhsi_fifo_occupancy(cfhsi->dev, &fifo_occupancy)); - dev_dbg(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n", + dev_err(&cfhsi->ndev->dev, "%s: Bytes in FIFO: %u.\n", __func__, (unsigned) fifo_occupancy); /* Check if we misssed the interrupt. */ @@ -1210,7 +1210,7 @@ int cfhsi_probe(struct platform_device *pdev) static void cfhsi_shutdown(struct cfhsi *cfhsi) { - u8 *tx_buf, *rx_buf, *flip_buf; + u8 *tx_buf, *rx_buf; /* Stop TXing */ netif_tx_stop_all_queues(cfhsi->ndev); @@ -1234,7 +1234,7 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi) /* Store bufferes: will be freed later. */ tx_buf = cfhsi->tx_buf; rx_buf = cfhsi->rx_buf; - flip_buf = cfhsi->rx_flip_buf; + /* Flush transmit queues. */ cfhsi_abort_tx(cfhsi); @@ -1247,7 +1247,6 @@ static void cfhsi_shutdown(struct cfhsi *cfhsi) /* Free buffers. */ kfree(tx_buf); kfree(rx_buf); - kfree(flip_buf); } int cfhsi_remove(struct platform_device *pdev) diff --git a/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 629c4ba5d49d..5234586dff15 100644 --- a/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/trunk/drivers/net/can/usb/peak_usb/pcan_usb_pro.c @@ -875,7 +875,6 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) PCAN_USBPRO_INFO_FW, &fi, sizeof(fi)); if (err) { - kfree(usb_if); dev_err(dev->netdev->dev.parent, "unable to read %s firmware info (err %d)\n", pcan_usb_pro.name, err); @@ -886,7 +885,6 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) PCAN_USBPRO_INFO_BL, &bi, sizeof(bi)); if (err) { - kfree(usb_if); dev_err(dev->netdev->dev.parent, "unable to read %s bootloader info (err %d)\n", pcan_usb_pro.name, err); diff --git a/trunk/drivers/net/dummy.c b/trunk/drivers/net/dummy.c index 442d91a2747b..d5c6d92f1ee7 100644 --- a/trunk/drivers/net/dummy.c +++ b/trunk/drivers/net/dummy.c @@ -107,14 +107,14 @@ static int dummy_dev_init(struct net_device *dev) return 0; } -static void dummy_dev_uninit(struct net_device *dev) +static void dummy_dev_free(struct net_device *dev) { free_percpu(dev->dstats); + free_netdev(dev); } static const struct net_device_ops dummy_netdev_ops = { .ndo_init = dummy_dev_init, - .ndo_uninit = dummy_dev_uninit, .ndo_start_xmit = dummy_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_rx_mode = set_multicast_list, @@ -128,7 +128,7 @@ static void dummy_setup(struct net_device *dev) /* Initialize the device structure. */ dev->netdev_ops = &dummy_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = dummy_dev_free; /* Fill in device structure with ethernet-generic values. */ dev->tx_queue_len = 0; diff --git a/trunk/drivers/net/ethernet/atheros/atlx/atl1.c b/trunk/drivers/net/ethernet/atheros/atlx/atl1.c index c926857e8205..40ac41436549 100644 --- a/trunk/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/trunk/drivers/net/ethernet/atheros/atlx/atl1.c @@ -2476,7 +2476,7 @@ static irqreturn_t atl1_intr(int irq, void *data) "pcie phy link down %x\n", status); if (netif_running(adapter->netdev)) { /* reset MAC */ iowrite32(0, adapter->hw.hw_addr + REG_IMR); - schedule_work(&adapter->reset_dev_task); + schedule_work(&adapter->pcie_dma_to_rst_task); return IRQ_HANDLED; } } @@ -2488,7 +2488,7 @@ static irqreturn_t atl1_intr(int irq, void *data) "pcie DMA r/w error (status = 0x%x)\n", status); iowrite32(0, adapter->hw.hw_addr + REG_IMR); - schedule_work(&adapter->reset_dev_task); + schedule_work(&adapter->pcie_dma_to_rst_task); return IRQ_HANDLED; } @@ -2633,10 +2633,10 @@ static void atl1_down(struct atl1_adapter *adapter) atl1_clean_rx_ring(adapter); } -static void atl1_reset_dev_task(struct work_struct *work) +static void atl1_tx_timeout_task(struct work_struct *work) { struct atl1_adapter *adapter = - container_of(work, struct atl1_adapter, reset_dev_task); + container_of(work, struct atl1_adapter, tx_timeout_task); struct net_device *netdev = adapter->netdev; netif_device_detach(netdev); @@ -3038,10 +3038,12 @@ static int __devinit atl1_probe(struct pci_dev *pdev, (unsigned long)adapter); adapter->phy_timer_pending = false; - INIT_WORK(&adapter->reset_dev_task, atl1_reset_dev_task); + INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task); INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task); + INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task); + err = register_netdev(netdev); if (err) goto err_common; diff --git a/trunk/drivers/net/ethernet/atheros/atlx/atl1.h b/trunk/drivers/net/ethernet/atheros/atlx/atl1.h index e04bf4d71e46..109d6da8be97 100644 --- a/trunk/drivers/net/ethernet/atheros/atlx/atl1.h +++ b/trunk/drivers/net/ethernet/atheros/atlx/atl1.h @@ -758,8 +758,9 @@ struct atl1_adapter { u16 link_speed; u16 link_duplex; spinlock_t lock; - struct work_struct reset_dev_task; + struct work_struct tx_timeout_task; struct work_struct link_chg_task; + struct work_struct pcie_dma_to_rst_task; struct timer_list phy_config_timer; bool phy_timer_pending; diff --git a/trunk/drivers/net/ethernet/atheros/atlx/atlx.c b/trunk/drivers/net/ethernet/atheros/atlx/atlx.c index c9e9dc57986c..3cd8837236dc 100644 --- a/trunk/drivers/net/ethernet/atheros/atlx/atlx.c +++ b/trunk/drivers/net/ethernet/atheros/atlx/atlx.c @@ -194,7 +194,7 @@ static void atlx_tx_timeout(struct net_device *netdev) { struct atlx_adapter *adapter = netdev_priv(netdev); /* Do the reset outside of interrupt context */ - schedule_work(&adapter->reset_dev_task); + schedule_work(&adapter->tx_timeout_task); } /* diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 64392ec410a3..ad95324dc042 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -942,12 +942,6 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params, const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 : DCBX_E3B0_MAX_NUM_COS_PORT0; - if (pri >= max_num_of_cos) { - DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " - "parameter Illegal strict priority\n"); - return -EINVAL; - } - if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) { DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " "parameter There can't be two COS's with " @@ -955,6 +949,12 @@ static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params, return -EINVAL; } + if (pri > max_num_of_cos) { + DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid " + "parameter Illegal strict priority\n"); + return -EINVAL; + } + sp_pri_to_cos[pri] = cos_entry; return 0; diff --git a/trunk/drivers/net/ethernet/broadcom/tg3.c b/trunk/drivers/net/ethernet/broadcom/tg3.c index ceeab8e852ef..062ac333fde6 100644 --- a/trunk/drivers/net/ethernet/broadcom/tg3.c +++ b/trunk/drivers/net/ethernet/broadcom/tg3.c @@ -879,13 +879,8 @@ static inline unsigned int tg3_has_work(struct tg3_napi *tnapi) if (sblk->status & SD_STATUS_LINK_CHG) work_exists = 1; } - - /* check for TX work to do */ - if (sblk->idx[0].tx_consumer != tnapi->tx_cons) - work_exists = 1; - - /* check for RX work to do */ - if (tnapi->rx_rcb_prod_idx && + /* check for RX/TX work to do */ + if (sblk->idx[0].tx_consumer != tnapi->tx_cons || *(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr) work_exists = 1; @@ -6129,9 +6124,6 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget) return work_done; } - if (!tnapi->rx_rcb_prod_idx) - return work_done; - /* run RX thread, within the bounds set by NAPI. * All RX "locking" is done by ensuring outside * code synchronizes with tg3->napi.poll() @@ -7575,12 +7567,6 @@ static int tg3_alloc_consistent(struct tg3 *tp) */ switch (i) { default: - if (tg3_flag(tp, ENABLE_RSS)) { - tnapi->rx_rcb_prod_idx = NULL; - break; - } - /* Fall through */ - case 1: tnapi->rx_rcb_prod_idx = &sblk->idx[0].rx_producer; break; case 2: diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/trunk/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index abb6ce7c1b7e..63bfdd10bd6d 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -1149,48 +1149,6 @@ static int update_tpsram(struct adapter *adap) return ret; } -/** - * t3_synchronize_rx - wait for current Rx processing on a port to complete - * @adap: the adapter - * @p: the port - * - * Ensures that current Rx processing on any of the queues associated with - * the given port completes before returning. We do this by acquiring and - * releasing the locks of the response queues associated with the port. - */ -static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) -{ - int i; - - for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) { - struct sge_rspq *q = &adap->sge.qs[i].rspq; - - spin_lock_irq(&q->lock); - spin_unlock_irq(&q->lock); - } -} - -static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) -{ - struct port_info *pi = netdev_priv(dev); - struct adapter *adapter = pi->adapter; - - if (adapter->params.rev > 0) { - t3_set_vlan_accel(adapter, 1 << pi->port_id, - features & NETIF_F_HW_VLAN_RX); - } else { - /* single control for all ports */ - unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; - - for_each_port(adapter, i) - have_vlans |= - adapter->port[i]->features & NETIF_F_HW_VLAN_RX; - - t3_set_vlan_accel(adapter, 1, have_vlans); - } - t3_synchronize_rx(adapter, pi); -} - /** * cxgb_up - enable the adapter * @adapter: adapter being enabled @@ -1203,7 +1161,7 @@ static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) */ static int cxgb_up(struct adapter *adap) { - int i, err; + int err; if (!(adap->flags & FULL_INIT_DONE)) { err = t3_check_fw_version(adap); @@ -1240,9 +1198,6 @@ static int cxgb_up(struct adapter *adap) if (err) goto out; - for_each_port(adap, i) - cxgb_vlan_mode(adap->port[i], adap->port[i]->features); - setup_rss(adap); if (!(adap->flags & NAPI_INIT)) init_napi(adap); @@ -2553,6 +2508,48 @@ static int cxgb_set_mac_addr(struct net_device *dev, void *p) return 0; } +/** + * t3_synchronize_rx - wait for current Rx processing on a port to complete + * @adap: the adapter + * @p: the port + * + * Ensures that current Rx processing on any of the queues associated with + * the given port completes before returning. We do this by acquiring and + * releasing the locks of the response queues associated with the port. + */ +static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p) +{ + int i; + + for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) { + struct sge_rspq *q = &adap->sge.qs[i].rspq; + + spin_lock_irq(&q->lock); + spin_unlock_irq(&q->lock); + } +} + +static void cxgb_vlan_mode(struct net_device *dev, netdev_features_t features) +{ + struct port_info *pi = netdev_priv(dev); + struct adapter *adapter = pi->adapter; + + if (adapter->params.rev > 0) { + t3_set_vlan_accel(adapter, 1 << pi->port_id, + features & NETIF_F_HW_VLAN_RX); + } else { + /* single control for all ports */ + unsigned int i, have_vlans = features & NETIF_F_HW_VLAN_RX; + + for_each_port(adapter, i) + have_vlans |= + adapter->port[i]->features & NETIF_F_HW_VLAN_RX; + + t3_set_vlan_accel(adapter, 1, have_vlans); + } + t3_synchronize_rx(adapter, pi); +} + static netdev_features_t cxgb_fix_features(struct net_device *dev, netdev_features_t features) { @@ -3356,6 +3353,9 @@ static int __devinit init_one(struct pci_dev *pdev, err = sysfs_create_group(&adapter->port[0]->dev.kobj, &cxgb3_attr_group); + for_each_port(adapter, i) + cxgb_vlan_mode(adapter->port[i], adapter->port[i]->features); + print_port_info(adapter, ai); return 0; diff --git a/trunk/drivers/net/ethernet/dlink/dl2k.c b/trunk/drivers/net/ethernet/dlink/dl2k.c index 2e09edb9cdf8..b2dc2c81a147 100644 --- a/trunk/drivers/net/ethernet/dlink/dl2k.c +++ b/trunk/drivers/net/ethernet/dlink/dl2k.c @@ -1259,21 +1259,55 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) { int phy_addr; struct netdev_private *np = netdev_priv(dev); - struct mii_ioctl_data *miidata = if_mii(rq); + struct mii_data *miidata = (struct mii_data *) &rq->ifr_ifru; + + struct netdev_desc *desc; + int i; phy_addr = np->phy_addr; switch (cmd) { - case SIOCGMIIPHY: - miidata->phy_id = phy_addr; + case SIOCDEVPRIVATE: + break; + + case SIOCDEVPRIVATE + 1: + miidata->out_value = mii_read (dev, phy_addr, miidata->reg_num); break; - case SIOCGMIIREG: - miidata->val_out = mii_read (dev, phy_addr, miidata->reg_num); + case SIOCDEVPRIVATE + 2: + mii_write (dev, phy_addr, miidata->reg_num, miidata->in_value); break; - case SIOCSMIIREG: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - mii_write (dev, phy_addr, miidata->reg_num, miidata->val_in); + case SIOCDEVPRIVATE + 3: + break; + case SIOCDEVPRIVATE + 4: + break; + case SIOCDEVPRIVATE + 5: + netif_stop_queue (dev); break; + case SIOCDEVPRIVATE + 6: + netif_wake_queue (dev); + break; + case SIOCDEVPRIVATE + 7: + printk + ("tx_full=%x cur_tx=%lx old_tx=%lx cur_rx=%lx old_rx=%lx\n", + netif_queue_stopped(dev), np->cur_tx, np->old_tx, np->cur_rx, + np->old_rx); + break; + case SIOCDEVPRIVATE + 8: + printk("TX ring:\n"); + for (i = 0; i < TX_RING_SIZE; i++) { + desc = &np->tx_ring[i]; + printk + ("%02x:cur:%08x next:%08x status:%08x frag1:%08x frag0:%08x", + i, + (u32) (np->tx_ring_dma + i * sizeof (*desc)), + (u32)le64_to_cpu(desc->next_desc), + (u32)le64_to_cpu(desc->status), + (u32)(le64_to_cpu(desc->fraginfo) >> 32), + (u32)le64_to_cpu(desc->fraginfo)); + printk ("\n"); + } + printk ("\n"); + break; + default: return -EOPNOTSUPP; } diff --git a/trunk/drivers/net/ethernet/dlink/dl2k.h b/trunk/drivers/net/ethernet/dlink/dl2k.h index 30c2da3de548..ba0adcafa55a 100644 --- a/trunk/drivers/net/ethernet/dlink/dl2k.h +++ b/trunk/drivers/net/ethernet/dlink/dl2k.h @@ -365,6 +365,13 @@ struct ioctl_data { char *data; }; +struct mii_data { + __u16 reserved; + __u16 reg_num; + __u16 in_value; + __u16 out_value; +}; + /* The Rx and Tx buffer descriptors. */ struct netdev_desc { __le64 next_desc; diff --git a/trunk/drivers/net/ethernet/freescale/ucc_geth.c b/trunk/drivers/net/ethernet/freescale/ucc_geth.c index 9ac14f804851..17a46e76123f 100644 --- a/trunk/drivers/net/ethernet/freescale/ucc_geth.c +++ b/trunk/drivers/net/ethernet/freescale/ucc_geth.c @@ -116,10 +116,10 @@ static struct ucc_geth_info ugeth_primary_info = { .maxGroupAddrInHash = 4, .maxIndAddrInHash = 4, .prel = 7, - .maxFrameLength = 1518+16, /* Add extra bytes for VLANs etc. */ + .maxFrameLength = 1518, .minFrameLength = 64, - .maxD1Length = 1520+16, /* Add extra bytes for VLANs etc. */ - .maxD2Length = 1520+16, /* Add extra bytes for VLANs etc. */ + .maxD1Length = 1520, + .maxD2Length = 1520, .vlantype = 0x8100, .ecamptr = ((uint32_t) NULL), .eventRegMask = UCCE_OTHER, diff --git a/trunk/drivers/net/ethernet/freescale/ucc_geth.h b/trunk/drivers/net/ethernet/freescale/ucc_geth.h index f71b3e7b12de..2e395a2566b8 100644 --- a/trunk/drivers/net/ethernet/freescale/ucc_geth.h +++ b/trunk/drivers/net/ethernet/freescale/ucc_geth.h @@ -877,7 +877,7 @@ struct ucc_geth_hardware_statistics { /* Driver definitions */ #define TX_BD_RING_LEN 0x10 -#define RX_BD_RING_LEN 0x20 +#define RX_BD_RING_LEN 0x10 #define TX_RING_MOD_MASK(size) (size-1) #define RX_RING_MOD_MASK(size) (size-1) diff --git a/trunk/drivers/net/ethernet/ibm/ehea/ehea_main.c b/trunk/drivers/net/ethernet/ibm/ehea/ehea_main.c index c9069a28832b..3516e17a399d 100644 --- a/trunk/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/trunk/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -290,18 +290,16 @@ static void ehea_update_bcmc_registrations(void) arr[i].adh = adapter->handle; arr[i].port_id = port->logical_port_id; - arr[i].reg_type = EHEA_BCMC_MULTICAST | + arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | + EHEA_BCMC_MULTICAST | EHEA_BCMC_UNTAGGED; - if (mc_entry->macaddr == 0) - arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL; arr[i++].macaddr = mc_entry->macaddr; arr[i].adh = adapter->handle; arr[i].port_id = port->logical_port_id; - arr[i].reg_type = EHEA_BCMC_MULTICAST | + arr[i].reg_type = EHEA_BCMC_SCOPE_ALL | + EHEA_BCMC_MULTICAST | EHEA_BCMC_VLANID_ALL; - if (mc_entry->macaddr == 0) - arr[i].reg_type |= EHEA_BCMC_SCOPE_ALL; arr[i++].macaddr = mc_entry->macaddr; num_registrations -= 2; } @@ -1840,9 +1838,8 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr, u64 hret; u8 reg_type; - reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_UNTAGGED; - if (mc_mac_addr == 0) - reg_type |= EHEA_BCMC_SCOPE_ALL; + reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST + | EHEA_BCMC_UNTAGGED; hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, port->logical_port_id, @@ -1850,9 +1847,8 @@ static u64 ehea_multicast_reg_helper(struct ehea_port *port, u64 mc_mac_addr, if (hret) goto out; - reg_type = EHEA_BCMC_MULTICAST | EHEA_BCMC_VLANID_ALL; - if (mc_mac_addr == 0) - reg_type |= EHEA_BCMC_SCOPE_ALL; + reg_type = EHEA_BCMC_SCOPE_ALL | EHEA_BCMC_MULTICAST + | EHEA_BCMC_VLANID_ALL; hret = ehea_h_reg_dereg_bcmc(port->adapter->handle, port->logical_port_id, @@ -1902,7 +1898,7 @@ static void ehea_allmulti(struct net_device *dev, int enable) netdev_err(dev, "failed enabling IFF_ALLMULTI\n"); } - } else { + } else if (!enable) { /* Disable ALLMULTI */ hret = ehea_multicast_reg_helper(port, 0, H_DEREG_BCMC); @@ -1912,7 +1908,6 @@ static void ehea_allmulti(struct net_device *dev, int enable) netdev_err(dev, "failed disabling IFF_ALLMULTI\n"); } - } } static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) @@ -1946,7 +1941,11 @@ static void ehea_set_multicast_list(struct net_device *dev) struct netdev_hw_addr *ha; int ret; - ehea_promiscuous(dev, !!(dev->flags & IFF_PROMISC)); + if (port->promisc) { + ehea_promiscuous(dev, 1); + return; + } + ehea_promiscuous(dev, 0); if (dev->flags & IFF_ALLMULTI) { ehea_allmulti(dev, 1); @@ -2464,7 +2463,6 @@ static int ehea_down(struct net_device *dev) return 0; ehea_drop_multicast_list(dev); - ehea_allmulti(dev, 0); ehea_broadcast_reg_helper(port, H_DEREG_BCMC); ehea_free_interrupts(dev); @@ -3263,7 +3261,6 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, struct ehea_adapter *adapter; const u64 *adapter_handle; int ret; - int i; if (!dev || !dev->dev.of_node) { pr_err("Invalid ibmebus device probed\n"); @@ -3317,9 +3314,17 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, tasklet_init(&adapter->neq_tasklet, ehea_neq_tasklet, (unsigned long)adapter); + ret = ibmebus_request_irq(adapter->neq->attr.ist1, + ehea_interrupt_neq, IRQF_DISABLED, + "ehea_neq", adapter); + if (ret) { + dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); + goto out_kill_eq; + } + ret = ehea_create_device_sysfs(dev); if (ret) - goto out_kill_eq; + goto out_free_irq; ret = ehea_setup_ports(adapter); if (ret) { @@ -3327,28 +3332,15 @@ static int __devinit ehea_probe_adapter(struct platform_device *dev, goto out_rem_dev_sysfs; } - ret = ibmebus_request_irq(adapter->neq->attr.ist1, - ehea_interrupt_neq, IRQF_DISABLED, - "ehea_neq", adapter); - if (ret) { - dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); - goto out_shutdown_ports; - } - - ret = 0; goto out; -out_shutdown_ports: - for (i = 0; i < EHEA_MAX_PORTS; i++) - if (adapter->port[i]) { - ehea_shutdown_single_port(adapter->port[i]); - adapter->port[i] = NULL; - } - out_rem_dev_sysfs: ehea_remove_device_sysfs(dev); +out_free_irq: + ibmebus_free_irq(adapter->neq->attr.ist1, adapter); + out_kill_eq: ehea_destroy_eq(adapter->neq); diff --git a/trunk/drivers/net/ethernet/ibm/ehea/ehea_phyp.h b/trunk/drivers/net/ethernet/ibm/ehea/ehea_phyp.h index 8364815c32ff..52c456ec4d6c 100644 --- a/trunk/drivers/net/ethernet/ibm/ehea/ehea_phyp.h +++ b/trunk/drivers/net/ethernet/ibm/ehea/ehea_phyp.h @@ -450,7 +450,7 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num, void *cb_addr); #define H_REGBCMC_PN EHEA_BMASK_IBM(48, 63) -#define H_REGBCMC_REGTYPE EHEA_BMASK_IBM(60, 63) +#define H_REGBCMC_REGTYPE EHEA_BMASK_IBM(61, 63) #define H_REGBCMC_MACADDR EHEA_BMASK_IBM(16, 63) #define H_REGBCMC_VLANID EHEA_BMASK_IBM(52, 63) diff --git a/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c b/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c index b461c24945e3..64c76443a7aa 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1310,6 +1310,10 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) if (mac_reg & E1000_PHY_CTRL_D0A_LPLU) oem_reg |= HV_OEM_BITS_LPLU; + + /* Set Restart auto-neg to activate the bits */ + if (!hw->phy.ops.check_reset_block(hw)) + oem_reg |= HV_OEM_BITS_RESTART_AN; } else { if (mac_reg & (E1000_PHY_CTRL_GBE_DISABLE | E1000_PHY_CTRL_NOND0A_GBE_DISABLE)) @@ -1320,11 +1324,6 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) oem_reg |= HV_OEM_BITS_LPLU; } - /* Set Restart auto-neg to activate the bits */ - if ((d0_state || (hw->mac.type != e1000_pchlan)) && - !hw->phy.ops.check_reset_block(hw)) - oem_reg |= HV_OEM_BITS_RESTART_AN; - ret_val = hw->phy.ops.write_reg_locked(hw, HV_OEM_BITS, oem_reg); release: @@ -3683,11 +3682,7 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) if (hw->mac.type >= e1000_pchlan) { e1000_oem_bits_config_ich8lan(hw, false); - - /* Reset PHY to activate OEM bits on 82577/8 */ - if (hw->mac.type == e1000_pchlan) - e1000e_phy_hw_reset_generic(hw); - + e1000_phy_hw_reset_ich8lan(hw); ret_val = hw->phy.ops.acquire(hw); if (ret_val) return; diff --git a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c index 9520a6ac1f30..19ab2154802c 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c @@ -3799,7 +3799,7 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter) /* fire an unusual interrupt on the test handler */ ew32(ICS, E1000_ICS_RXSEQ); e1e_flush(); - msleep(100); + msleep(50); e1000_irq_disable(adapter); diff --git a/trunk/drivers/net/ethernet/intel/e1000e/param.c b/trunk/drivers/net/ethernet/intel/e1000e/param.c index 16adeb9418a8..ff796e42c3eb 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/param.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/param.c @@ -106,7 +106,7 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); /* * Interrupt Throttle Rate (interrupts/sec) * - * Valid Range: 100-100000 or one of: 0=off, 1=dynamic, 3=dynamic conservative + * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative) */ E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); #define DEFAULT_ITR 3 @@ -344,60 +344,53 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) if (num_InterruptThrottleRate > bd) { adapter->itr = InterruptThrottleRate[bd]; - - /* - * Make sure a message is printed for non-special - * values. And in case of an invalid option, display - * warning, use default and got through itr/itr_setting - * adjustment logic below - */ - if ((adapter->itr > 4) && - e1000_validate_option(&adapter->itr, &opt, adapter)) - adapter->itr = opt.def; + switch (adapter->itr) { + case 0: + e_info("%s turned off\n", opt.name); + break; + case 1: + e_info("%s set to dynamic mode\n", opt.name); + adapter->itr_setting = adapter->itr; + adapter->itr = 20000; + break; + case 3: + e_info("%s set to dynamic conservative mode\n", + opt.name); + adapter->itr_setting = adapter->itr; + adapter->itr = 20000; + break; + case 4: + e_info("%s set to simplified (2000-8000 ints) " + "mode\n", opt.name); + adapter->itr_setting = 4; + break; + default: + /* + * Save the setting, because the dynamic bits + * change itr. + */ + if (e1000_validate_option(&adapter->itr, &opt, + adapter) && + (adapter->itr == 3)) { + /* + * In case of invalid user value, + * default to conservative mode. + */ + adapter->itr_setting = adapter->itr; + adapter->itr = 20000; + } else { + /* + * Clear the lower two bits because + * they are used as control. + */ + adapter->itr_setting = + adapter->itr & ~3; + } + break; + } } else { - /* - * If no option specified, use default value and go - * through the logic below to adjust itr/itr_setting - */ - adapter->itr = opt.def; - - /* - * Make sure a message is printed for non-special - * default values - */ - if (adapter->itr > 40) - e_info("%s set to default %d\n", opt.name, - adapter->itr); - } - - adapter->itr_setting = adapter->itr; - switch (adapter->itr) { - case 0: - e_info("%s turned off\n", opt.name); - break; - case 1: - e_info("%s set to dynamic mode\n", opt.name); - adapter->itr = 20000; - break; - case 3: - e_info("%s set to dynamic conservative mode\n", - opt.name); + adapter->itr_setting = opt.def; adapter->itr = 20000; - break; - case 4: - e_info("%s set to simplified (2000-8000 ints) mode\n", - opt.name); - break; - default: - /* - * Save the setting, because the dynamic bits - * change itr. - * - * Clear the lower two bits because - * they are used as control. - */ - adapter->itr_setting &= ~3; - break; } } { /* Interrupt Mode */ diff --git a/trunk/drivers/net/ethernet/intel/igbvf/netdev.c b/trunk/drivers/net/ethernet/intel/igbvf/netdev.c index 8ec74b07f940..d61ca2a732f0 100644 --- a/trunk/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/trunk/drivers/net/ethernet/intel/igbvf/netdev.c @@ -2731,14 +2731,14 @@ static int __devinit igbvf_probe(struct pci_dev *pdev, netdev->addr_len); } - if (!is_valid_ether_addr(netdev->dev_addr)) { + if (!is_valid_ether_addr(netdev->perm_addr)) { dev_err(&pdev->dev, "Invalid MAC Address: %pM\n", netdev->dev_addr); err = -EIO; goto err_hw_init; } - memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); + memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len); setup_timer(&adapter->watchdog_timer, &igbvf_watchdog, (unsigned long) adapter); diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c index bc07933d67da..77ea4b716535 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c @@ -437,7 +437,6 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, */ if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) && (fctl & FC_FC_END_SEQ)) { - skb_linearize(skb); crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc)); crc->fcoe_eof = FC_EOF_T; } diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index ed1b47dc0834..027d7a75be39 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -622,16 +622,6 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, int v_idx, if (adapter->hw.mac.type == ixgbe_mac_82599EB) set_bit(__IXGBE_RX_CSUM_UDP_ZERO_ERR, &ring->state); -#ifdef IXGBE_FCOE - if (adapter->netdev->features & NETIF_F_FCOE_MTU) { - struct ixgbe_ring_feature *f; - f = &adapter->ring_feature[RING_F_FCOE]; - if ((rxr_idx >= f->mask) && - (rxr_idx < f->mask + f->indices)) - set_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state); - } - -#endif /* IXGBE_FCOE */ /* apply Rx specific ring traits */ ring->count = adapter->rx_ring_count; ring->queue_index = rxr_idx; diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 88f6b2e9b72d..3e26b1f9ac75 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -3154,6 +3154,14 @@ static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) set_ring_rsc_enabled(rx_ring); else clear_ring_rsc_enabled(rx_ring); +#ifdef IXGBE_FCOE + if (netdev->features & NETIF_F_FCOE_MTU) { + struct ixgbe_ring_feature *f; + f = &adapter->ring_feature[RING_F_FCOE]; + if ((i >= f->mask) && (i < f->mask + f->indices)) + set_bit(__IXGBE_RX_FCOE_BUFSZ, &rx_ring->state); + } +#endif /* IXGBE_FCOE */ } } @@ -4828,9 +4836,7 @@ static int ixgbe_resume(struct pci_dev *pdev) pci_wake_from_d3(pdev, false); - rtnl_lock(); err = ixgbe_init_interrupt_scheme(adapter); - rtnl_unlock(); if (err) { e_dev_err("Cannot initialize interrupts for device\n"); return err; @@ -4873,6 +4879,10 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) } ixgbe_clear_interrupt_scheme(adapter); +#ifdef CONFIG_DCB + kfree(adapter->ixgbe_ieee_pfc); + kfree(adapter->ixgbe_ieee_ets); +#endif #ifdef CONFIG_PM retval = pci_save_state(pdev); @@ -4883,16 +4893,6 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) if (wufc) { ixgbe_set_rx_mode(netdev); - /* - * enable the optics for both mult-speed fiber and - * 82599 SFP+ fiber as we can WoL. - */ - if (hw->mac.ops.enable_tx_laser && - (hw->phy.multispeed_fiber || - (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber && - hw->mac.type == ixgbe_mac_82599EB))) - hw->mac.ops.enable_tx_laser(hw); - /* turn on all-multi mode if wake on multicast is enabled */ if (wufc & IXGBE_WUFC_MC) { fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); @@ -7220,11 +7220,6 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) ixgbe_release_hw_control(adapter); -#ifdef CONFIG_DCB - kfree(adapter->ixgbe_ieee_pfc); - kfree(adapter->ixgbe_ieee_ets); - -#endif iounmap(adapter->hw.hw_addr); pci_release_selected_regions(pdev, pci_select_bars(pdev, IORESOURCE_MEM)); diff --git a/trunk/drivers/net/ethernet/marvell/sky2.c b/trunk/drivers/net/ethernet/marvell/sky2.c index 487a6c8bd4ec..c9b504e2dfc3 100644 --- a/trunk/drivers/net/ethernet/marvell/sky2.c +++ b/trunk/drivers/net/ethernet/marvell/sky2.c @@ -2494,13 +2494,8 @@ static struct sk_buff *receive_copy(struct sky2_port *sky2, skb_copy_from_linear_data(re->skb, skb->data, length); skb->ip_summed = re->skb->ip_summed; skb->csum = re->skb->csum; - skb->rxhash = re->skb->rxhash; - skb->vlan_tci = re->skb->vlan_tci; - pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr, length, PCI_DMA_FROMDEVICE); - re->skb->vlan_tci = 0; - re->skb->rxhash = 0; re->skb->ip_summed = CHECKSUM_NONE; skb_put(skb, length); } @@ -2585,6 +2580,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev, struct sk_buff *skb = NULL; u16 count = (status & GMR_FS_LEN) >> 16; + if (status & GMR_FS_VLAN) + count -= VLAN_HLEN; /* Account for vlan tag */ + netif_printk(sky2, rx_status, KERN_DEBUG, dev, "rx slot %u status 0x%x len %d\n", sky2->rx_next, status, length); @@ -2592,9 +2590,6 @@ static struct sk_buff *sky2_receive(struct net_device *dev, sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; prefetch(sky2->rx_ring + sky2->rx_next); - if (vlan_tx_tag_present(re->skb)) - count -= VLAN_HLEN; /* Account for vlan tag */ - /* This chip has hardware problems that generates bogus status. * So do only marginal checking and expect higher level protocols * to handle crap frames. @@ -2652,8 +2647,11 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last) } static inline void sky2_skb_rx(const struct sky2_port *sky2, - struct sk_buff *skb) + u32 status, struct sk_buff *skb) { + if (status & GMR_FS_VLAN) + __vlan_hwaccel_put_tag(skb, be16_to_cpu(sky2->rx_tag)); + if (skb->ip_summed == CHECKSUM_NONE) netif_receive_skb(skb); else @@ -2707,14 +2705,6 @@ static void sky2_rx_checksum(struct sky2_port *sky2, u32 status) } } -static void sky2_rx_tag(struct sky2_port *sky2, u16 length) -{ - struct sk_buff *skb; - - skb = sky2->rx_ring[sky2->rx_next].skb; - __vlan_hwaccel_put_tag(skb, be16_to_cpu(length)); -} - static void sky2_rx_hash(struct sky2_port *sky2, u32 status) { struct sk_buff *skb; @@ -2773,7 +2763,8 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) } skb->protocol = eth_type_trans(skb, dev); - sky2_skb_rx(sky2, skb); + + sky2_skb_rx(sky2, status, skb); /* Stop after net poll weight */ if (++work_done >= to_do) @@ -2781,11 +2772,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) break; case OP_RXVLAN: - sky2_rx_tag(sky2, length); + sky2->rx_tag = length; break; case OP_RXCHKSVLAN: - sky2_rx_tag(sky2, length); + sky2->rx_tag = length; /* fall through */ case OP_RXCHKS: if (likely(dev->features & NETIF_F_RXCSUM)) diff --git a/trunk/drivers/net/ethernet/marvell/sky2.h b/trunk/drivers/net/ethernet/marvell/sky2.h index 3c896ce80b71..ff6f58bf822a 100644 --- a/trunk/drivers/net/ethernet/marvell/sky2.h +++ b/trunk/drivers/net/ethernet/marvell/sky2.h @@ -2241,6 +2241,7 @@ struct sky2_port { u16 rx_pending; u16 rx_data_size; u16 rx_nfrags; + u16 rx_tag; struct { unsigned long last; diff --git a/trunk/drivers/net/ethernet/micrel/ks8851.c b/trunk/drivers/net/ethernet/micrel/ks8851.c index f8dda009d3c0..c722aa607d07 100644 --- a/trunk/drivers/net/ethernet/micrel/ks8851.c +++ b/trunk/drivers/net/ethernet/micrel/ks8851.c @@ -889,17 +889,16 @@ static int ks8851_net_stop(struct net_device *dev) netif_stop_queue(dev); mutex_lock(&ks->lock); - /* turn off the IRQs and ack any outstanding */ - ks8851_wrreg16(ks, KS_IER, 0x0000); - ks8851_wrreg16(ks, KS_ISR, 0xffff); - mutex_unlock(&ks->lock); /* stop any outstanding work */ flush_work(&ks->irq_work); flush_work(&ks->tx_work); flush_work(&ks->rxctrl_work); - mutex_lock(&ks->lock); + /* turn off the IRQs and ack any outstanding */ + ks8851_wrreg16(ks, KS_IER, 0x0000); + ks8851_wrreg16(ks, KS_ISR, 0xffff); + /* shutdown RX process */ ks8851_wrreg16(ks, KS_RXCR1, 0x0000); @@ -908,7 +907,6 @@ static int ks8851_net_stop(struct net_device *dev) /* set powermode to soft power down to save power */ ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); - mutex_unlock(&ks->lock); /* ensure any queued tx buffers are dumped */ while (!skb_queue_empty(&ks->txq)) { @@ -920,6 +918,7 @@ static int ks8851_net_stop(struct net_device *dev) dev_kfree_skb(txb); } + mutex_unlock(&ks->lock); return 0; } @@ -1419,7 +1418,6 @@ static int __devinit ks8851_probe(struct spi_device *spi) struct net_device *ndev; struct ks8851_net *ks; int ret; - unsigned cider; ndev = alloc_etherdev(sizeof(struct ks8851_net)); if (!ndev) @@ -1486,8 +1484,8 @@ static int __devinit ks8851_probe(struct spi_device *spi) ks8851_soft_reset(ks, GRR_GSR); /* simple check for a valid chip being connected to the bus */ - cider = ks8851_rdreg16(ks, KS_CIDER); - if ((cider & ~CIDER_REV_MASK) != CIDER_ID) { + + if ((ks8851_rdreg16(ks, KS_CIDER) & ~CIDER_REV_MASK) != CIDER_ID) { dev_err(&spi->dev, "failed to read device ID\n"); ret = -ENODEV; goto err_id; @@ -1518,14 +1516,15 @@ static int __devinit ks8851_probe(struct spi_device *spi) } netdev_info(ndev, "revision %d, MAC %pM, IRQ %d, %s EEPROM\n", - CIDER_REV_GET(cider), ndev->dev_addr, ndev->irq, + CIDER_REV_GET(ks8851_rdreg16(ks, KS_CIDER)), + ndev->dev_addr, ndev->irq, ks->rc_ccr & CCR_EEPROM ? "has" : "no"); return 0; err_netdev: - free_irq(ndev->irq, ks); + free_irq(ndev->irq, ndev); err_id: err_irq: diff --git a/trunk/drivers/net/ethernet/micrel/ks8851_mll.c b/trunk/drivers/net/ethernet/micrel/ks8851_mll.c index 5ffde23ac8fb..b8104d9f4081 100644 --- a/trunk/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/trunk/drivers/net/ethernet/micrel/ks8851_mll.c @@ -40,7 +40,7 @@ #define DRV_NAME "ks8851_mll" static u8 KS_DEFAULT_MAC_ADDRESS[] = { 0x00, 0x10, 0xA1, 0x86, 0x95, 0x11 }; -#define MAX_RECV_FRAMES 255 +#define MAX_RECV_FRAMES 32 #define MAX_BUF_SIZE 2048 #define TX_BUF_SIZE 2000 #define RX_BUF_SIZE 2000 diff --git a/trunk/drivers/net/ethernet/micrel/ksz884x.c b/trunk/drivers/net/ethernet/micrel/ksz884x.c index eaf9ff0262a9..ef723b185d85 100644 --- a/trunk/drivers/net/ethernet/micrel/ksz884x.c +++ b/trunk/drivers/net/ethernet/micrel/ksz884x.c @@ -5675,7 +5675,7 @@ static int netdev_set_mac_address(struct net_device *dev, void *addr) memcpy(hw->override_addr, mac->sa_data, ETH_ALEN); } - memcpy(dev->dev_addr, mac->sa_data, ETH_ALEN); + memcpy(dev->dev_addr, mac->sa_data, MAX_ADDR_LEN); interrupt = hw_block_intr(hw); diff --git a/trunk/drivers/net/ethernet/realtek/8139cp.c b/trunk/drivers/net/ethernet/realtek/8139cp.c index b3287c0fe279..abc79076f867 100644 --- a/trunk/drivers/net/ethernet/realtek/8139cp.c +++ b/trunk/drivers/net/ethernet/realtek/8139cp.c @@ -958,11 +958,6 @@ static inline void cp_start_hw (struct cp_private *cp) cpw8(Cmd, RxOn | TxOn); } -static void cp_enable_irq(struct cp_private *cp) -{ - cpw16_f(IntrMask, cp_intr_mask); -} - static void cp_init_hw (struct cp_private *cp) { struct net_device *dev = cp->dev; @@ -1002,6 +997,8 @@ static void cp_init_hw (struct cp_private *cp) cpw16(MultiIntr, 0); + cpw16_f(IntrMask, cp_intr_mask); + cpw8_f(Cfg9346, Cfg9346_Lock); } @@ -1133,8 +1130,6 @@ static int cp_open (struct net_device *dev) if (rc) goto err_out_hw; - cp_enable_irq(cp); - netif_carrier_off(dev); mii_check_media(&cp->mii_if, netif_msg_link(cp), true); netif_start_queue(dev); @@ -2036,7 +2031,6 @@ static int cp_resume (struct pci_dev *pdev) /* FIXME: sh*t may happen if the Rx ring buffer is depleted */ cp_init_rings_index (cp); cp_init_hw (cp); - cp_enable_irq(cp); netif_start_queue (dev); spin_lock_irqsave (&cp->lock, flags); diff --git a/trunk/drivers/net/ethernet/smsc/smsc911x.c b/trunk/drivers/net/ethernet/smsc/smsc911x.c index cd3defb11ffb..4a6971027076 100644 --- a/trunk/drivers/net/ethernet/smsc/smsc911x.c +++ b/trunk/drivers/net/ethernet/smsc/smsc911x.c @@ -1166,8 +1166,10 @@ smsc911x_rx_counterrors(struct net_device *dev, unsigned int rxstat) /* Quickly dumps bad packets */ static void -smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktwords) +smsc911x_rx_fastforward(struct smsc911x_data *pdata, unsigned int pktbytes) { + unsigned int pktwords = (pktbytes + NET_IP_ALIGN + 3) >> 2; + if (likely(pktwords >= 4)) { unsigned int timeout = 500; unsigned int val; @@ -1231,7 +1233,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) continue; } - skb = netdev_alloc_skb(dev, pktwords << 2); + skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN); if (unlikely(!skb)) { SMSC_WARN(pdata, rx_err, "Unable to allocate skb for rx packet"); @@ -1241,12 +1243,14 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) break; } - pdata->ops->rx_readfifo(pdata, - (unsigned int *)skb->data, pktwords); + skb->data = skb->head; + skb_reset_tail_pointer(skb); /* Align IP on 16B boundary */ skb_reserve(skb, NET_IP_ALIGN); skb_put(skb, pktlength - 4); + pdata->ops->rx_readfifo(pdata, + (unsigned int *)skb->head, pktwords); skb->protocol = eth_type_trans(skb, dev); skb_checksum_none_assert(skb); netif_receive_skb(skb); @@ -1561,7 +1565,7 @@ static int smsc911x_open(struct net_device *dev) smsc911x_reg_write(pdata, FIFO_INT, temp); /* set RX Data offset to 2 bytes for alignment */ - smsc911x_reg_write(pdata, RX_CFG, (NET_IP_ALIGN << 8)); + smsc911x_reg_write(pdata, RX_CFG, (2 << 8)); /* enable NAPI polling before enabling RX interrupts */ napi_enable(&pdata->napi); @@ -2378,6 +2382,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) SET_NETDEV_DEV(dev, &pdev->dev); pdata = netdev_priv(dev); + dev->irq = irq_res->start; irq_flags = irq_res->flags & IRQF_TRIGGER_MASK; pdata->ioaddr = ioremap_nocache(res->start, res_size); @@ -2441,7 +2446,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) if (retval) { SMSC_WARN(pdata, probe, "Unable to claim requested irq: %d", dev->irq); - goto out_disable_resources; + goto out_free_irq; } retval = register_netdev(dev); diff --git a/trunk/drivers/net/ethernet/sun/sungem.c b/trunk/drivers/net/ethernet/sun/sungem.c index 4ba969096717..558409ff4058 100644 --- a/trunk/drivers/net/ethernet/sun/sungem.c +++ b/trunk/drivers/net/ethernet/sun/sungem.c @@ -2339,7 +2339,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state) netif_device_detach(dev); /* Switch off chip, remember WOL setting */ - gp->asleep_wol = !!gp->wake_on_lan; + gp->asleep_wol = gp->wake_on_lan; gem_do_stop(dev, gp->asleep_wol); /* Unlock the network stack */ diff --git a/trunk/drivers/net/ethernet/ti/davinci_emac.c b/trunk/drivers/net/ethernet/ti/davinci_emac.c index 08aff1a2087c..174a3348f676 100644 --- a/trunk/drivers/net/ethernet/ti/davinci_emac.c +++ b/trunk/drivers/net/ethernet/ti/davinci_emac.c @@ -1511,7 +1511,7 @@ static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd) static int match_first_device(struct device *dev, void *data) { - return !strncmp(dev_name(dev), "davinci_mdio", 12); + return 1; } /** diff --git a/trunk/drivers/net/ethernet/ti/davinci_mdio.c b/trunk/drivers/net/ethernet/ti/davinci_mdio.c index e4e47088e26b..2757c7d6e633 100644 --- a/trunk/drivers/net/ethernet/ti/davinci_mdio.c +++ b/trunk/drivers/net/ethernet/ti/davinci_mdio.c @@ -181,11 +181,6 @@ static inline int wait_for_user_access(struct davinci_mdio_data *data) __davinci_mdio_reset(data); return -EAGAIN; } - - reg = __raw_readl(®s->user[0].access); - if ((reg & USERACCESS_GO) == 0) - return 0; - dev_err(data->dev, "timed out waiting for user access\n"); return -ETIMEDOUT; } diff --git a/trunk/drivers/net/ethernet/ti/tlan.c b/trunk/drivers/net/ethernet/ti/tlan.c index efd36691ce54..817ad3bc4957 100644 --- a/trunk/drivers/net/ethernet/ti/tlan.c +++ b/trunk/drivers/net/ethernet/ti/tlan.c @@ -228,7 +228,7 @@ tlan_get_skb(const struct tlan_list *tag) unsigned long addr; addr = tag->buffer[9].address; - addr |= ((unsigned long) tag->buffer[8].address << 16) << 16; + addr |= (tag->buffer[8].address << 16) << 16; return (struct sk_buff *) addr; } diff --git a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet.h b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet.h index 44b8d2bad8c3..cc83af083fd7 100644 --- a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet.h +++ b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet.h @@ -2,7 +2,9 @@ * Definitions for Xilinx Axi Ethernet device driver. * * Copyright (c) 2009 Secret Lab Technologies, Ltd. - * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved. + * Copyright (c) 2010 Xilinx, Inc. All rights reserved. + * Copyright (c) 2012 Daniel Borkmann, + * Copyright (c) 2012 Ariane Keller, */ #ifndef XILINX_AXIENET_H diff --git a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 9c365e192a31..2fcbeba6814b 100644 --- a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -4,9 +4,9 @@ * Copyright (c) 2008 Nissin Systems Co., Ltd., Yoshio Kashiwagi * Copyright (c) 2005-2008 DLA Systems, David H. Lynch Jr. * Copyright (c) 2008-2009 Secret Lab Technologies Ltd. - * Copyright (c) 2010 - 2011 Michal Simek - * Copyright (c) 2010 - 2011 PetaLogix - * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved. + * Copyright (c) 2010 Xilinx, Inc. All rights reserved. + * Copyright (c) 2012 Daniel Borkmann, + * Copyright (c) 2012 Ariane Keller, * * This is a driver for the Xilinx Axi Ethernet which is used in the Virtex6 * and Spartan6. diff --git a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c index e90e1f46121e..d70b6e79f6c0 100644 --- a/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c +++ b/trunk/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -2,9 +2,9 @@ * MDIO bus driver for the Xilinx Axi Ethernet device * * Copyright (c) 2009 Secret Lab Technologies, Ltd. - * Copyright (c) 2010 - 2011 Michal Simek - * Copyright (c) 2010 - 2011 PetaLogix - * Copyright (c) 2010 - 2012 Xilinx, Inc. All rights reserved. + * Copyright (c) 2010 Xilinx, Inc. All rights reserved. + * Copyright (c) 2012 Daniel Borkmann, + * Copyright (c) 2012 Ariane Keller, */ #include diff --git a/trunk/drivers/net/hyperv/netvsc_drv.c b/trunk/drivers/net/hyperv/netvsc_drv.c index 2d59138db7f3..dd294783b5c5 100644 --- a/trunk/drivers/net/hyperv/netvsc_drv.c +++ b/trunk/drivers/net/hyperv/netvsc_drv.c @@ -44,7 +44,6 @@ struct net_device_context { /* point back to our device context */ struct hv_device *device_ctx; struct delayed_work dwork; - struct work_struct work; }; @@ -52,22 +51,30 @@ static int ring_size = 128; module_param(ring_size, int, S_IRUGO); MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); +struct set_multicast_work { + struct work_struct work; + struct net_device *net; +}; + static void do_set_multicast(struct work_struct *w) { - struct net_device_context *ndevctx = - container_of(w, struct net_device_context, work); + struct set_multicast_work *swk = + container_of(w, struct set_multicast_work, work); + struct net_device *net = swk->net; + + struct net_device_context *ndevctx = netdev_priv(net); struct netvsc_device *nvdev; struct rndis_device *rdev; nvdev = hv_get_drvdata(ndevctx->device_ctx); - if (nvdev == NULL || nvdev->ndev == NULL) - return; + if (nvdev == NULL) + goto out; rdev = nvdev->extension; if (rdev == NULL) - return; + goto out; - if (nvdev->ndev->flags & IFF_PROMISC) + if (net->flags & IFF_PROMISC) rndis_filter_set_packet_filter(rdev, NDIS_PACKET_TYPE_PROMISCUOUS); else @@ -75,13 +82,21 @@ static void do_set_multicast(struct work_struct *w) NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_ALL_MULTICAST | NDIS_PACKET_TYPE_DIRECTED); + +out: + kfree(w); } static void netvsc_set_multicast_list(struct net_device *net) { - struct net_device_context *net_device_ctx = netdev_priv(net); + struct set_multicast_work *swk = + kmalloc(sizeof(struct set_multicast_work), GFP_ATOMIC); + if (swk == NULL) + return; - schedule_work(&net_device_ctx->work); + swk->net = net; + INIT_WORK(&swk->work, do_set_multicast); + schedule_work(&swk->work); } static int netvsc_open(struct net_device *net) @@ -110,8 +125,6 @@ static int netvsc_close(struct net_device *net) netif_tx_disable(net); - /* Make sure netvsc_set_multicast_list doesn't re-enable filter! */ - cancel_work_sync(&net_device_ctx->work); ret = rndis_filter_close(device_obj); if (ret != 0) netdev_err(net, "unable to close device (ret %d).\n", ret); @@ -322,7 +335,6 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) nvdev->start_remove = true; cancel_delayed_work_sync(&ndevctx->dwork); - cancel_work_sync(&ndevctx->work); netif_tx_disable(ndev); rndis_filter_device_remove(hdev); @@ -391,7 +403,6 @@ static int netvsc_probe(struct hv_device *dev, net_device_ctx->device_ctx = dev; hv_set_drvdata(dev, net); INIT_DELAYED_WORK(&net_device_ctx->dwork, netvsc_send_garp); - INIT_WORK(&net_device_ctx->work, do_set_multicast); net->netdev_ops = &device_ops; @@ -445,7 +456,6 @@ static int netvsc_remove(struct hv_device *dev) ndev_ctx = netdev_priv(net); cancel_delayed_work_sync(&ndev_ctx->dwork); - cancel_work_sync(&ndev_ctx->work); /* Stop outbound asap */ netif_tx_disable(net); diff --git a/trunk/drivers/net/phy/icplus.c b/trunk/drivers/net/phy/icplus.c index 5ac46f5226f3..f08c85acf761 100644 --- a/trunk/drivers/net/phy/icplus.c +++ b/trunk/drivers/net/phy/icplus.c @@ -40,7 +40,6 @@ MODULE_LICENSE("GPL"); #define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ #define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ -#define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */ static int ip175c_config_init(struct phy_device *phydev) { @@ -186,15 +185,6 @@ static int ip175c_config_aneg(struct phy_device *phydev) return 0; } -static int ip101a_g_ack_interrupt(struct phy_device *phydev) -{ - int err = phy_read(phydev, IP101A_G_IRQ_CONF_STATUS); - if (err < 0) - return err; - - return 0; -} - static struct phy_driver ip175c_driver = { .phy_id = 0x02430d80, .name = "ICPlus IP175C", @@ -214,6 +204,7 @@ static struct phy_driver ip1001_driver = { .phy_id_mask = 0x0ffffff0, .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause, + .flags = PHY_HAS_INTERRUPT, .config_init = &ip1001_config_init, .config_aneg = &genphy_config_aneg, .read_status = &genphy_read_status, @@ -229,7 +220,6 @@ static struct phy_driver ip101a_g_driver = { .features = PHY_BASIC_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause, .flags = PHY_HAS_INTERRUPT, - .ack_interrupt = ip101a_g_ack_interrupt, .config_init = &ip101a_g_config_init, .config_aneg = &genphy_config_aneg, .read_status = &genphy_read_status, diff --git a/trunk/drivers/net/ppp/ppp_generic.c b/trunk/drivers/net/ppp/ppp_generic.c index 21d7151fb0ab..33f8c51968b6 100644 --- a/trunk/drivers/net/ppp/ppp_generic.c +++ b/trunk/drivers/net/ppp/ppp_generic.c @@ -235,7 +235,7 @@ struct ppp_net { /* Prototypes. */ static int ppp_unattached_ioctl(struct net *net, struct ppp_file *pf, struct file *file, unsigned int cmd, unsigned long arg); -static void ppp_xmit_process(struct ppp *ppp); +static int ppp_xmit_process(struct ppp *ppp); static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb); static void ppp_push(struct ppp *ppp); static void ppp_channel_push(struct channel *pch); @@ -969,7 +969,8 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev) put_unaligned_be16(proto, pp); skb_queue_tail(&ppp->file.xq, skb); - ppp_xmit_process(ppp); + if (!ppp_xmit_process(ppp)) + netif_stop_queue(dev); return NETDEV_TX_OK; outf: @@ -1047,10 +1048,11 @@ static void ppp_setup(struct net_device *dev) * Called to do any work queued up on the transmit side * that can now be done. */ -static void +static int ppp_xmit_process(struct ppp *ppp) { struct sk_buff *skb; + int ret = 0; ppp_xmit_lock(ppp); if (!ppp->closing) { @@ -1060,12 +1062,13 @@ ppp_xmit_process(struct ppp *ppp) ppp_send_frame(ppp, skb); /* If there's no work left to do, tell the core net code that we can accept some more. */ - if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq)) + if (!ppp->xmit_pending && !skb_peek(&ppp->file.xq)) { netif_wake_queue(ppp->dev); - else - netif_stop_queue(ppp->dev); + ret = 1; + } } ppp_xmit_unlock(ppp); + return ret; } static inline struct sk_buff * diff --git a/trunk/drivers/net/usb/asix.c b/trunk/drivers/net/usb/asix.c index 42b5151aa78a..5ee032cafade 100644 --- a/trunk/drivers/net/usb/asix.c +++ b/trunk/drivers/net/usb/asix.c @@ -355,7 +355,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, u32 packet_len; u32 padbytes = 0xffff0000; - padlen = ((skb->len + 4) & (dev->maxpacket - 1)) ? 0 : 4; + padlen = ((skb->len + 4) % 512) ? 0 : 4; if ((!skb_cloned(skb)) && ((headroom + tailroom) >= (4 + padlen))) { @@ -377,7 +377,7 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, cpu_to_le32s(&packet_len); skb_copy_to_linear_data(skb, &packet_len, sizeof(packet_len)); - if (padlen) { + if ((skb->len % 512) == 0) { cpu_to_le32s(&padbytes); memcpy(skb_tail_pointer(skb), &padbytes, sizeof(padbytes)); skb_put(skb, sizeof(padbytes)); diff --git a/trunk/drivers/net/usb/qmi_wwan.c b/trunk/drivers/net/usb/qmi_wwan.c index d316503b35d4..552d24bf862e 100644 --- a/trunk/drivers/net/usb/qmi_wwan.c +++ b/trunk/drivers/net/usb/qmi_wwan.c @@ -365,27 +365,6 @@ static const struct driver_info qmi_wwan_force_int4 = { .data = BIT(4), /* interface whitelist bitmap */ }; -/* Sierra Wireless provide equally useless interface descriptors - * Devices in QMI mode can be switched between two different - * configurations: - * a) USB interface #8 is QMI/wwan - * b) USB interfaces #8, #19 and #20 are QMI/wwan - * - * Both configurations provide a number of other interfaces (serial++), - * some of which have the same endpoint configuration as we expect, so - * a whitelist or blacklist is necessary. - * - * FIXME: The below whitelist should include BIT(20). It does not - * because I cannot get it to work... - */ -static const struct driver_info qmi_wwan_sierra = { - .description = "Sierra Wireless wwan/QMI device", - .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_gobi, - .unbind = qmi_wwan_unbind_shared, - .manage_power = qmi_wwan_manage_power, - .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ -}; #define HUAWEI_VENDOR_ID 0x12D1 #define QMI_GOBI_DEVICE(vend, prod) \ @@ -466,15 +445,6 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_force_int4, }, - { /* Sierra Wireless MC77xx in QMI mode */ - .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, - .idVendor = 0x1199, - .idProduct = 0x68a2, - .bInterfaceClass = 0xff, - .bInterfaceSubClass = 0xff, - .bInterfaceProtocol = 0xff, - .driver_info = (unsigned long)&qmi_wwan_sierra, - }, {QMI_GOBI_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ diff --git a/trunk/drivers/net/usb/smsc75xx.c b/trunk/drivers/net/usb/smsc75xx.c index 00103a8c5e04..187d01ccb973 100644 --- a/trunk/drivers/net/usb/smsc75xx.c +++ b/trunk/drivers/net/usb/smsc75xx.c @@ -98,7 +98,7 @@ static int __must_check smsc75xx_read_reg(struct usbnet *dev, u32 index, if (unlikely(ret < 0)) netdev_warn(dev->net, - "Failed to read reg index 0x%08x: %d", index, ret); + "Failed to read register index 0x%08x", index); le32_to_cpus(buf); *data = *buf; @@ -128,7 +128,7 @@ static int __must_check smsc75xx_write_reg(struct usbnet *dev, u32 index, if (unlikely(ret < 0)) netdev_warn(dev->net, - "Failed to write reg index 0x%08x: %d", index, ret); + "Failed to write register index 0x%08x", index); kfree(buf); @@ -171,7 +171,7 @@ static int smsc75xx_mdio_read(struct net_device *netdev, int phy_id, int idx) idx &= dev->mii.reg_num_mask; addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) - | MII_ACCESS_READ | MII_ACCESS_BUSY; + | MII_ACCESS_READ; ret = smsc75xx_write_reg(dev, MII_ACCESS, addr); check_warn_goto_done(ret, "Error writing MII_ACCESS"); @@ -210,7 +210,7 @@ static void smsc75xx_mdio_write(struct net_device *netdev, int phy_id, int idx, idx &= dev->mii.reg_num_mask; addr = ((phy_id << MII_ACCESS_PHY_ADDR_SHIFT) & MII_ACCESS_PHY_ADDR) | ((idx << MII_ACCESS_REG_ADDR_SHIFT) & MII_ACCESS_REG_ADDR) - | MII_ACCESS_WRITE | MII_ACCESS_BUSY; + | MII_ACCESS_WRITE; ret = smsc75xx_write_reg(dev, MII_ACCESS, addr); check_warn_goto_done(ret, "Error writing MII_ACCESS"); @@ -508,10 +508,9 @@ static int smsc75xx_link_reset(struct usbnet *dev) u16 lcladv, rmtadv; int ret; - /* read and write to clear phy interrupt status */ + /* clear interrupt status */ ret = smsc75xx_mdio_read(dev->net, mii->phy_id, PHY_INT_SRC); check_warn_return(ret, "Error reading PHY_INT_SRC"); - smsc75xx_mdio_write(dev->net, mii->phy_id, PHY_INT_SRC, 0xffff); ret = smsc75xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL); check_warn_return(ret, "Error writing INT_STS"); @@ -644,7 +643,7 @@ static int smsc75xx_set_mac_address(struct usbnet *dev) static int smsc75xx_phy_initialize(struct usbnet *dev) { - int bmcr, ret, timeout = 0; + int bmcr, timeout = 0; /* Initialize MII structure */ dev->mii.dev = dev->net; @@ -652,7 +651,6 @@ static int smsc75xx_phy_initialize(struct usbnet *dev) dev->mii.mdio_write = smsc75xx_mdio_write; dev->mii.phy_id_mask = 0x1f; dev->mii.reg_num_mask = 0x1f; - dev->mii.supports_gmii = 1; dev->mii.phy_id = SMSC75XX_INTERNAL_PHY_ID; /* reset phy and wait for reset to complete */ @@ -663,7 +661,7 @@ static int smsc75xx_phy_initialize(struct usbnet *dev) bmcr = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); check_warn_return(bmcr, "Error reading MII_BMCR"); timeout++; - } while ((bmcr & BMCR_RESET) && (timeout < 100)); + } while ((bmcr & MII_BMCR) && (timeout < 100)); if (timeout >= 100) { netdev_warn(dev->net, "timeout on PHY Reset"); @@ -673,13 +671,10 @@ static int smsc75xx_phy_initialize(struct usbnet *dev) smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_ADVERTISE, ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); - smsc75xx_mdio_write(dev->net, dev->mii.phy_id, MII_CTRL1000, - ADVERTISE_1000FULL); - /* read and write to clear phy interrupt status */ - ret = smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); - check_warn_return(ret, "Error reading PHY_INT_SRC"); - smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_SRC, 0xffff); + /* read to clear */ + smsc75xx_mdio_read(dev->net, dev->mii.phy_id, PHY_INT_SRC); + check_warn_return(bmcr, "Error reading PHY_INT_SRC"); smsc75xx_mdio_write(dev->net, dev->mii.phy_id, PHY_INT_MASK, PHY_INT_MASK_DEFAULT); @@ -951,14 +946,6 @@ static int smsc75xx_reset(struct usbnet *dev) ret = smsc75xx_write_reg(dev, INT_EP_CTL, buf); check_warn_return(ret, "Failed to write INT_EP_CTL: %d", ret); - /* allow mac to detect speed and duplex from phy */ - ret = smsc75xx_read_reg(dev, MAC_CR, &buf); - check_warn_return(ret, "Failed to read MAC_CR: %d", ret); - - buf |= (MAC_CR_ADD | MAC_CR_ASD); - ret = smsc75xx_write_reg(dev, MAC_CR, buf); - check_warn_return(ret, "Failed to write MAC_CR: %d", ret); - ret = smsc75xx_read_reg(dev, MAC_TX, &buf); check_warn_return(ret, "Failed to read MAC_TX: %d", ret); @@ -1064,7 +1051,6 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->ethtool_ops = &smsc75xx_ethtool_ops; dev->net->flags |= IFF_MULTICAST; dev->net->hard_header_len += SMSC75XX_TX_OVERHEAD; - dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; return 0; } @@ -1225,7 +1211,7 @@ static const struct driver_info smsc75xx_info = { .rx_fixup = smsc75xx_rx_fixup, .tx_fixup = smsc75xx_tx_fixup, .status = smsc75xx_status, - .flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR, + .flags = FLAG_ETHER | FLAG_SEND_ZLP, }; static const struct usb_device_id products[] = { diff --git a/trunk/drivers/net/usb/smsc95xx.c b/trunk/drivers/net/usb/smsc95xx.c index 94ae66999f59..5f19f84d3494 100644 --- a/trunk/drivers/net/usb/smsc95xx.c +++ b/trunk/drivers/net/usb/smsc95xx.c @@ -1017,7 +1017,6 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) dev->net->ethtool_ops = &smsc95xx_ethtool_ops; dev->net->flags |= IFF_MULTICAST; dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM; - dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len; return 0; } @@ -1192,7 +1191,7 @@ static const struct driver_info smsc95xx_info = { .rx_fixup = smsc95xx_rx_fixup, .tx_fixup = smsc95xx_tx_fixup, .status = smsc95xx_status, - .flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR, + .flags = FLAG_ETHER | FLAG_SEND_ZLP, }; static const struct usb_device_id products[] = { diff --git a/trunk/drivers/net/usb/usbnet.c b/trunk/drivers/net/usb/usbnet.c index 2d927fb4adf4..b7b3f5b0d406 100644 --- a/trunk/drivers/net/usb/usbnet.c +++ b/trunk/drivers/net/usb/usbnet.c @@ -210,7 +210,6 @@ static int init_status (struct usbnet *dev, struct usb_interface *intf) } else { usb_fill_int_urb(dev->interrupt, dev->udev, pipe, buf, maxp, intr_complete, dev, period); - dev->interrupt->transfer_flags |= URB_FREE_BUFFER; dev_dbg(&intf->dev, "status ep%din, %d bytes period %d\n", usb_pipeendpoint(pipe), maxp, period); @@ -1444,7 +1443,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) status = register_netdev (net); if (status) - goto out4; + goto out3; netif_info(dev, probe, dev->net, "register '%s' at usb-%s-%s, %s, %pM\n", udev->dev.driver->name, @@ -1462,8 +1461,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) return 0; -out4: - usb_free_urb(dev->interrupt); out3: if (info->unbind) info->unbind (dev, udev); diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index af8acc85f4bb..4de2760c5937 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -626,15 +626,16 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) /* This can happen with OOM and indirect buffers. */ if (unlikely(capacity < 0)) { if (likely(capacity == -ENOMEM)) { - if (net_ratelimit()) + if (net_ratelimit()) { dev_warn(&dev->dev, "TX queue failure: out of memory\n"); - } else { + } else { dev->stats.tx_fifo_errors++; if (net_ratelimit()) dev_warn(&dev->dev, "Unexpected TX queue failure: %d\n", capacity); + } } dev->stats.tx_dropped++; kfree_skb(skb); diff --git a/trunk/drivers/net/wan/farsync.c b/trunk/drivers/net/wan/farsync.c index 1a623183cbe5..ebb9f24eefb5 100644 --- a/trunk/drivers/net/wan/farsync.c +++ b/trunk/drivers/net/wan/farsync.c @@ -2483,7 +2483,6 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent) pr_err("Control memory remap failed\n"); pci_release_regions(pdev); pci_disable_device(pdev); - iounmap(card->mem); kfree(card); return -ENODEV; } diff --git a/trunk/drivers/net/wireless/ath/ath5k/ahb.c b/trunk/drivers/net/wireless/ath/ath5k/ahb.c index aec33cc207fd..8faa129da5a0 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/ahb.c +++ b/trunk/drivers/net/wireless/ath/ath5k/ahb.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "ath5k.h" #include "debug.h" @@ -120,7 +119,7 @@ static int ath_ahb_probe(struct platform_device *pdev) if (res == NULL) { dev_err(&pdev->dev, "no IRQ resource found\n"); ret = -ENXIO; - goto err_iounmap; + goto err_out; } irq = res->start; @@ -129,7 +128,7 @@ static int ath_ahb_probe(struct platform_device *pdev) if (hw == NULL) { dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); ret = -ENOMEM; - goto err_iounmap; + goto err_out; } ah = hw->priv; @@ -186,8 +185,6 @@ static int ath_ahb_probe(struct platform_device *pdev) err_free_hw: ieee80211_free_hw(hw); platform_set_drvdata(pdev, NULL); - err_iounmap: - iounmap(mem); err_out: return ret; } @@ -220,7 +217,6 @@ static int ath_ahb_remove(struct platform_device *pdev) } ath5k_deinit_ah(ah); - iounmap(ah->iobase); platform_set_drvdata(pdev, NULL); ieee80211_free_hw(hw); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c index aba088005b22..d7d8e9199140 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -869,7 +869,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, ar5008_hw_set_channel_regs(ah, chan); ar5008_hw_init_chain_masks(ah); ath9k_olc_init(ah); - ath9k_hw_apply_txpower(ah, chan, false); + ath9k_hw_apply_txpower(ah, chan); /* Write analog registers */ if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 3d400e8d6535..59647a3ceb7f 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -54,7 +54,7 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val) if (val) { ah->paprd_table_write_done = true; - ath9k_hw_apply_txpower(ah, chan, false); + ath9k_hw_apply_txpower(ah, chan); } REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c index deb6cfb2959a..bc992b237ae5 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -694,7 +694,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, ar9003_hw_override_ini(ah); ar9003_hw_set_channel_regs(ah, chan); ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); - ath9k_hw_apply_txpower(ah, chan, false); + ath9k_hw_apply_txpower(ah, chan); if (AR_SREV_9462(ah)) { if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, diff --git a/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c index b34e8b2990b1..f272236d8053 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/trunk/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -824,8 +824,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, regulatory->max_power_level = ratesArray[i]; } - ath9k_hw_update_regulatory_maxpower(ah); - if (test) return; diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index fa84e37bf091..6c69e4e8b1cb 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -1454,7 +1454,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, return false; } ath9k_hw_set_clockrate(ah); - ath9k_hw_apply_txpower(ah, chan, false); + ath9k_hw_apply_txpower(ah, chan); ath9k_hw_rfbus_done(ah); if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) @@ -2652,8 +2652,7 @@ static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan) return ah->eep_ops->get_eeprom(ah, gain_param); } -void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, - bool test) +void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan) { struct ath_regulatory *reg = ath9k_hw_regulatory(ah); struct ieee80211_channel *channel; @@ -2674,7 +2673,7 @@ void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, ah->eep_ops->set_txpower(ah, chan, ath9k_regd_get_ctl(reg, chan), - ant_reduction, new_pwr, test); + ant_reduction, new_pwr, false); } void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) @@ -2687,7 +2686,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) if (test) channel->max_power = MAX_RATE_POWER / 2; - ath9k_hw_apply_txpower(ah, chan, test); + ath9k_hw_apply_txpower(ah, chan); if (test) channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2); diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.h b/trunk/drivers/net/wireless/ath/ath9k/hw.h index e88f182ff45c..aa1680a0c7fd 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.h @@ -985,8 +985,7 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); /* PHY */ void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, u32 *coef_mantissa, u32 *coef_exponent); -void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan, - bool test); +void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan); /* * Code Specific to AR5008, AR9001 or AR9002, diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index 798ea57252b4..2504ab005589 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -1548,7 +1548,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ieee80211_conf *conf = &hw->conf; - bool reset_channel = false; ath9k_ps_wakeup(sc); mutex_lock(&sc->mutex); @@ -1557,12 +1556,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) sc->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); if (sc->ps_idle) ath_cancel_work(sc); - else - /* - * The chip needs a reset to properly wake up from - * full sleep - */ - reset_channel = ah->chip_fullsleep; } /* @@ -1591,7 +1584,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) } } - if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { struct ieee80211_channel *curchan = hw->conf.channel; int pos = curchan->hw_value; int old_pos = -1; diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index 23eaa1b26ebe..834e6bc45e8b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -1820,7 +1820,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, struct ath_frame_info *fi = get_frame_info(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ath_buf *bf; - int fragno; u16 seqno; bf = ath_tx_get_buffer(sc); @@ -1832,16 +1831,9 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, ATH_TXBUF_RESET(bf); if (tid) { - fragno = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; seqno = tid->seq_next; hdr->seq_ctrl = cpu_to_le16(tid->seq_next << IEEE80211_SEQ_SEQ_SHIFT); - - if (fragno) - hdr->seq_ctrl |= cpu_to_le16(fragno); - - if (!ieee80211_has_morefrags(hdr->frame_control)) - INCR(tid->seq_next, IEEE80211_SEQ_MAX); - + INCR(tid->seq_next, IEEE80211_SEQ_MAX); bf->bf_state.seqno = seqno; } diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index e4d6dc2e37d1..c79e6638c88d 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -4827,14 +4827,8 @@ static int b43_op_start(struct ieee80211_hw *hw) out_mutex_unlock: mutex_unlock(&wl->mutex); - /* - * Configuration may have been overwritten during initialization. - * Reload the configuration, but only if initialization was - * successful. Reloading the configuration after a failed init - * may hang the system. - */ - if (!err) - b43_op_config(hw, ~0); + /* reload configuration */ + b43_op_config(hw, ~0); return err; } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 758c115b556e..4688904908ec 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -108,15 +108,9 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, sdio_release_host(sdfunc); } } else if (regaddr == SDIO_CCCR_ABORT) { - sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), - GFP_KERNEL); - if (!sdfunc) - return -ENOMEM; - sdfunc->num = 0; sdio_claim_host(sdfunc); sdio_writeb(sdfunc, *byte, regaddr, &err_ret); sdio_release_host(sdfunc); - kfree(sdfunc); } else if (regaddr < 0xF0) { brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr); err_ret = -EPERM; @@ -492,7 +486,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, kfree(bus_if); return -ENOMEM; } - sdiodev->func[0] = func; + sdiodev->func[0] = func->card->sdio_func[0]; sdiodev->func[1] = func; sdiodev->bus_if = bus_if; bus_if->bus_priv.sdio = sdiodev; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index eb3829b03cd3..2bf5dda29291 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -574,8 +574,6 @@ struct brcmf_sdio { struct task_struct *dpc_tsk; struct completion dpc_wait; - struct list_head dpc_tsklst; - spinlock_t dpc_tl_lock; struct semaphore sdsem; @@ -2596,58 +2594,29 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) return resched; } -static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus) -{ - struct list_head *new_hd; - unsigned long flags; - - if (in_interrupt()) - new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC); - else - new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL); - if (new_hd == NULL) - return; - - spin_lock_irqsave(&bus->dpc_tl_lock, flags); - list_add_tail(new_hd, &bus->dpc_tsklst); - spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); -} - static int brcmf_sdbrcm_dpc_thread(void *data) { struct brcmf_sdio *bus = (struct brcmf_sdio *) data; - struct list_head *cur_hd, *tmp_hd; - unsigned long flags; allow_signal(SIGTERM); /* Run until signal received */ while (1) { if (kthread_should_stop()) break; - - if (list_empty(&bus->dpc_tsklst)) - if (wait_for_completion_interruptible(&bus->dpc_wait)) - break; - - spin_lock_irqsave(&bus->dpc_tl_lock, flags); - list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) { - spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); - - if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) { + if (!wait_for_completion_interruptible(&bus->dpc_wait)) { + /* Call bus dpc unless it indicated down + (then clean stop) */ + if (bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN) { + if (brcmf_sdbrcm_dpc(bus)) + complete(&bus->dpc_wait); + } else { /* after stopping the bus, exit thread */ brcmf_sdbrcm_bus_stop(bus->sdiodev->dev); bus->dpc_tsk = NULL; break; } - - if (brcmf_sdbrcm_dpc(bus)) - brcmf_sdbrcm_adddpctsk(bus); - - spin_lock_irqsave(&bus->dpc_tl_lock, flags); - list_del(cur_hd); - kfree(cur_hd); - } - spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); + } else + break; } return 0; } @@ -2700,10 +2669,8 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) /* Schedule DPC if needed to send queued packet(s) */ if (!bus->dpc_sched) { bus->dpc_sched = true; - if (bus->dpc_tsk) { - brcmf_sdbrcm_adddpctsk(bus); + if (bus->dpc_tsk) complete(&bus->dpc_wait); - } } return ret; @@ -3547,10 +3514,8 @@ void brcmf_sdbrcm_isr(void *arg) brcmf_dbg(ERROR, "isr w/o interrupt configured!\n"); bus->dpc_sched = true; - if (bus->dpc_tsk) { - brcmf_sdbrcm_adddpctsk(bus); + if (bus->dpc_tsk) complete(&bus->dpc_wait); - } } static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) @@ -3594,10 +3559,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->ipend = true; bus->dpc_sched = true; - if (bus->dpc_tsk) { - brcmf_sdbrcm_adddpctsk(bus); + if (bus->dpc_tsk) complete(&bus->dpc_wait); - } } } @@ -3934,8 +3897,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) } /* Initialize DPC thread */ init_completion(&bus->dpc_wait); - INIT_LIST_HEAD(&bus->dpc_tsklst); - spin_lock_init(&bus->dpc_tl_lock); bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread, bus, "brcmf_dpc"); if (IS_ERR(bus->dpc_tsk)) { diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c index b4d92792c502..231ddf4a674f 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -847,7 +847,8 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) */ if (!(txs->status & TX_STATUS_AMPDU) && (txs->status & TX_STATUS_INTERMEDIATE)) { - BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n"); + wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n", + __func__); return false; } @@ -7613,7 +7614,6 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh, { int len_mpdu; struct ieee80211_rx_status rx_status; - struct ieee80211_hdr *hdr; memset(&rx_status, 0, sizeof(rx_status)); prep_mac80211_status(wlc, rxh, p, &rx_status); @@ -7623,13 +7623,6 @@ brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh, skb_pull(p, D11_PHY_HDR_LEN); __skb_trim(p, len_mpdu); - /* unmute transmit */ - if (wlc->hw->suspended_fifos) { - hdr = (struct ieee80211_hdr *)p->data; - if (ieee80211_is_beacon(hdr->frame_control)) - brcms_b_mute(wlc->hw, false); - } - memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status)); ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); } diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c index 1779db3aa2b0..2b022571a859 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c @@ -2191,7 +2191,6 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) { int rc = 0; unsigned long flags; - unsigned long now, end; spin_lock_irqsave(&priv->lock, flags); if (priv->status & STATUS_HCMD_ACTIVE) { @@ -2233,20 +2232,10 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd) } spin_unlock_irqrestore(&priv->lock, flags); - now = jiffies; - end = now + HOST_COMPLETE_TIMEOUT; -again: rc = wait_event_interruptible_timeout(priv->wait_command_queue, !(priv-> status & STATUS_HCMD_ACTIVE), - end - now); - if (rc < 0) { - now = jiffies; - if (time_before(now, end)) - goto again; - rc = 0; - } - + HOST_COMPLETE_TIMEOUT); if (rc == 0) { spin_lock_irqsave(&priv->lock, flags); if (priv->status & STATUS_HCMD_ACTIVE) { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c index 8d80e233bc7a..5b0d888f746b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -46,8 +46,8 @@ #include "iwl-prph.h" /* Highest firmware API version supported */ -#define IWL1000_UCODE_API_MAX 5 -#define IWL100_UCODE_API_MAX 5 +#define IWL1000_UCODE_API_MAX 6 +#define IWL100_UCODE_API_MAX 6 /* Oldest version we won't warn about */ #define IWL1000_UCODE_API_OK 5 @@ -226,5 +226,5 @@ const struct iwl_cfg iwl100_bg_cfg = { IWL_DEVICE_100, }; -MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_OK)); +MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX)); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c index ea108622e0bd..5635b9e2c69e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -51,10 +51,10 @@ #define IWL135_UCODE_API_MAX 6 /* Oldest version we won't warn about */ -#define IWL2030_UCODE_API_OK 6 -#define IWL2000_UCODE_API_OK 6 -#define IWL105_UCODE_API_OK 6 -#define IWL135_UCODE_API_OK 6 +#define IWL2030_UCODE_API_OK 5 +#define IWL2000_UCODE_API_OK 5 +#define IWL105_UCODE_API_OK 5 +#define IWL135_UCODE_API_OK 5 /* Lowest firmware API version supported */ #define IWL2030_UCODE_API_MIN 5 @@ -328,7 +328,7 @@ const struct iwl_cfg iwl135_bgn_cfg = { .ht_params = &iwl2000_ht_params, }; -MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_OK)); -MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_OK)); -MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_OK)); +MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL135_MODULE_FIRMWARE(IWL135_UCODE_API_MAX)); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c index de0920c74cdd..a805e97b89af 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -51,10 +51,6 @@ #define IWL5000_UCODE_API_MAX 5 #define IWL5150_UCODE_API_MAX 2 -/* Oldest version we won't warn about */ -#define IWL5000_UCODE_API_OK 5 -#define IWL5150_UCODE_API_OK 2 - /* Lowest firmware API version supported */ #define IWL5000_UCODE_API_MIN 1 #define IWL5150_UCODE_API_MIN 1 @@ -330,7 +326,6 @@ static const struct iwl_ht_params iwl5000_ht_params = { #define IWL_DEVICE_5000 \ .fw_name_pre = IWL5000_FW_PRE, \ .ucode_api_max = IWL5000_UCODE_API_MAX, \ - .ucode_api_ok = IWL5000_UCODE_API_OK, \ .ucode_api_min = IWL5000_UCODE_API_MIN, \ .max_inst_size = IWLAGN_RTC_INST_SIZE, \ .max_data_size = IWLAGN_RTC_DATA_SIZE, \ @@ -376,7 +371,6 @@ const struct iwl_cfg iwl5350_agn_cfg = { .name = "Intel(R) WiMAX/WiFi Link 5350 AGN", .fw_name_pre = IWL5000_FW_PRE, .ucode_api_max = IWL5000_UCODE_API_MAX, - .ucode_api_ok = IWL5000_UCODE_API_OK, .ucode_api_min = IWL5000_UCODE_API_MIN, .max_inst_size = IWLAGN_RTC_INST_SIZE, .max_data_size = IWLAGN_RTC_DATA_SIZE, @@ -392,7 +386,6 @@ const struct iwl_cfg iwl5350_agn_cfg = { #define IWL_DEVICE_5150 \ .fw_name_pre = IWL5150_FW_PRE, \ .ucode_api_max = IWL5150_UCODE_API_MAX, \ - .ucode_api_ok = IWL5150_UCODE_API_OK, \ .ucode_api_min = IWL5150_UCODE_API_MIN, \ .max_inst_size = IWLAGN_RTC_INST_SIZE, \ .max_data_size = IWLAGN_RTC_DATA_SIZE, \ @@ -416,5 +409,5 @@ const struct iwl_cfg iwl5150_abg_cfg = { IWL_DEVICE_5150, }; -MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_OK)); +MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX)); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c index f0c91505a7f7..64060cd738b5 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -53,8 +53,6 @@ /* Oldest version we won't warn about */ #define IWL6000_UCODE_API_OK 4 #define IWL6000G2_UCODE_API_OK 5 -#define IWL6050_UCODE_API_OK 5 -#define IWL6000G2B_UCODE_API_OK 6 /* Lowest firmware API version supported */ #define IWL6000_UCODE_API_MIN 4 @@ -390,7 +388,7 @@ const struct iwl_cfg iwl6005_2agn_mow2_cfg = { #define IWL_DEVICE_6030 \ .fw_name_pre = IWL6030_FW_PRE, \ .ucode_api_max = IWL6000G2_UCODE_API_MAX, \ - .ucode_api_ok = IWL6000G2B_UCODE_API_OK, \ + .ucode_api_ok = IWL6000G2_UCODE_API_OK, \ .ucode_api_min = IWL6000G2_UCODE_API_MIN, \ .max_inst_size = IWL60_RTC_INST_SIZE, \ .max_data_size = IWL60_RTC_DATA_SIZE, \ @@ -559,6 +557,6 @@ const struct iwl_cfg iwl6000_3agn_cfg = { }; MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_OK)); -MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_OK)); +MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c index 2a9a16f901c3..f1226dbf789d 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -863,6 +863,7 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) void iwlagn_prepare_restart(struct iwl_priv *priv) { + struct iwl_rxon_context *ctx; bool bt_full_concurrent; u8 bt_ci_compliance; u8 bt_load; @@ -871,6 +872,8 @@ void iwlagn_prepare_restart(struct iwl_priv *priv) lockdep_assert_held(&priv->mutex); + for_each_context(priv, ctx) + ctx->vif = NULL; priv->is_open = 0; /* diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-fh.h b/trunk/drivers/net/wireless/iwlwifi/iwl-fh.h index 74bce97a8600..90208094b8eb 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -104,29 +104,15 @@ * (see struct iwl_tfd_frame). These 16 pointer registers are offset by 0x04 * bytes from one another. Each TFD circular buffer in DRAM must be 256-byte * aligned (address bits 0-7 must be 0). - * Later devices have 20 (5000 series) or 30 (higher) queues, but the registers - * for them are in different places. * * Bit fields in each pointer register: * 27-0: TFD CB physical base address [35:8], must be 256-byte aligned */ -#define FH_MEM_CBBC_0_15_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0) -#define FH_MEM_CBBC_0_15_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xA10) -#define FH_MEM_CBBC_16_19_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xBF0) -#define FH_MEM_CBBC_16_19_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xC00) -#define FH_MEM_CBBC_20_31_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0xB20) -#define FH_MEM_CBBC_20_31_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xB80) - -/* Find TFD CB base pointer for given queue */ -static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) -{ - if (chnl < 16) - return FH_MEM_CBBC_0_15_LOWER_BOUND + 4 * chnl; - if (chnl < 20) - return FH_MEM_CBBC_16_19_LOWER_BOUND + 4 * (chnl - 16); - WARN_ON_ONCE(chnl >= 32); - return FH_MEM_CBBC_20_31_LOWER_BOUND + 4 * (chnl - 20); -} +#define FH_MEM_CBBC_LOWER_BOUND (FH_MEM_LOWER_BOUND + 0x9D0) +#define FH_MEM_CBBC_UPPER_BOUND (FH_MEM_LOWER_BOUND + 0xA10) + +/* Find TFD CB base pointer for given queue (range 0-15). */ +#define FH_MEM_CBBC_QUEUE(x) (FH_MEM_CBBC_LOWER_BOUND + (x) * 0x4) /** diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c index c24a7134a6f9..b6805f8e9a01 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -1244,7 +1244,6 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, struct iwl_rxon_context *tmp, *ctx = NULL; int err; enum nl80211_iftype viftype = ieee80211_vif_type_p2p(vif); - bool reset = false; IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", viftype, vif->addr); @@ -1266,13 +1265,6 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, tmp->interface_modes | tmp->exclusive_interface_modes; if (tmp->vif) { - /* On reset we need to add the same interface again */ - if (tmp->vif == vif) { - reset = true; - ctx = tmp; - break; - } - /* check if this busy context is exclusive */ if (tmp->exclusive_interface_modes & BIT(tmp->vif->type)) { @@ -1299,7 +1291,7 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, ctx->vif = vif; err = iwl_setup_interface(priv, ctx); - if (!err || reset) + if (!err) goto out; ctx->vif = NULL; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-prph.h b/trunk/drivers/net/wireless/iwlwifi/iwl-prph.h index 3b1069290fa9..75dc20bd965b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -223,33 +223,12 @@ #define SCD_AIT (SCD_BASE + 0x0c) #define SCD_TXFACT (SCD_BASE + 0x10) #define SCD_ACTIVE (SCD_BASE + 0x14) +#define SCD_QUEUE_WRPTR(x) (SCD_BASE + 0x18 + (x) * 4) +#define SCD_QUEUE_RDPTR(x) (SCD_BASE + 0x68 + (x) * 4) #define SCD_QUEUECHAIN_SEL (SCD_BASE + 0xe8) #define SCD_AGGR_SEL (SCD_BASE + 0x248) #define SCD_INTERRUPT_MASK (SCD_BASE + 0x108) - -static inline unsigned int SCD_QUEUE_WRPTR(unsigned int chnl) -{ - if (chnl < 20) - return SCD_BASE + 0x18 + chnl * 4; - WARN_ON_ONCE(chnl >= 32); - return SCD_BASE + 0x284 + (chnl - 20) * 4; -} - -static inline unsigned int SCD_QUEUE_RDPTR(unsigned int chnl) -{ - if (chnl < 20) - return SCD_BASE + 0x68 + chnl * 4; - WARN_ON_ONCE(chnl >= 32); - return SCD_BASE + 0x2B4 + (chnl - 20) * 4; -} - -static inline unsigned int SCD_QUEUE_STATUS_BITS(unsigned int chnl) -{ - if (chnl < 20) - return SCD_BASE + 0x10c + chnl * 4; - WARN_ON_ONCE(chnl >= 32); - return SCD_BASE + 0x384 + (chnl - 20) * 4; -} +#define SCD_QUEUE_STATUS_BITS(x) (SCD_BASE + 0x10c + (x) * 4) /*********************** END TX SCHEDULER *************************************/ diff --git a/trunk/drivers/net/wireless/libertas/cfg.c b/trunk/drivers/net/wireless/libertas/cfg.c index 2fa879b015b6..3fa1ecebadfd 100644 --- a/trunk/drivers/net/wireless/libertas/cfg.c +++ b/trunk/drivers/net/wireless/libertas/cfg.c @@ -103,7 +103,7 @@ static const u32 cipher_suites[] = { * Convert NL80211's auth_type to the one from Libertas, see chapter 5.9.1 * in the firmware spec */ -static int lbs_auth_to_authtype(enum nl80211_auth_type auth_type) +static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type) { int ret = -ENOTSUPP; @@ -1411,12 +1411,7 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev, goto done; } - ret = lbs_set_authtype(priv, sme); - if (ret == -ENOTSUPP) { - wiphy_err(wiphy, "unsupported authtype 0x%x\n", sme->auth_type); - goto done; - } - + lbs_set_authtype(priv, sme); lbs_set_radio(priv, preamble, 1); /* Do the actual association */ diff --git a/trunk/drivers/net/wireless/mwifiex/pcie.h b/trunk/drivers/net/wireless/mwifiex/pcie.h index 2f218f9a3fd3..445ff21772e2 100644 --- a/trunk/drivers/net/wireless/mwifiex/pcie.h +++ b/trunk/drivers/net/wireless/mwifiex/pcie.h @@ -48,15 +48,15 @@ #define PCIE_HOST_INT_STATUS_MASK 0xC3C #define PCIE_SCRATCH_2_REG 0xC40 #define PCIE_SCRATCH_3_REG 0xC44 -#define PCIE_SCRATCH_4_REG 0xCD0 -#define PCIE_SCRATCH_5_REG 0xCD4 -#define PCIE_SCRATCH_6_REG 0xCD8 -#define PCIE_SCRATCH_7_REG 0xCDC -#define PCIE_SCRATCH_8_REG 0xCE0 -#define PCIE_SCRATCH_9_REG 0xCE4 -#define PCIE_SCRATCH_10_REG 0xCE8 -#define PCIE_SCRATCH_11_REG 0xCEC -#define PCIE_SCRATCH_12_REG 0xCF0 +#define PCIE_SCRATCH_4_REG 0xCC0 +#define PCIE_SCRATCH_5_REG 0xCC4 +#define PCIE_SCRATCH_6_REG 0xCC8 +#define PCIE_SCRATCH_7_REG 0xCCC +#define PCIE_SCRATCH_8_REG 0xCD0 +#define PCIE_SCRATCH_9_REG 0xCD4 +#define PCIE_SCRATCH_10_REG 0xCD8 +#define PCIE_SCRATCH_11_REG 0xCDC +#define PCIE_SCRATCH_12_REG 0xCE0 #define CPU_INTR_DNLD_RDY BIT(0) #define CPU_INTR_DOOR_BELL BIT(1) diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.c b/trunk/drivers/net/wireless/rtlwifi/pci.c index cc15fdb36060..288b035a3579 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.c +++ b/trunk/drivers/net/wireless/rtlwifi/pci.c @@ -1941,7 +1941,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev) rtl_deinit_deferred_work(hw); rtlpriv->intf_ops->adapter_stop(hw); } - rtlpriv->cfg->ops->disable_interrupt(hw); /*deinit rfkill */ rtl_deinit_rfkill(hw); diff --git a/trunk/drivers/net/wireless/wl1251/main.c b/trunk/drivers/net/wireless/wl1251/main.c index d1afb8e3b2ef..41302c7b1ad0 100644 --- a/trunk/drivers/net/wireless/wl1251/main.c +++ b/trunk/drivers/net/wireless/wl1251/main.c @@ -479,7 +479,6 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->tx_work); cancel_work_sync(&wl->filter_work); - cancel_delayed_work_sync(&wl->elp_work); mutex_lock(&wl->mutex); diff --git a/trunk/drivers/net/wireless/wl1251/sdio.c b/trunk/drivers/net/wireless/wl1251/sdio.c index 1b851f650e07..f78694295c39 100644 --- a/trunk/drivers/net/wireless/wl1251/sdio.c +++ b/trunk/drivers/net/wireless/wl1251/sdio.c @@ -315,8 +315,8 @@ static void __devexit wl1251_sdio_remove(struct sdio_func *func) if (wl->irq) free_irq(wl->irq, wl); - wl1251_free_hw(wl); kfree(wl_sdio); + wl1251_free_hw(wl); sdio_claim_host(func); sdio_release_irq(func); diff --git a/trunk/drivers/pci/Makefile b/trunk/drivers/pci/Makefile index 165274c064bc..083a49fee56a 100644 --- a/trunk/drivers/pci/Makefile +++ b/trunk/drivers/pci/Makefile @@ -42,7 +42,6 @@ obj-$(CONFIG_UNICORE32) += setup-bus.o setup-irq.o obj-$(CONFIG_PARISC) += setup-bus.o obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o obj-$(CONFIG_PPC) += setup-bus.o -obj-$(CONFIG_FRV) += setup-bus.o obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o obj-$(CONFIG_X86_VISWS) += setup-irq.o obj-$(CONFIG_MN10300) += setup-bus.o diff --git a/trunk/drivers/pci/pci-acpi.c b/trunk/drivers/pci/pci-acpi.c index 1929c0c63b75..0f150f271c2a 100644 --- a/trunk/drivers/pci/pci-acpi.c +++ b/trunk/drivers/pci/pci-acpi.c @@ -200,7 +200,7 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) return PCI_D1; case ACPI_STATE_D2: return PCI_D2; - case ACPI_STATE_D3_HOT: + case ACPI_STATE_D3: return PCI_D3hot; case ACPI_STATE_D3_COLD: return PCI_D3cold; @@ -223,7 +223,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) [PCI_D0] = ACPI_STATE_D0, [PCI_D1] = ACPI_STATE_D1, [PCI_D2] = ACPI_STATE_D2, - [PCI_D3hot] = ACPI_STATE_D3_HOT, + [PCI_D3hot] = ACPI_STATE_D3, [PCI_D3cold] = ACPI_STATE_D3 }; int error = -EINVAL; diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 111569ccab43..d20f1334792b 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -991,8 +991,8 @@ static void pci_restore_config_dword(struct pci_dev *pdev, int offset, } } -static void pci_restore_config_space_range(struct pci_dev *pdev, - int start, int end, int retry) +static void pci_restore_config_space(struct pci_dev *pdev, int start, int end, + int retry) { int index; @@ -1002,18 +1002,6 @@ static void pci_restore_config_space_range(struct pci_dev *pdev, retry); } -static void pci_restore_config_space(struct pci_dev *pdev) -{ - if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL) { - pci_restore_config_space_range(pdev, 10, 15, 0); - /* Restore BARs before the command register. */ - pci_restore_config_space_range(pdev, 4, 9, 10); - pci_restore_config_space_range(pdev, 0, 3, 0); - } else { - pci_restore_config_space_range(pdev, 0, 15, 0); - } -} - /** * pci_restore_state - Restore the saved state of a PCI device * @dev: - PCI device that we're dealing with @@ -1027,7 +1015,13 @@ void pci_restore_state(struct pci_dev *dev) pci_restore_pcie_state(dev); pci_restore_ats_state(dev); - pci_restore_config_space(dev); + pci_restore_config_space(dev, 10, 15, 0); + /* + * The Base Address register should be programmed before the command + * register(s) + */ + pci_restore_config_space(dev, 4, 9, 10); + pci_restore_config_space(dev, 0, 3, 0); pci_restore_pcix_state(dev); pci_restore_msi_state(dev); diff --git a/trunk/drivers/pinctrl/core.c b/trunk/drivers/pinctrl/core.c index df6296c5f47b..ec3b8cc188af 100644 --- a/trunk/drivers/pinctrl/core.c +++ b/trunk/drivers/pinctrl/core.c @@ -908,6 +908,10 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) const struct pinctrl_ops *ops = pctldev->desc->pctlops; unsigned selector = 0; + /* No grouping */ + if (!ops) + return 0; + mutex_lock(&pinctrl_mutex); seq_puts(s, "registered pin groups:\n"); @@ -1221,19 +1225,6 @@ static void pinctrl_remove_device_debugfs(struct pinctrl_dev *pctldev) #endif -static int pinctrl_check_ops(struct pinctrl_dev *pctldev) -{ - const struct pinctrl_ops *ops = pctldev->desc->pctlops; - - if (!ops || - !ops->list_groups || - !ops->get_group_name || - !ops->get_group_pins) - return -EINVAL; - - return 0; -} - /** * pinctrl_register() - register a pin controller device * @pctldesc: descriptor for this pin controller @@ -1265,14 +1256,6 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, INIT_LIST_HEAD(&pctldev->gpio_ranges); pctldev->dev = dev; - /* check core ops for sanity */ - ret = pinctrl_check_ops(pctldev); - if (ret) { - pr_err("%s pinctrl ops lacks necessary functions\n", - pctldesc->name); - goto out_err; - } - /* If we're implementing pinmuxing, check the ops for sanity */ if (pctldesc->pmxops) { ret = pinmux_check_ops(pctldev); diff --git a/trunk/drivers/platform/x86/acerhdf.c b/trunk/drivers/platform/x86/acerhdf.c index 639db4d0aa76..bc8384c6f3eb 100644 --- a/trunk/drivers/platform/x86/acerhdf.c +++ b/trunk/drivers/platform/x86/acerhdf.c @@ -50,7 +50,7 @@ */ #undef START_IN_KERNEL_MODE -#define DRV_VER "0.5.26" +#define DRV_VER "0.5.24" /* * According to the Atom N270 datasheet, @@ -83,8 +83,8 @@ static int kernelmode; #endif static unsigned int interval = 10; -static unsigned int fanon = 60000; -static unsigned int fanoff = 53000; +static unsigned int fanon = 63000; +static unsigned int fanoff = 58000; static unsigned int verbose; static unsigned int fanstate = ACERHDF_FAN_AUTO; static char force_bios[16]; @@ -150,8 +150,6 @@ static const struct bios_settings_t bios_tbl[] = { {"Acer", "AOA150", "v0.3308", 0x55, 0x58, {0x20, 0x00} }, {"Acer", "AOA150", "v0.3309", 0x55, 0x58, {0x20, 0x00} }, {"Acer", "AOA150", "v0.3310", 0x55, 0x58, {0x20, 0x00} }, - /* LT1005u */ - {"Acer", "LT-10Q", "v0.3310", 0x55, 0x58, {0x20, 0x00} }, /* Acer 1410 */ {"Acer", "Aspire 1410", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1410", "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, @@ -163,7 +161,6 @@ static const struct bios_settings_t bios_tbl[] = { {"Acer", "Aspire 1410", "v1.3303", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1410", "v1.3308", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1410", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1410", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, /* Acer 1810xx */ {"Acer", "Aspire 1810TZ", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1810T", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, @@ -186,44 +183,29 @@ static const struct bios_settings_t bios_tbl[] = { {"Acer", "Aspire 1810TZ", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1810T", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1810TZ", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810T", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, /* Acer 531 */ - {"Acer", "AO531h", "v0.3104", 0x55, 0x58, {0x20, 0x00} }, {"Acer", "AO531h", "v0.3201", 0x55, 0x58, {0x20, 0x00} }, - {"Acer", "AO531h", "v0.3304", 0x55, 0x58, {0x20, 0x00} }, - /* Acer 751 */ - {"Acer", "AO751h", "V0.3212", 0x55, 0x58, {0x21, 0x00} }, - /* Acer 1825 */ - {"Acer", "Aspire 1825PTZ", "V1.3118", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1825PTZ", "V1.3127", 0x55, 0x58, {0x9e, 0x00} }, - /* Acer TravelMate 7730 */ - {"Acer", "TravelMate 7730G", "v0.3509", 0x55, 0x58, {0xaf, 0x00} }, /* Gateway */ - {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, - {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} }, - {"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x9e, 0x00} }, - {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, - {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, - {"Gateway", "LT31", "v1.3303t", 0x55, 0x58, {0x9e, 0x00} }, + {"Gateway", "AOA110", "v0.3103", 0x55, 0x58, {0x21, 0x00} }, + {"Gateway", "AOA150", "v0.3103", 0x55, 0x58, {0x20, 0x00} }, + {"Gateway", "LT31", "v1.3103", 0x55, 0x58, {0x9e, 0x00} }, + {"Gateway", "LT31", "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, + {"Gateway", "LT31", "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, /* Packard Bell */ - {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} }, - {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, - {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, - {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, - {"Packard Bell", "ENBFT", "V1.3118", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "ENBFT", "V1.3127", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3115", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3117", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v0.3119", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMU", "v1.3204", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMA", "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMA", "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTMA", "v1.3303t", 0x55, 0x58, {0x9e, 0x00} }, - {"Packard Bell", "DOTVR46", "v1.3308", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOA150", "v0.3104", 0x55, 0x58, {0x21, 0x00} }, + {"Packard Bell", "DOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, + {"Packard Bell", "AOA110", "v0.3105", 0x55, 0x58, {0x21, 0x00} }, + {"Packard Bell", "AOA150", "v0.3105", 0x55, 0x58, {0x20, 0x00} }, + {"Packard Bell", "DOTMU", "v1.3303", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3120", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3108", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3113", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3115", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3117", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v0.3119", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMU", "v1.3204", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMA", "v1.3201", 0x55, 0x58, {0x9e, 0x00} }, + {"Packard Bell", "DOTMA", "v1.3302", 0x55, 0x58, {0x9e, 0x00} }, /* pewpew-terminator */ {"", "", "", 0, 0, {0, 0} } }; @@ -719,20 +701,15 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Peter Feuerer"); MODULE_DESCRIPTION("Aspire One temperature and fan driver"); MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:"); -MODULE_ALIAS("dmi:*:*Acer*:pnAO751h*:"); MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1410*:"); MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1810*:"); -MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1825PTZ:"); MODULE_ALIAS("dmi:*:*Acer*:pnAO531*:"); -MODULE_ALIAS("dmi:*:*Acer*:TravelMate*7730G:"); MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:"); MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:"); MODULE_ALIAS("dmi:*:*Packard*Bell*:pnAOA*:"); MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOA*:"); MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMU*:"); -MODULE_ALIAS("dmi:*:*Packard*Bell*:pnENBFT*:"); MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMA*:"); -MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTVR46*:"); module_init(acerhdf_init); module_exit(acerhdf_exit); diff --git a/trunk/drivers/platform/x86/dell-laptop.c b/trunk/drivers/platform/x86/dell-laptop.c index e6c08ee8d46c..a05fc9c955d8 100644 --- a/trunk/drivers/platform/x86/dell-laptop.c +++ b/trunk/drivers/platform/x86/dell-laptop.c @@ -212,7 +212,6 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { }, .driver_data = &quirk_dell_vostro_v130, }, - { } }; static struct calling_interface_buffer *buffer; diff --git a/trunk/drivers/platform/x86/intel_ips.c b/trunk/drivers/platform/x86/intel_ips.c index 0ffdb3cde2bb..f7ba316e0ed6 100644 --- a/trunk/drivers/platform/x86/intel_ips.c +++ b/trunk/drivers/platform/x86/intel_ips.c @@ -1565,7 +1565,7 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) ips->poll_turbo_status = true; if (!ips_get_i915_syms(ips)) { - dev_info(&dev->dev, "failed to get i915 symbols, graphics turbo disabled until i915 loads\n"); + dev_err(&dev->dev, "failed to get i915 symbols, graphics turbo disabled\n"); ips->gpu_turbo_enabled = false; } else { dev_dbg(&dev->dev, "graphics turbo enabled\n"); diff --git a/trunk/drivers/platform/x86/intel_mid_powerbtn.c b/trunk/drivers/platform/x86/intel_mid_powerbtn.c index bcbad8452a6f..0a3594c7e912 100644 --- a/trunk/drivers/platform/x86/intel_mid_powerbtn.c +++ b/trunk/drivers/platform/x86/intel_mid_powerbtn.c @@ -78,7 +78,7 @@ static int __devinit mfld_pb_probe(struct platform_device *pdev) input_set_capability(input, EV_KEY, KEY_POWER); - error = request_threaded_irq(irq, NULL, mfld_pb_isr, IRQF_NO_SUSPEND, + error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0, DRIVER_NAME, input); if (error) { dev_err(&pdev->dev, "Unable to request irq %d for mfld power" diff --git a/trunk/drivers/rtc/rtc-ds1307.c b/trunk/drivers/rtc/rtc-ds1307.c index c293d0cdb104..cd188ab72f79 100644 --- a/trunk/drivers/rtc/rtc-ds1307.c +++ b/trunk/drivers/rtc/rtc-ds1307.c @@ -902,7 +902,6 @@ static int __devinit ds1307_probe(struct i2c_client *client, } ds1307->nvram->attr.name = "nvram"; ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR; - sysfs_bin_attr_init(ds1307->nvram); ds1307->nvram->read = ds1307_nvram_read, ds1307->nvram->write = ds1307_nvram_write, ds1307->nvram->size = chip->nvram_size; diff --git a/trunk/drivers/rtc/rtc-mpc5121.c b/trunk/drivers/rtc/rtc-mpc5121.c index 029e421baaed..42f5f829b3ee 100644 --- a/trunk/drivers/rtc/rtc-mpc5121.c +++ b/trunk/drivers/rtc/rtc-mpc5121.c @@ -360,11 +360,12 @@ static int __devinit mpc5121_rtc_probe(struct platform_device *op) &mpc5200_rtc_ops, THIS_MODULE); } + rtc->rtc->uie_unsupported = 1; + if (IS_ERR(rtc->rtc)) { err = PTR_ERR(rtc->rtc); goto out_free_irq; } - rtc->rtc->uie_unsupported = 1; return 0; diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index bc2e8a7c265b..c21871a4e73d 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -2844,7 +2844,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( sector_t recid, trkid; unsigned int offs; unsigned int count, count_to_trk_end; - int ret; basedev = block->base; if (rq_data_dir(req) == READ) { @@ -2885,8 +2884,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( itcw = itcw_init(cqr->data, itcw_size, itcw_op, 0, ctidaw, 0); if (IS_ERR(itcw)) { - ret = -EINVAL; - goto out_error; + dasd_sfree_request(cqr, startdev); + return ERR_PTR(-EINVAL); } cqr->cpaddr = itcw_get_tcw(itcw); if (prepare_itcw(itcw, first_trk, last_trk, @@ -2898,8 +2897,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( /* Clock not in sync and XRC is enabled. * Try again later. */ - ret = -EAGAIN; - goto out_error; + dasd_sfree_request(cqr, startdev); + return ERR_PTR(-EAGAIN); } len_to_track_end = 0; /* @@ -2938,10 +2937,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( tidaw_flags = 0; last_tidaw = itcw_add_tidaw(itcw, tidaw_flags, dst, part_len); - if (IS_ERR(last_tidaw)) { - ret = -EINVAL; - goto out_error; - } + if (IS_ERR(last_tidaw)) + return ERR_PTR(-EINVAL); dst += part_len; } } @@ -2950,10 +2947,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( dst = page_address(bv->bv_page) + bv->bv_offset; last_tidaw = itcw_add_tidaw(itcw, 0x00, dst, bv->bv_len); - if (IS_ERR(last_tidaw)) { - ret = -EINVAL; - goto out_error; - } + if (IS_ERR(last_tidaw)) + return ERR_PTR(-EINVAL); } } last_tidaw->flags |= TIDAW_FLAGS_LAST; @@ -2973,9 +2968,6 @@ static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track( cqr->buildclk = get_clock(); cqr->status = DASD_CQR_FILLED; return cqr; -out_error: - dasd_sfree_request(cqr, startdev); - return ERR_PTR(ret); } static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev, diff --git a/trunk/drivers/s390/char/vmur.c b/trunk/drivers/s390/char/vmur.c index 73bef0bd394c..85f4a9a5d12e 100644 --- a/trunk/drivers/s390/char/vmur.c +++ b/trunk/drivers/s390/char/vmur.c @@ -903,7 +903,7 @@ static int ur_set_online(struct ccw_device *cdev) goto fail_urdev_put; } - urd->char_device->ops = &ur_fops; + cdev_init(urd->char_device, &ur_fops); urd->char_device->dev = MKDEV(major, minor); urd->char_device->owner = ur_fops.owner; diff --git a/trunk/drivers/s390/net/qeth_core_main.c b/trunk/drivers/s390/net/qeth_core_main.c index 8334dadc681d..120955c66410 100644 --- a/trunk/drivers/s390/net/qeth_core_main.c +++ b/trunk/drivers/s390/net/qeth_core_main.c @@ -1672,8 +1672,7 @@ static void qeth_configure_blkt_default(struct qeth_card *card, char *prcd) { QETH_DBF_TEXT(SETUP, 2, "cfgblkt"); - if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && - (prcd[76] == 0xF5 || prcd[76] == 0xF6)) { + if (prcd[74] == 0xF0 && prcd[75] == 0xF0 && prcd[76] == 0xF5) { card->info.blkt.time_total = 250; card->info.blkt.inter_packet = 5; card->info.blkt.inter_packet_jumbo = 15; @@ -4541,8 +4540,7 @@ static void qeth_determine_capabilities(struct qeth_card *card) goto out_offline; } qeth_configure_unitaddr(card, prcd); - if (ddev_offline) - qeth_configure_blkt_default(card, prcd); + qeth_configure_blkt_default(card, prcd); kfree(prcd); rc = qdio_get_ssqd_desc(ddev, &card->ssqd); diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 467dc38246f9..e002cd466e9a 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -4549,12 +4549,8 @@ static int ipr_ata_slave_alloc(struct scsi_device *sdev) ENTER; if (sdev->sdev_target) sata_port = sdev->sdev_target->hostdata; - if (sata_port) { + if (sata_port) rc = ata_sas_port_init(sata_port->ap); - if (rc == 0) - rc = ata_sas_sync_probe(sata_port->ap); - } - if (rc) ipr_slave_destroy(sdev); diff --git a/trunk/drivers/scsi/libfc/fc_lport.c b/trunk/drivers/scsi/libfc/fc_lport.c index cc83b66d45b7..ef9560dff295 100644 --- a/trunk/drivers/scsi/libfc/fc_lport.c +++ b/trunk/drivers/scsi/libfc/fc_lport.c @@ -1742,19 +1742,17 @@ void fc_lport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp, mfs = ntohs(flp->fl_csp.sp_bb_data) & FC_SP_BB_DATA_MASK; - - if (mfs < FC_SP_MIN_MAX_PAYLOAD || mfs > FC_SP_MAX_MAX_PAYLOAD) { + if (mfs >= FC_SP_MIN_MAX_PAYLOAD && + mfs <= lport->mfs) { + lport->mfs = mfs; + fc_host_maxframe_size(lport->host) = mfs; + } else { FC_LPORT_DBG(lport, "FLOGI bad mfs:%hu response, " "lport->mfs:%hu\n", mfs, lport->mfs); fc_lport_error(lport, fp); goto err; } - if (mfs <= lport->mfs) { - lport->mfs = mfs; - fc_host_maxframe_size(lport->host) = mfs; - } - csp_flags = ntohs(flp->fl_csp.sp_features); r_a_tov = ntohl(flp->fl_csp.sp_r_a_tov); e_d_tov = ntohl(flp->fl_csp.sp_e_d_tov); diff --git a/trunk/drivers/scsi/libsas/sas_ata.c b/trunk/drivers/scsi/libsas/sas_ata.c index 441d88ad99a7..bc0cecc6ad62 100644 --- a/trunk/drivers/scsi/libsas/sas_ata.c +++ b/trunk/drivers/scsi/libsas/sas_ata.c @@ -546,12 +546,11 @@ static struct ata_port_info sata_port_info = { .port_ops = &sas_sata_ops }; -int sas_ata_init(struct domain_device *found_dev) +int sas_ata_init_host_and_port(struct domain_device *found_dev) { struct sas_ha_struct *ha = found_dev->port->ha; struct Scsi_Host *shost = ha->core.shost; struct ata_port *ap; - int rc; ata_host_init(&found_dev->sata_dev.ata_host, ha->dev, @@ -568,11 +567,8 @@ int sas_ata_init(struct domain_device *found_dev) ap->private_data = found_dev; ap->cbl = ATA_CBL_SATA; ap->scsi_host = shost; - rc = ata_sas_port_init(ap); - if (rc) { - ata_sas_port_destroy(ap); - return rc; - } + /* publish initialized ata port */ + smp_wmb(); found_dev->sata_dev.ap = ap; return 0; @@ -652,13 +648,18 @@ static void sas_get_ata_command_set(struct domain_device *dev) void sas_probe_sata(struct asd_sas_port *port) { struct domain_device *dev, *n; + int err; mutex_lock(&port->ha->disco_mutex); - list_for_each_entry(dev, &port->disco_list, disco_list_node) { + list_for_each_entry_safe(dev, n, &port->disco_list, disco_list_node) { if (!dev_is_sata(dev)) continue; - ata_sas_async_probe(dev->sata_dev.ap); + err = sas_ata_init_host_and_port(dev); + if (err) + sas_fail_probe(dev, __func__, err); + else + ata_sas_async_port_init(dev->sata_dev.ap); } mutex_unlock(&port->ha->disco_mutex); @@ -717,6 +718,18 @@ static void async_sas_ata_eh(void *data, async_cookie_t cookie) sas_put_device(dev); } +static bool sas_ata_dev_eh_valid(struct domain_device *dev) +{ + struct ata_port *ap; + + if (!dev_is_sata(dev)) + return false; + ap = dev->sata_dev.ap; + /* consume fully initialized ata ports */ + smp_rmb(); + return !!ap; +} + void sas_ata_strategy_handler(struct Scsi_Host *shost) { struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); @@ -740,7 +753,7 @@ void sas_ata_strategy_handler(struct Scsi_Host *shost) spin_lock(&port->dev_list_lock); list_for_each_entry(dev, &port->dev_list, dev_list_node) { - if (!dev_is_sata(dev)) + if (!sas_ata_dev_eh_valid(dev)) continue; async_schedule_domain(async_sas_ata_eh, dev, &async); } diff --git a/trunk/drivers/scsi/libsas/sas_discover.c b/trunk/drivers/scsi/libsas/sas_discover.c index 629a0865b130..364679675602 100644 --- a/trunk/drivers/scsi/libsas/sas_discover.c +++ b/trunk/drivers/scsi/libsas/sas_discover.c @@ -72,7 +72,6 @@ static int sas_get_port_device(struct asd_sas_port *port) struct asd_sas_phy *phy; struct sas_rphy *rphy; struct domain_device *dev; - int rc = -ENODEV; dev = sas_alloc_device(); if (!dev) @@ -111,16 +110,9 @@ static int sas_get_port_device(struct asd_sas_port *port) sas_init_dev(dev); - dev->port = port; switch (dev->dev_type) { - case SATA_DEV: - rc = sas_ata_init(dev); - if (rc) { - rphy = NULL; - break; - } - /* fall through */ case SAS_END_DEV: + case SATA_DEV: rphy = sas_end_device_alloc(port->port); break; case EDGE_DEV: @@ -139,14 +131,19 @@ static int sas_get_port_device(struct asd_sas_port *port) if (!rphy) { sas_put_device(dev); - return rc; + return -ENODEV; } + spin_lock_irq(&port->phy_list_lock); + list_for_each_entry(phy, &port->phy_list, port_phy_el) + sas_phy_set_target(phy, dev); + spin_unlock_irq(&port->phy_list_lock); rphy->identify.phy_identifier = phy->phy->identify.phy_identifier; memcpy(dev->sas_addr, port->attached_sas_addr, SAS_ADDR_SIZE); sas_fill_in_rphy(dev, rphy); sas_hash_addr(dev->hashed_sas_addr, dev->sas_addr); port->port_dev = dev; + dev->port = port; dev->linkrate = port->linkrate; dev->min_linkrate = port->linkrate; dev->max_linkrate = port->linkrate; @@ -158,7 +155,6 @@ static int sas_get_port_device(struct asd_sas_port *port) sas_device_set_phy(dev, port->port); dev->rphy = rphy; - get_device(&dev->rphy->dev); if (dev_is_sata(dev) || dev->dev_type == SAS_END_DEV) list_add_tail(&dev->disco_list_node, &port->disco_list); @@ -168,11 +164,6 @@ static int sas_get_port_device(struct asd_sas_port *port) spin_unlock_irq(&port->dev_list_lock); } - spin_lock_irq(&port->phy_list_lock); - list_for_each_entry(phy, &port->phy_list, port_phy_el) - sas_phy_set_target(phy, dev); - spin_unlock_irq(&port->phy_list_lock); - return 0; } @@ -214,7 +205,8 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev) static void sas_probe_devices(struct work_struct *work) { struct domain_device *dev, *n; - struct sas_discovery_event *ev = to_sas_discovery_event(work); + struct sas_discovery_event *ev = + container_of(work, struct sas_discovery_event, work); struct asd_sas_port *port = ev->port; clear_bit(DISCE_PROBE, &port->disc.pending); @@ -263,9 +255,6 @@ void sas_free_device(struct kref *kref) { struct domain_device *dev = container_of(kref, typeof(*dev), kref); - put_device(&dev->rphy->dev); - dev->rphy = NULL; - if (dev->parent) sas_put_device(dev->parent); @@ -302,7 +291,8 @@ static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_d static void sas_destruct_devices(struct work_struct *work) { struct domain_device *dev, *n; - struct sas_discovery_event *ev = to_sas_discovery_event(work); + struct sas_discovery_event *ev = + container_of(work, struct sas_discovery_event, work); struct asd_sas_port *port = ev->port; clear_bit(DISCE_DESTRUCT, &port->disc.pending); @@ -312,6 +302,7 @@ static void sas_destruct_devices(struct work_struct *work) sas_remove_children(&dev->rphy->dev); sas_rphy_delete(dev->rphy); + dev->rphy = NULL; sas_unregister_common_dev(port, dev); } } @@ -323,11 +314,11 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev) /* this rphy never saw sas_rphy_add */ list_del_init(&dev->disco_list_node); sas_rphy_free(dev->rphy); + dev->rphy = NULL; sas_unregister_common_dev(port, dev); - return; } - if (!test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) { + if (dev->rphy && !test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) { sas_rphy_unlink(dev->rphy); list_move_tail(&dev->disco_list_node, &port->destroy_list); sas_discover_event(dev->port, DISCE_DESTRUCT); @@ -386,7 +377,8 @@ static void sas_discover_domain(struct work_struct *work) { struct domain_device *dev; int error = 0; - struct sas_discovery_event *ev = to_sas_discovery_event(work); + struct sas_discovery_event *ev = + container_of(work, struct sas_discovery_event, work); struct asd_sas_port *port = ev->port; clear_bit(DISCE_DISCOVER_DOMAIN, &port->disc.pending); @@ -427,6 +419,8 @@ static void sas_discover_domain(struct work_struct *work) if (error) { sas_rphy_free(dev->rphy); + dev->rphy = NULL; + list_del_init(&dev->disco_list_node); spin_lock_irq(&port->dev_list_lock); list_del_init(&dev->dev_list_node); @@ -443,7 +437,8 @@ static void sas_discover_domain(struct work_struct *work) static void sas_revalidate_domain(struct work_struct *work) { int res = 0; - struct sas_discovery_event *ev = to_sas_discovery_event(work); + struct sas_discovery_event *ev = + container_of(work, struct sas_discovery_event, work); struct asd_sas_port *port = ev->port; struct sas_ha_struct *ha = port->ha; @@ -471,25 +466,21 @@ static void sas_revalidate_domain(struct work_struct *work) /* ---------- Events ---------- */ -static void sas_chain_work(struct sas_ha_struct *ha, struct sas_work *sw) +static void sas_chain_work(struct sas_ha_struct *ha, struct work_struct *work) { - /* chained work is not subject to SA_HA_DRAINING or - * SAS_HA_REGISTERED, because it is either submitted in the - * workqueue, or known to be submitted from a context that is - * not racing against draining - */ - scsi_queue_work(ha->core.shost, &sw->work); + /* chained work is not subject to SA_HA_DRAINING or SAS_HA_REGISTERED */ + scsi_queue_work(ha->core.shost, work); } static void sas_chain_event(int event, unsigned long *pending, - struct sas_work *sw, + struct work_struct *work, struct sas_ha_struct *ha) { if (!test_and_set_bit(event, pending)) { unsigned long flags; spin_lock_irqsave(&ha->state_lock, flags); - sas_chain_work(ha, sw); + sas_chain_work(ha, work); spin_unlock_irqrestore(&ha->state_lock, flags); } } @@ -528,7 +519,7 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port) disc->pending = 0; for (i = 0; i < DISC_NUM_EVENTS; i++) { - INIT_SAS_WORK(&disc->disc_work[i].work, sas_event_fns[i]); + INIT_WORK(&disc->disc_work[i].work, sas_event_fns[i]); disc->disc_work[i].port = port; } } diff --git a/trunk/drivers/scsi/libsas/sas_event.c b/trunk/drivers/scsi/libsas/sas_event.c index 4e4292d210c1..16639bbae629 100644 --- a/trunk/drivers/scsi/libsas/sas_event.c +++ b/trunk/drivers/scsi/libsas/sas_event.c @@ -27,21 +27,19 @@ #include "sas_internal.h" #include "sas_dump.h" -void sas_queue_work(struct sas_ha_struct *ha, struct sas_work *sw) +void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work) { if (!test_bit(SAS_HA_REGISTERED, &ha->state)) return; - if (test_bit(SAS_HA_DRAINING, &ha->state)) { - /* add it to the defer list, if not already pending */ - if (list_empty(&sw->drain_node)) - list_add(&sw->drain_node, &ha->defer_q); - } else - scsi_queue_work(ha->core.shost, &sw->work); + if (test_bit(SAS_HA_DRAINING, &ha->state)) + list_add(&work->entry, &ha->defer_q); + else + scsi_queue_work(ha->core.shost, work); } static void sas_queue_event(int event, unsigned long *pending, - struct sas_work *work, + struct work_struct *work, struct sas_ha_struct *ha) { if (!test_and_set_bit(event, pending)) { @@ -57,7 +55,7 @@ static void sas_queue_event(int event, unsigned long *pending, void __sas_drain_work(struct sas_ha_struct *ha) { struct workqueue_struct *wq = ha->core.shost->work_q; - struct sas_work *sw, *_sw; + struct work_struct *w, *_w; set_bit(SAS_HA_DRAINING, &ha->state); /* flush submitters */ @@ -68,9 +66,9 @@ void __sas_drain_work(struct sas_ha_struct *ha) spin_lock_irq(&ha->state_lock); clear_bit(SAS_HA_DRAINING, &ha->state); - list_for_each_entry_safe(sw, _sw, &ha->defer_q, drain_node) { - list_del_init(&sw->drain_node); - sas_queue_work(ha, sw); + list_for_each_entry_safe(w, _w, &ha->defer_q, entry) { + list_del_init(&w->entry); + sas_queue_work(ha, w); } spin_unlock_irq(&ha->state_lock); } @@ -153,7 +151,7 @@ int sas_init_events(struct sas_ha_struct *sas_ha) int i; for (i = 0; i < HA_NUM_EVENTS; i++) { - INIT_SAS_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]); + INIT_WORK(&sas_ha->ha_events[i].work, sas_ha_event_fns[i]); sas_ha->ha_events[i].ha = sas_ha; } diff --git a/trunk/drivers/scsi/libsas/sas_expander.c b/trunk/drivers/scsi/libsas/sas_expander.c index caa0525d2523..05acd9e35fc4 100644 --- a/trunk/drivers/scsi/libsas/sas_expander.c +++ b/trunk/drivers/scsi/libsas/sas_expander.c @@ -202,7 +202,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) u8 sas_addr[SAS_ADDR_SIZE]; struct smp_resp *resp = rsp; struct discover_resp *dr = &resp->disc; - struct sas_ha_struct *ha = dev->port->ha; struct expander_device *ex = &dev->ex_dev; struct ex_phy *phy = &ex->ex_phy[phy_id]; struct sas_rphy *rphy = dev->rphy; @@ -210,8 +209,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) char *type; if (new_phy) { - if (WARN_ON_ONCE(test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state))) - return; phy->phy = sas_phy_alloc(&rphy->dev, phy_id); /* FIXME: error_handling */ @@ -236,8 +233,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) memcpy(sas_addr, phy->attached_sas_addr, SAS_ADDR_SIZE); phy->attached_dev_type = to_dev_type(dr); - if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) - goto out; phy->phy_id = phy_id; phy->linkrate = dr->linkrate; phy->attached_sata_host = dr->attached_sata_host; @@ -245,14 +240,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) phy->attached_sata_ps = dr->attached_sata_ps; phy->attached_iproto = dr->iproto << 1; phy->attached_tproto = dr->tproto << 1; - /* help some expanders that fail to zero sas_address in the 'no - * device' case - */ - if (phy->attached_dev_type == NO_DEVICE || - phy->linkrate < SAS_LINK_RATE_1_5_GBPS) - memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE); - else - memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE); + memcpy(phy->attached_sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE); phy->attached_phy_id = dr->attached_phy_id; phy->phy_change_count = dr->change_count; phy->routing_attr = dr->routing_attr; @@ -278,7 +266,6 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) return; } - out: switch (phy->attached_dev_type) { case SATA_PENDING: type = "stp pending"; @@ -317,15 +304,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp) else return; - /* if the attached device type changed and ata_eh is active, - * make sure we run revalidation when eh completes (see: - * sas_enable_revalidation) - */ - if (test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state)) - set_bit(DISCE_REVALIDATE_DOMAIN, &dev->port->disc.pending); - - SAS_DPRINTK("%sex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", - test_bit(SAS_HA_ATA_EH_ACTIVE, &ha->state) ? "ata: " : "", + SAS_DPRINTK("ex %016llx phy%02d:%c:%X attached: %016llx (%s)\n", SAS_ADDR(dev->sas_addr), phy->phy_id, sas_route_char(dev, phy), phy->linkrate, SAS_ADDR(phy->attached_sas_addr), type); @@ -797,16 +776,13 @@ static struct domain_device *sas_ex_discover_end_dev( if (res) goto out_free; - sas_init_dev(child); - res = sas_ata_init(child); - if (res) - goto out_free; rphy = sas_end_device_alloc(phy->port); - if (!rphy) + if (unlikely(!rphy)) goto out_free; + sas_init_dev(child); + child->rphy = rphy; - get_device(&rphy->dev); list_add_tail(&child->disco_list_node, &parent->port->disco_list); @@ -830,7 +806,6 @@ static struct domain_device *sas_ex_discover_end_dev( sas_init_dev(child); child->rphy = rphy; - get_device(&rphy->dev); sas_fill_in_rphy(child, rphy); list_add_tail(&child->disco_list_node, &parent->port->disco_list); @@ -855,6 +830,8 @@ static struct domain_device *sas_ex_discover_end_dev( out_list_del: sas_rphy_free(child->rphy); + child->rphy = NULL; + list_del(&child->disco_list_node); spin_lock_irq(&parent->port->dev_list_lock); list_del(&child->dev_list_node); @@ -934,7 +911,6 @@ static struct domain_device *sas_ex_discover_expander( } port = parent->port; child->rphy = rphy; - get_device(&rphy->dev); edev = rphy_to_expander_device(rphy); child->dev_type = phy->attached_dev_type; kref_get(&parent->kref); @@ -958,7 +934,6 @@ static struct domain_device *sas_ex_discover_expander( res = sas_discover_expander(child); if (res) { - sas_rphy_delete(rphy); spin_lock_irq(&parent->port->dev_list_lock); list_del(&child->dev_list_node); spin_unlock_irq(&parent->port->dev_list_lock); @@ -1743,17 +1718,9 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id, int phy_change_count = 0; res = sas_get_phy_change_count(dev, i, &phy_change_count); - switch (res) { - case SMP_RESP_PHY_VACANT: - case SMP_RESP_NO_PHY: - continue; - case SMP_RESP_FUNC_ACC: - break; - default: - return res; - } - - if (phy_change_count != ex->ex_phy[i].phy_change_count) { + if (res) + goto out; + else if (phy_change_count != ex->ex_phy[i].phy_change_count) { if (update) ex->ex_phy[i].phy_change_count = phy_change_count; @@ -1761,7 +1728,8 @@ static int sas_find_bcast_phy(struct domain_device *dev, int *phy_id, return 0; } } - return 0; +out: + return res; } static int sas_get_ex_change_count(struct domain_device *dev, int *ecc) diff --git a/trunk/drivers/scsi/libsas/sas_init.c b/trunk/drivers/scsi/libsas/sas_init.c index 10cb5ae30977..120bff64be30 100644 --- a/trunk/drivers/scsi/libsas/sas_init.c +++ b/trunk/drivers/scsi/libsas/sas_init.c @@ -94,7 +94,8 @@ void sas_hash_addr(u8 *hashed, const u8 *sas_addr) void sas_hae_reset(struct work_struct *work) { - struct sas_ha_event *ev = to_sas_ha_event(work); + struct sas_ha_event *ev = + container_of(work, struct sas_ha_event, work); struct sas_ha_struct *ha = ev->ha; clear_bit(HAE_RESET, &ha->pending); @@ -368,14 +369,14 @@ static void sas_phy_release(struct sas_phy *phy) static void phy_reset_work(struct work_struct *work) { - struct sas_phy_data *d = container_of(work, typeof(*d), reset_work.work); + struct sas_phy_data *d = container_of(work, typeof(*d), reset_work); d->reset_result = transport_sas_phy_reset(d->phy, d->hard_reset); } static void phy_enable_work(struct work_struct *work) { - struct sas_phy_data *d = container_of(work, typeof(*d), enable_work.work); + struct sas_phy_data *d = container_of(work, typeof(*d), enable_work); d->enable_result = sas_phy_enable(d->phy, d->enable); } @@ -388,8 +389,8 @@ static int sas_phy_setup(struct sas_phy *phy) return -ENOMEM; mutex_init(&d->event_lock); - INIT_SAS_WORK(&d->reset_work, phy_reset_work); - INIT_SAS_WORK(&d->enable_work, phy_enable_work); + INIT_WORK(&d->reset_work, phy_reset_work); + INIT_WORK(&d->enable_work, phy_enable_work); d->phy = phy; phy->hostdata = d; diff --git a/trunk/drivers/scsi/libsas/sas_internal.h b/trunk/drivers/scsi/libsas/sas_internal.h index 507e4cf12e56..f05c63879949 100644 --- a/trunk/drivers/scsi/libsas/sas_internal.h +++ b/trunk/drivers/scsi/libsas/sas_internal.h @@ -45,10 +45,10 @@ struct sas_phy_data { struct mutex event_lock; int hard_reset; int reset_result; - struct sas_work reset_work; + struct work_struct reset_work; int enable; int enable_result; - struct sas_work enable_work; + struct work_struct enable_work; }; void sas_scsi_recover_host(struct Scsi_Host *shost); @@ -80,7 +80,7 @@ void sas_porte_broadcast_rcvd(struct work_struct *work); void sas_porte_link_reset_err(struct work_struct *work); void sas_porte_timer_event(struct work_struct *work); void sas_porte_hard_reset(struct work_struct *work); -void sas_queue_work(struct sas_ha_struct *ha, struct sas_work *sw); +void sas_queue_work(struct sas_ha_struct *ha, struct work_struct *work); int sas_notify_lldd_dev_found(struct domain_device *); void sas_notify_lldd_dev_gone(struct domain_device *); diff --git a/trunk/drivers/scsi/libsas/sas_phy.c b/trunk/drivers/scsi/libsas/sas_phy.c index 521422e857ab..dcfd4a9105c5 100644 --- a/trunk/drivers/scsi/libsas/sas_phy.c +++ b/trunk/drivers/scsi/libsas/sas_phy.c @@ -32,7 +32,8 @@ static void sas_phye_loss_of_signal(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; clear_bit(PHYE_LOSS_OF_SIGNAL, &phy->phy_events_pending); @@ -42,7 +43,8 @@ static void sas_phye_loss_of_signal(struct work_struct *work) static void sas_phye_oob_done(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; clear_bit(PHYE_OOB_DONE, &phy->phy_events_pending); @@ -51,7 +53,8 @@ static void sas_phye_oob_done(struct work_struct *work) static void sas_phye_oob_error(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; struct sas_ha_struct *sas_ha = phy->ha; struct asd_sas_port *port = phy->port; @@ -82,7 +85,8 @@ static void sas_phye_oob_error(struct work_struct *work) static void sas_phye_spinup_hold(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; struct sas_ha_struct *sas_ha = phy->ha; struct sas_internal *i = @@ -123,12 +127,14 @@ int sas_register_phys(struct sas_ha_struct *sas_ha) phy->error = 0; INIT_LIST_HEAD(&phy->port_phy_el); for (k = 0; k < PORT_NUM_EVENTS; k++) { - INIT_SAS_WORK(&phy->port_events[k].work, sas_port_event_fns[k]); + INIT_WORK(&phy->port_events[k].work, + sas_port_event_fns[k]); phy->port_events[k].phy = phy; } for (k = 0; k < PHY_NUM_EVENTS; k++) { - INIT_SAS_WORK(&phy->phy_events[k].work, sas_phy_event_fns[k]); + INIT_WORK(&phy->phy_events[k].work, + sas_phy_event_fns[k]); phy->phy_events[k].phy = phy; } @@ -138,7 +144,8 @@ int sas_register_phys(struct sas_ha_struct *sas_ha) spin_lock_init(&phy->sas_prim_lock); phy->frame_rcvd_size = 0; - phy->phy = sas_phy_alloc(&sas_ha->core.shost->shost_gendev, i); + phy->phy = sas_phy_alloc(&sas_ha->core.shost->shost_gendev, + i); if (!phy->phy) return -ENOMEM; diff --git a/trunk/drivers/scsi/libsas/sas_port.c b/trunk/drivers/scsi/libsas/sas_port.c index e884a8c58a0c..eb19c016d500 100644 --- a/trunk/drivers/scsi/libsas/sas_port.c +++ b/trunk/drivers/scsi/libsas/sas_port.c @@ -123,7 +123,7 @@ static void sas_form_port(struct asd_sas_phy *phy) spin_unlock_irqrestore(&sas_ha->phy_port_lock, flags); if (!port->port) { - port->port = sas_port_alloc(phy->phy->dev.parent, port->id); + port->port = sas_port_alloc(phy->phy->dev.parent, phy->id); BUG_ON(!port->port); sas_port_add(port->port); } @@ -208,7 +208,8 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone) void sas_porte_bytes_dmaed(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; clear_bit(PORTE_BYTES_DMAED, &phy->port_events_pending); @@ -218,7 +219,8 @@ void sas_porte_bytes_dmaed(struct work_struct *work) void sas_porte_broadcast_rcvd(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; unsigned long flags; u32 prim; @@ -235,7 +237,8 @@ void sas_porte_broadcast_rcvd(struct work_struct *work) void sas_porte_link_reset_err(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; clear_bit(PORTE_LINK_RESET_ERR, &phy->port_events_pending); @@ -245,7 +248,8 @@ void sas_porte_link_reset_err(struct work_struct *work) void sas_porte_timer_event(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; clear_bit(PORTE_TIMER_EVENT, &phy->port_events_pending); @@ -255,7 +259,8 @@ void sas_porte_timer_event(struct work_struct *work) void sas_porte_hard_reset(struct work_struct *work) { - struct asd_sas_event *ev = to_asd_sas_event(work); + struct asd_sas_event *ev = + container_of(work, struct asd_sas_event, work); struct asd_sas_phy *phy = ev->phy; clear_bit(PORTE_HARD_RESET, &phy->port_events_pending); diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 5dfd7495d1a1..ead6405f3e51 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -1638,7 +1638,7 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, request_fn_proc *request_fn) { struct request_queue *q; - struct device *dev = shost->dma_dev; + struct device *dev = shost->shost_gendev.parent; q = blk_init_queue(request_fn, NULL); if (!q) diff --git a/trunk/drivers/spi/Kconfig b/trunk/drivers/spi/Kconfig index 00c024039c97..3ed748355b98 100644 --- a/trunk/drivers/spi/Kconfig +++ b/trunk/drivers/spi/Kconfig @@ -74,7 +74,7 @@ config SPI_ATMEL This selects a driver for the Atmel SPI Controller, present on many AT32 (AVR32) and AT91 (ARM) chips. -config SPI_BFIN5XX +config SPI_BFIN tristate "SPI controller driver for ADI Blackfin5xx" depends on BLACKFIN help diff --git a/trunk/drivers/spi/Makefile b/trunk/drivers/spi/Makefile index 9d75d2198ff5..a1d48e0ba3dc 100644 --- a/trunk/drivers/spi/Makefile +++ b/trunk/drivers/spi/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o obj-$(CONFIG_SPI_ATH79) += spi-ath79.o obj-$(CONFIG_SPI_AU1550) += spi-au1550.o obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o -obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o +obj-$(CONFIG_SPI_BFIN) += spi-bfin5xx.o obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o obj-$(CONFIG_SPI_BUTTERFLY) += spi-butterfly.o diff --git a/trunk/drivers/spi/spi-bcm63xx.c b/trunk/drivers/spi/spi-bcm63xx.c index 7491971139a6..f01b2648452e 100644 --- a/trunk/drivers/spi/spi-bcm63xx.c +++ b/trunk/drivers/spi/spi-bcm63xx.c @@ -1,7 +1,7 @@ /* * Broadcom BCM63xx SPI controller support * - * Copyright (C) 2009-2012 Florian Fainelli + * Copyright (C) 2009-2011 Florian Fainelli * Copyright (C) 2010 Tanguy Bouzeloc * * This program is free software; you can redistribute it and/or @@ -30,8 +30,6 @@ #include #include #include -#include -#include #include @@ -39,6 +37,8 @@ #define DRV_VER "0.1.2" struct bcm63xx_spi { + spinlock_t lock; + int stopping; struct completion done; void __iomem *regs; @@ -96,12 +96,17 @@ static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = { { 391000, SPI_CLK_0_391MHZ } }; -static int bcm63xx_spi_check_transfer(struct spi_device *spi, - struct spi_transfer *t) +static int bcm63xx_spi_setup_transfer(struct spi_device *spi, + struct spi_transfer *t) { + struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); u8 bits_per_word; + u8 clk_cfg, reg; + u32 hz; + int i; bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word; + hz = (t) ? t->speed_hz : spi->max_speed_hz; if (bits_per_word != 8) { dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", __func__, bits_per_word); @@ -114,19 +119,6 @@ static int bcm63xx_spi_check_transfer(struct spi_device *spi, return -EINVAL; } - return 0; -} - -static void bcm63xx_spi_setup_transfer(struct spi_device *spi, - struct spi_transfer *t) -{ - struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); - u32 hz; - u8 clk_cfg, reg; - int i; - - hz = (t) ? t->speed_hz : spi->max_speed_hz; - /* Find the closest clock configuration */ for (i = 0; i < SPI_CLK_MASK; i++) { if (hz <= bcm63xx_spi_freq_table[i][0]) { @@ -147,6 +139,8 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, bcm_spi_writeb(bs, reg, SPI_CLK_CFG); dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n", clk_cfg, hz); + + return 0; } /* the spi->mode bits understood by this driver: */ @@ -159,6 +153,9 @@ static int bcm63xx_spi_setup(struct spi_device *spi) bs = spi_master_get_devdata(spi->master); + if (bs->stopping) + return -ESHUTDOWN; + if (!spi->bits_per_word) spi->bits_per_word = 8; @@ -168,7 +165,7 @@ static int bcm63xx_spi_setup(struct spi_device *spi) return -EINVAL; } - ret = bcm63xx_spi_check_transfer(spi, NULL); + ret = bcm63xx_spi_setup_transfer(spi, NULL); if (ret < 0) { dev_err(&spi->dev, "setup: unsupported mode bits %x\n", spi->mode & ~MODEBITS); @@ -193,29 +190,28 @@ static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs) bs->remaining_bytes -= size; } -static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi, - struct spi_transfer *t) +static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) { struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); u16 msg_ctl; u16 cmd; - /* Disable the CMD_DONE interrupt */ - bcm_spi_writeb(bs, 0, SPI_INT_MASK); - dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", t->tx_buf, t->rx_buf, t->len); /* Transmitter is inhibited */ bs->tx_ptr = t->tx_buf; bs->rx_ptr = t->rx_buf; + init_completion(&bs->done); if (t->tx_buf) { bs->remaining_bytes = t->len; bcm63xx_spi_fill_tx_fifo(bs); } - init_completion(&bs->done); + /* Enable the command done interrupt which + * we use to determine completion of a command */ + bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); /* Fill in the Message control register */ msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); @@ -234,76 +230,33 @@ static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi, cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT); bcm_spi_writew(bs, cmd, SPI_CMD); + wait_for_completion(&bs->done); - /* Enable the CMD_DONE interrupt */ - bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); + /* Disable the CMD_DONE interrupt */ + bcm_spi_writeb(bs, 0, SPI_INT_MASK); return t->len - bs->remaining_bytes; } -static int bcm63xx_spi_prepare_transfer(struct spi_master *master) -{ - struct bcm63xx_spi *bs = spi_master_get_devdata(master); - - pm_runtime_get_sync(&bs->pdev->dev); - - return 0; -} - -static int bcm63xx_spi_unprepare_transfer(struct spi_master *master) +static int bcm63xx_transfer(struct spi_device *spi, struct spi_message *m) { - struct bcm63xx_spi *bs = spi_master_get_devdata(master); - - pm_runtime_put(&bs->pdev->dev); - - return 0; -} - -static int bcm63xx_spi_transfer_one(struct spi_master *master, - struct spi_message *m) -{ - struct bcm63xx_spi *bs = spi_master_get_devdata(master); + struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); struct spi_transfer *t; - struct spi_device *spi = m->spi; - int status = 0; - unsigned int timeout = 0; - - list_for_each_entry(t, &m->transfers, transfer_list) { - unsigned int len = t->len; - u8 rx_tail; - - status = bcm63xx_spi_check_transfer(spi, t); - if (status < 0) - goto exit; - - /* configure adapter for a new transfer */ - bcm63xx_spi_setup_transfer(spi, t); + int ret = 0; - while (len) { - /* send the data */ - len -= bcm63xx_txrx_bufs(spi, t); - - timeout = wait_for_completion_timeout(&bs->done, HZ); - if (!timeout) { - status = -ETIMEDOUT; - goto exit; - } + if (unlikely(list_empty(&m->transfers))) + return -EINVAL; - /* read out all data */ - rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); + if (bs->stopping) + return -ESHUTDOWN; - /* Read out all the data */ - if (rx_tail) - memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail); - } - - m->actual_length += t->len; + list_for_each_entry(t, &m->transfers, transfer_list) { + ret += bcm63xx_txrx_bufs(spi, t); } -exit: - m->status = status; - spi_finalize_current_message(master); - return 0; + m->complete(m->context); + + return ret; } /* This driver supports single master mode only. Hence @@ -314,15 +267,39 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id) struct spi_master *master = (struct spi_master *)dev_id; struct bcm63xx_spi *bs = spi_master_get_devdata(master); u8 intr; + u16 cmd; /* Read interupts and clear them immediately */ intr = bcm_spi_readb(bs, SPI_INT_STATUS); bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); bcm_spi_writeb(bs, 0, SPI_INT_MASK); - /* A transfer completed */ - if (intr & SPI_INTR_CMD_DONE) - complete(&bs->done); + /* A tansfer completed */ + if (intr & SPI_INTR_CMD_DONE) { + u8 rx_tail; + + rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); + + /* Read out all the data */ + if (rx_tail) + memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail); + + /* See if there is more data to send */ + if (bs->remaining_bytes > 0) { + bcm63xx_spi_fill_tx_fifo(bs); + + /* Start the transfer */ + bcm_spi_writew(bs, SPI_HD_W << SPI_MSG_TYPE_SHIFT, + SPI_MSG_CTL); + cmd = bcm_spi_readw(bs, SPI_CMD); + cmd |= SPI_CMD_START_IMMEDIATE; + cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); + bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); + bcm_spi_writew(bs, cmd, SPI_CMD); + } else { + complete(&bs->done); + } + } return IRQ_HANDLED; } @@ -368,6 +345,7 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev) } bs = spi_master_get_devdata(master); + init_completion(&bs->done); platform_set_drvdata(pdev, master); bs->pdev = pdev; @@ -401,13 +379,12 @@ static int __devinit bcm63xx_spi_probe(struct platform_device *pdev) master->bus_num = pdata->bus_num; master->num_chipselect = pdata->num_chipselect; master->setup = bcm63xx_spi_setup; - master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer; - master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer; - master->transfer_one_message = bcm63xx_spi_transfer_one; - master->mode_bits = MODEBITS; + master->transfer = bcm63xx_transfer; bs->speed_hz = pdata->speed_hz; + bs->stopping = 0; bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); + spin_lock_init(&bs->lock); /* Initialize hardware */ clk_enable(bs->clk); @@ -441,16 +418,18 @@ static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) struct spi_master *master = platform_get_drvdata(pdev); struct bcm63xx_spi *bs = spi_master_get_devdata(master); - spi_unregister_master(master); - /* reset spi block */ bcm_spi_writeb(bs, 0, SPI_INT_MASK); + spin_lock(&bs->lock); + bs->stopping = 1; /* HW shutdown */ clk_disable(bs->clk); clk_put(bs->clk); + spin_unlock(&bs->lock); platform_set_drvdata(pdev, 0); + spi_unregister_master(master); return 0; } diff --git a/trunk/drivers/spi/spi-bfin-sport.c b/trunk/drivers/spi/spi-bfin-sport.c index 1fe51198a622..248a2cc671a9 100644 --- a/trunk/drivers/spi/spi-bfin-sport.c +++ b/trunk/drivers/spi/spi-bfin-sport.c @@ -252,15 +252,19 @@ static void bfin_sport_spi_restore_state(struct bfin_sport_spi_master_data *drv_data) { struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip; + unsigned int bits = (drv_data->ops == &bfin_sport_transfer_ops_u8 ? 7 : 15); bfin_sport_spi_disable(drv_data); dev_dbg(drv_data->dev, "restoring spi ctl state\n"); bfin_write(&drv_data->regs->tcr1, chip->ctl_reg); + bfin_write(&drv_data->regs->tcr2, bits); bfin_write(&drv_data->regs->tclkdiv, chip->baud); + bfin_write(&drv_data->regs->tfsdiv, bits); SSYNC(); bfin_write(&drv_data->regs->rcr1, chip->ctl_reg & ~(ITCLK | ITFS)); + bfin_write(&drv_data->regs->rcr2, bits); SSYNC(); bfin_sport_spi_cs_active(chip); @@ -416,15 +420,11 @@ bfin_sport_spi_pump_transfers(unsigned long data) drv_data->cs_change = transfer->cs_change; /* Bits per word setup */ - bits_per_word = transfer->bits_per_word ? : - message->spi->bits_per_word ? : 8; - if (bits_per_word % 16 == 0) - drv_data->ops = &bfin_sport_transfer_ops_u16; - else + bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word; + if (bits_per_word == 8) drv_data->ops = &bfin_sport_transfer_ops_u8; - bfin_write(&drv_data->regs->tcr2, bits_per_word - 1); - bfin_write(&drv_data->regs->tfsdiv, bits_per_word - 1); - bfin_write(&drv_data->regs->rcr2, bits_per_word - 1); + else + drv_data->ops = &bfin_sport_transfer_ops_u16; drv_data->state = RUNNING_STATE; @@ -598,12 +598,11 @@ bfin_sport_spi_setup(struct spi_device *spi) } chip->cs_chg_udelay = chip_info->cs_chg_udelay; chip->idle_tx_val = chip_info->idle_tx_val; + spi->bits_per_word = chip_info->bits_per_word; } } - if (spi->bits_per_word % 8) { - dev_err(&spi->dev, "%d bits_per_word is not supported\n", - spi->bits_per_word); + if (spi->bits_per_word != 8 && spi->bits_per_word != 16) { ret = -EINVAL; goto error; } diff --git a/trunk/drivers/spi/spi-bfin5xx.c b/trunk/drivers/spi/spi-bfin5xx.c index 9bb4d4af8547..3b83ff8b1e2b 100644 --- a/trunk/drivers/spi/spi-bfin5xx.c +++ b/trunk/drivers/spi/spi-bfin5xx.c @@ -396,7 +396,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) /* last read */ if (drv_data->rx) { dev_dbg(&drv_data->pdev->dev, "last read\n"); - if (!(n_bytes % 2)) { + if (n_bytes % 2) { u16 *buf = (u16 *)drv_data->rx; for (loop = 0; loop < n_bytes / 2; loop++) *buf++ = bfin_read(&drv_data->regs->rdbr); @@ -424,7 +424,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) if (drv_data->rx && drv_data->tx) { /* duplex */ dev_dbg(&drv_data->pdev->dev, "duplex: write_TDBR\n"); - if (!(n_bytes % 2)) { + if (n_bytes % 2) { u16 *buf = (u16 *)drv_data->rx; u16 *buf2 = (u16 *)drv_data->tx; for (loop = 0; loop < n_bytes / 2; loop++) { @@ -442,7 +442,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) } else if (drv_data->rx) { /* read */ dev_dbg(&drv_data->pdev->dev, "read: write_TDBR\n"); - if (!(n_bytes % 2)) { + if (n_bytes % 2) { u16 *buf = (u16 *)drv_data->rx; for (loop = 0; loop < n_bytes / 2; loop++) { *buf++ = bfin_read(&drv_data->regs->rdbr); @@ -458,7 +458,7 @@ static irqreturn_t bfin_spi_pio_irq_handler(int irq, void *dev_id) } else if (drv_data->tx) { /* write */ dev_dbg(&drv_data->pdev->dev, "write: write_TDBR\n"); - if (!(n_bytes % 2)) { + if (n_bytes % 2) { u16 *buf = (u16 *)drv_data->tx; for (loop = 0; loop < n_bytes / 2; loop++) { bfin_read(&drv_data->regs->rdbr); @@ -587,7 +587,6 @@ static void bfin_spi_pump_transfers(unsigned long data) if (message->state == DONE_STATE) { dev_dbg(&drv_data->pdev->dev, "transfer: all done!\n"); message->status = 0; - bfin_spi_flush(drv_data); bfin_spi_giveback(drv_data); return; } @@ -871,10 +870,8 @@ static void bfin_spi_pump_transfers(unsigned long data) message->actual_length += drv_data->len_in_bytes; /* Move to next transfer of this msg */ message->state = bfin_spi_next_transfer(drv_data); - if (drv_data->cs_change && message->state != DONE_STATE) { - bfin_spi_flush(drv_data); + if (drv_data->cs_change) bfin_spi_cs_deactive(drv_data, chip); - } } /* Schedule next transfer tasklet */ @@ -1029,6 +1026,7 @@ static int bfin_spi_setup(struct spi_device *spi) chip->cs_chg_udelay = chip_info->cs_chg_udelay; chip->idle_tx_val = chip_info->idle_tx_val; chip->pio_interrupt = chip_info->pio_interrupt; + spi->bits_per_word = chip_info->bits_per_word; } else { /* force a default base state */ chip->ctl_reg &= bfin_ctl_reg; diff --git a/trunk/drivers/spi/spi-ep93xx.c b/trunk/drivers/spi/spi-ep93xx.c index e8055073e84d..6db2887852d6 100644 --- a/trunk/drivers/spi/spi-ep93xx.c +++ b/trunk/drivers/spi/spi-ep93xx.c @@ -545,12 +545,13 @@ static void ep93xx_spi_pio_transfer(struct ep93xx_spi *espi) * in case of failure. */ static struct dma_async_tx_descriptor * -ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) +ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_data_direction dir) { struct spi_transfer *t = espi->current_msg->state; struct dma_async_tx_descriptor *txd; enum dma_slave_buswidth buswidth; struct dma_slave_config conf; + enum dma_transfer_direction slave_dirn; struct scatterlist *sg; struct sg_table *sgt; struct dma_chan *chan; @@ -566,13 +567,14 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) memset(&conf, 0, sizeof(conf)); conf.direction = dir; - if (dir == DMA_DEV_TO_MEM) { + if (dir == DMA_FROM_DEVICE) { chan = espi->dma_rx; buf = t->rx_buf; sgt = &espi->rx_sgt; conf.src_addr = espi->sspdr_phys; conf.src_addr_width = buswidth; + slave_dirn = DMA_DEV_TO_MEM; } else { chan = espi->dma_tx; buf = t->tx_buf; @@ -580,6 +582,7 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) conf.dst_addr = espi->sspdr_phys; conf.dst_addr_width = buswidth; + slave_dirn = DMA_MEM_TO_DEV; } ret = dmaengine_slave_config(chan, &conf); @@ -630,7 +633,8 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) if (!nents) return ERR_PTR(-ENOMEM); - txd = dmaengine_prep_slave_sg(chan, sgt->sgl, nents, dir, DMA_CTRL_ACK); + txd = dmaengine_prep_slave_sg(chan, sgt->sgl, nents, + slave_dirn, DMA_CTRL_ACK); if (!txd) { dma_unmap_sg(chan->device->dev, sgt->sgl, sgt->nents, dir); return ERR_PTR(-ENOMEM); @@ -647,12 +651,12 @@ ep93xx_spi_dma_prepare(struct ep93xx_spi *espi, enum dma_transfer_direction dir) * unmapped. */ static void ep93xx_spi_dma_finish(struct ep93xx_spi *espi, - enum dma_transfer_direction dir) + enum dma_data_direction dir) { struct dma_chan *chan; struct sg_table *sgt; - if (dir == DMA_DEV_TO_MEM) { + if (dir == DMA_FROM_DEVICE) { chan = espi->dma_rx; sgt = &espi->rx_sgt; } else { @@ -673,16 +677,16 @@ static void ep93xx_spi_dma_transfer(struct ep93xx_spi *espi) struct spi_message *msg = espi->current_msg; struct dma_async_tx_descriptor *rxd, *txd; - rxd = ep93xx_spi_dma_prepare(espi, DMA_DEV_TO_MEM); + rxd = ep93xx_spi_dma_prepare(espi, DMA_FROM_DEVICE); if (IS_ERR(rxd)) { dev_err(&espi->pdev->dev, "DMA RX failed: %ld\n", PTR_ERR(rxd)); msg->status = PTR_ERR(rxd); return; } - txd = ep93xx_spi_dma_prepare(espi, DMA_MEM_TO_DEV); + txd = ep93xx_spi_dma_prepare(espi, DMA_TO_DEVICE); if (IS_ERR(txd)) { - ep93xx_spi_dma_finish(espi, DMA_DEV_TO_MEM); + ep93xx_spi_dma_finish(espi, DMA_FROM_DEVICE); dev_err(&espi->pdev->dev, "DMA TX failed: %ld\n", PTR_ERR(rxd)); msg->status = PTR_ERR(txd); return; @@ -701,8 +705,8 @@ static void ep93xx_spi_dma_transfer(struct ep93xx_spi *espi) wait_for_completion(&espi->wait); - ep93xx_spi_dma_finish(espi, DMA_MEM_TO_DEV); - ep93xx_spi_dma_finish(espi, DMA_DEV_TO_MEM); + ep93xx_spi_dma_finish(espi, DMA_TO_DEVICE); + ep93xx_spi_dma_finish(espi, DMA_FROM_DEVICE); } /** diff --git a/trunk/drivers/spi/spi-pl022.c b/trunk/drivers/spi/spi-pl022.c index 400ae2121a2a..09c925aaf320 100644 --- a/trunk/drivers/spi/spi-pl022.c +++ b/trunk/drivers/spi/spi-pl022.c @@ -1667,15 +1667,9 @@ static int calculate_effective_freq(struct pl022 *pl022, int freq, struct /* cpsdvsr = 254 & scr = 255 */ min_tclk = spi_rate(rate, CPSDVR_MAX, SCR_MAX); - if (freq > max_tclk) - dev_warn(&pl022->adev->dev, - "Max speed that can be programmed is %d Hz, you requested %d\n", - max_tclk, freq); - - if (freq < min_tclk) { + if (!((freq <= max_tclk) && (freq >= min_tclk))) { dev_err(&pl022->adev->dev, - "Requested frequency: %d Hz is less than minimum possible %d Hz\n", - freq, min_tclk); + "controller data is incorrect: out of range frequency"); return -EINVAL; } @@ -1687,37 +1681,26 @@ static int calculate_effective_freq(struct pl022 *pl022, int freq, struct while (scr <= SCR_MAX) { tmp = spi_rate(rate, cpsdvsr, scr); - if (tmp > freq) { - /* we need lower freq */ + if (tmp > freq) scr++; - continue; - } - /* - * If found exact value, mark found and break. - * If found more closer value, update and break. + * If found exact value, update and break. + * If found more closer value, update and continue. */ - if (tmp > best_freq) { + else if ((tmp == freq) || (tmp > best_freq)) { best_freq = tmp; best_cpsdvsr = cpsdvsr; best_scr = scr; if (tmp == freq) - found = 1; + break; } - /* - * increased scr will give lower rates, which are not - * required - */ - break; + scr++; } cpsdvsr += 2; scr = SCR_MIN; } - WARN(!best_freq, "pl022: Matching cpsdvsr and scr not found for %d Hz rate \n", - freq); - clk_freq->cpsdvsr = (u8) (best_cpsdvsr & 0xFF); clk_freq->scr = (u8) (best_scr & 0xFF); dev_dbg(&pl022->adev->dev, @@ -1840,12 +1823,9 @@ static int pl022_setup(struct spi_device *spi) } else chip->cs_control = chip_info->cs_control; - /* Check bits per word with vendor specific range */ - if ((bits <= 3) || (bits > pl022->vendor->max_bpw)) { + if (bits <= 3) { + /* PL022 doesn't support less than 4-bits */ status = -ENOTSUPP; - dev_err(&spi->dev, "illegal data size for this controller!\n"); - dev_err(&spi->dev, "This controller can only handle 4 <= n <= %d bit words\n", - pl022->vendor->max_bpw); goto err_config_params; } else if (bits <= 8) { dev_dbg(&spi->dev, "4 <= n <=8 bits per word\n"); @@ -1858,10 +1838,20 @@ static int pl022_setup(struct spi_device *spi) chip->read = READING_U16; chip->write = WRITING_U16; } else { - dev_dbg(&spi->dev, "17 <= n <= 32 bits per word\n"); - chip->n_bytes = 4; - chip->read = READING_U32; - chip->write = WRITING_U32; + if (pl022->vendor->max_bpw >= 32) { + dev_dbg(&spi->dev, "17 <= n <= 32 bits per word\n"); + chip->n_bytes = 4; + chip->read = READING_U32; + chip->write = WRITING_U32; + } else { + dev_err(&spi->dev, + "illegal data size for this controller!\n"); + dev_err(&spi->dev, + "a standard pl022 can only handle " + "1 <= n <= 16 bit words\n"); + status = -ENOTSUPP; + goto err_config_params; + } } /* Now Initialize all register settings required for this chip */ diff --git a/trunk/drivers/staging/octeon/ethernet-rx.c b/trunk/drivers/staging/octeon/ethernet-rx.c index d91751f9ffe8..400df8cbee53 100644 --- a/trunk/drivers/staging/octeon/ethernet-rx.c +++ b/trunk/drivers/staging/octeon/ethernet-rx.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #ifdef CONFIG_XFRM #include diff --git a/trunk/drivers/staging/octeon/ethernet-tx.c b/trunk/drivers/staging/octeon/ethernet-tx.c index 91a97b3e45c6..56d74dc2fbd5 100644 --- a/trunk/drivers/staging/octeon/ethernet-tx.c +++ b/trunk/drivers/staging/octeon/ethernet-tx.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #ifdef CONFIG_XFRM #include diff --git a/trunk/drivers/staging/octeon/ethernet.c b/trunk/drivers/staging/octeon/ethernet.c index 60cba8194de3..9112cd882154 100644 --- a/trunk/drivers/staging/octeon/ethernet.c +++ b/trunk/drivers/staging/octeon/ethernet.c @@ -31,7 +31,6 @@ #include #include #include -#include #include diff --git a/trunk/drivers/staging/ozwpan/ozpd.c b/trunk/drivers/staging/ozwpan/ozpd.c index 04cd57f2a6da..2b45d3d1800c 100644 --- a/trunk/drivers/staging/ozwpan/ozpd.c +++ b/trunk/drivers/staging/ozwpan/ozpd.c @@ -383,6 +383,8 @@ static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f) pd->tx_pool = &f->link; pd->tx_pool_count++; f = 0; + } else { + kfree(f); } spin_unlock_bh(&pd->tx_frame_lock); if (f) diff --git a/trunk/drivers/staging/tidspbridge/core/tiomap3430.c b/trunk/drivers/staging/tidspbridge/core/tiomap3430.c index 9cf29fcea11e..7862513cc295 100644 --- a/trunk/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/trunk/drivers/staging/tidspbridge/core/tiomap3430.c @@ -79,6 +79,10 @@ #define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) #define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) +#define OMAP343X_CTRL_REGADDR(reg) \ + OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) + + /* Forward Declarations: */ static int bridge_brd_monitor(struct bridge_dev_context *dev_ctxt); static int bridge_brd_read(struct bridge_dev_context *dev_ctxt, @@ -414,27 +418,19 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, /* Assert RST1 i.e only the RST only for DSP megacell */ if (!status) { - /* - * XXX: ioremapping MUST be removed once ctrl - * function is made available. - */ - void __iomem *ctrl = ioremap(OMAP343X_CTRL_BASE, SZ_4K); - if (!ctrl) - return -ENOMEM; - (*pdata->dsp_prm_rmw_bits)(OMAP3430_RST1_IVA2_MASK, OMAP3430_RST1_IVA2_MASK, OMAP3430_IVA2_MOD, OMAP2_RM_RSTCTRL); /* Mask address with 1K for compatibility */ __raw_writel(dsp_addr & OMAP3_IVA2_BOOTADDR_MASK, - ctrl + OMAP343X_CONTROL_IVA2_BOOTADDR); + OMAP343X_CTRL_REGADDR( + OMAP343X_CONTROL_IVA2_BOOTADDR)); /* * Set bootmode to self loop if dsp_debug flag is true */ __raw_writel((dsp_debug) ? OMAP3_IVA2_BOOTMOD_IDLE : 0, - ctrl + OMAP343X_CONTROL_IVA2_BOOTMOD); - - iounmap(ctrl); + OMAP343X_CTRL_REGADDR( + OMAP343X_CONTROL_IVA2_BOOTMOD)); } } if (!status) { diff --git a/trunk/drivers/staging/tidspbridge/core/wdt.c b/trunk/drivers/staging/tidspbridge/core/wdt.c index 870f934f4f3b..70055c8111ed 100644 --- a/trunk/drivers/staging/tidspbridge/core/wdt.c +++ b/trunk/drivers/staging/tidspbridge/core/wdt.c @@ -53,10 +53,7 @@ int dsp_wdt_init(void) int ret = 0; dsp_wdt.sm_wdt = NULL; - dsp_wdt.reg_base = ioremap(OMAP34XX_WDT3_BASE, SZ_4K); - if (!dsp_wdt.reg_base) - return -ENOMEM; - + dsp_wdt.reg_base = OMAP2_L4_IO_ADDRESS(OMAP34XX_WDT3_BASE); tasklet_init(&dsp_wdt.wdt3_tasklet, dsp_wdt_dpc, 0); dsp_wdt.fclk = clk_get(NULL, "wdt3_fck"); @@ -102,9 +99,6 @@ void dsp_wdt_exit(void) dsp_wdt.fclk = NULL; dsp_wdt.iclk = NULL; dsp_wdt.sm_wdt = NULL; - - if (dsp_wdt.reg_base) - iounmap(dsp_wdt.reg_base); dsp_wdt.reg_base = NULL; } diff --git a/trunk/drivers/staging/zcache/Kconfig b/trunk/drivers/staging/zcache/Kconfig index 7048e01f0817..3ed2c8f656a5 100644 --- a/trunk/drivers/staging/zcache/Kconfig +++ b/trunk/drivers/staging/zcache/Kconfig @@ -2,7 +2,7 @@ config ZCACHE bool "Dynamic compression of swap pages and clean pagecache pages" # X86 dependency is because zsmalloc uses non-portable pte/tlb # functions - depends on (CLEANCACHE || FRONTSWAP) && CRYPTO=y && X86 + depends on (CLEANCACHE || FRONTSWAP) && CRYPTO && X86 select ZSMALLOC select CRYPTO_LZO default n diff --git a/trunk/drivers/tty/amiserial.c b/trunk/drivers/tty/amiserial.c index 6cc4358f68c1..24145c30c9b0 100644 --- a/trunk/drivers/tty/amiserial.c +++ b/trunk/drivers/tty/amiserial.c @@ -1073,10 +1073,8 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, (new_serial.close_delay != port->close_delay) || (new_serial.xmit_fifo_size != state->xmit_fifo_size) || ((new_serial.flags & ~ASYNC_USR_MASK) != - (port->flags & ~ASYNC_USR_MASK))) { - tty_unlock(); + (port->flags & ~ASYNC_USR_MASK))) return -EPERM; - } port->flags = ((port->flags & ~ASYNC_USR_MASK) | (new_serial.flags & ASYNC_USR_MASK)); state->custom_divisor = new_serial.custom_divisor; diff --git a/trunk/drivers/tty/serial/clps711x.c b/trunk/drivers/tty/serial/clps711x.c index 836fe2731234..e6c3dbd781d6 100644 --- a/trunk/drivers/tty/serial/clps711x.c +++ b/trunk/drivers/tty/serial/clps711x.c @@ -154,9 +154,10 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) port->x_char = 0; return IRQ_HANDLED; } - - if (uart_circ_empty(xmit) || uart_tx_stopped(port)) - goto disable_tx_irq; + if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { + clps711xuart_stop_tx(port); + return IRQ_HANDLED; + } count = port->fifosize >> 1; do { @@ -170,11 +171,8 @@ static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); - if (uart_circ_empty(xmit)) { - disable_tx_irq: - disable_irq_nosync(TX_IRQ(port)); - tx_enabled(port) = 0; - } + if (uart_circ_empty(xmit)) + clps711xuart_stop_tx(port); return IRQ_HANDLED; } diff --git a/trunk/drivers/tty/serial/pch_uart.c b/trunk/drivers/tty/serial/pch_uart.c index c2816f494807..bbbec4a74cfb 100644 --- a/trunk/drivers/tty/serial/pch_uart.c +++ b/trunk/drivers/tty/serial/pch_uart.c @@ -1447,11 +1447,9 @@ static int pch_uart_verify_port(struct uart_port *port, __func__); return -EOPNOTSUPP; #endif + priv->use_dma = 1; priv->use_dma_flag = 1; dev_info(priv->port.dev, "PCH UART : Use DMA Mode\n"); - if (!priv->use_dma) - pch_request_dma(port); - priv->use_dma = 1; } return 0; diff --git a/trunk/drivers/tty/serial/pmac_zilog.c b/trunk/drivers/tty/serial/pmac_zilog.c index 654755a990df..08ebe901bb59 100644 --- a/trunk/drivers/tty/serial/pmac_zilog.c +++ b/trunk/drivers/tty/serial/pmac_zilog.c @@ -469,7 +469,7 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) tty = NULL; if (r3 & (CHAEXT | CHATxIP | CHARxIP)) { if (!ZS_IS_OPEN(uap_a)) { - pmz_debug("ChanA interrupt while not open !\n"); + pmz_debug("ChanA interrupt while open !\n"); goto skip_a; } write_zsreg(uap_a, R0, RES_H_IUS); @@ -493,8 +493,8 @@ static irqreturn_t pmz_interrupt(int irq, void *dev_id) spin_lock(&uap_b->port.lock); tty = NULL; if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) { - if (!ZS_IS_OPEN(uap_b)) { - pmz_debug("ChanB interrupt while not open !\n"); + if (!ZS_IS_OPEN(uap_a)) { + pmz_debug("ChanB interrupt while open !\n"); goto skip_b; } write_zsreg(uap_b, R0, RES_H_IUS); diff --git a/trunk/drivers/tty/vt/keyboard.c b/trunk/drivers/tty/vt/keyboard.c index 29ca20dbd335..86dd1e302bb3 100644 --- a/trunk/drivers/tty/vt/keyboard.c +++ b/trunk/drivers/tty/vt/keyboard.c @@ -1085,21 +1085,15 @@ void vt_set_led_state(int console, int leds) * * Handle console start. This is a wrapper for the VT layer * so that we can keep kbd knowledge internal - * - * FIXME: We eventually need to hold the kbd lock here to protect - * the LED updating. We can't do it yet because fn_hold calls stop_tty - * and start_tty under the kbd_event_lock, while normal tty paths - * don't hold the lock. We probably need to split out an LED lock - * but not during an -rc release! */ void vt_kbd_con_start(int console) { struct kbd_struct * kbd = kbd_table + console; -/* unsigned long flags; */ -/* spin_lock_irqsave(&kbd_event_lock, flags); */ + unsigned long flags; + spin_lock_irqsave(&kbd_event_lock, flags); clr_vc_kbd_led(kbd, VC_SCROLLOCK); set_leds(); -/* spin_unlock_irqrestore(&kbd_event_lock, flags); */ + spin_unlock_irqrestore(&kbd_event_lock, flags); } /** @@ -1108,28 +1102,22 @@ void vt_kbd_con_start(int console) * * Handle console stop. This is a wrapper for the VT layer * so that we can keep kbd knowledge internal - * - * FIXME: We eventually need to hold the kbd lock here to protect - * the LED updating. We can't do it yet because fn_hold calls stop_tty - * and start_tty under the kbd_event_lock, while normal tty paths - * don't hold the lock. We probably need to split out an LED lock - * but not during an -rc release! */ void vt_kbd_con_stop(int console) { struct kbd_struct * kbd = kbd_table + console; -/* unsigned long flags; */ -/* spin_lock_irqsave(&kbd_event_lock, flags); */ + unsigned long flags; + spin_lock_irqsave(&kbd_event_lock, flags); set_vc_kbd_led(kbd, VC_SCROLLOCK); set_leds(); -/* spin_unlock_irqrestore(&kbd_event_lock, flags); */ + spin_unlock_irqrestore(&kbd_event_lock, flags); } /* * This is the tasklet that updates LED state on all keyboards * attached to the box. The reason we use tasklet is that we * need to handle the scenario when keyboard handler is not - * registered yet but we already getting updates from the VT to + * registered yet but we already getting updates form VT to * update led state. */ static void kbd_bh(unsigned long dummy) diff --git a/trunk/drivers/usb/class/cdc-wdm.c b/trunk/drivers/usb/class/cdc-wdm.c index 0bb2b3248dad..c6f6560d436c 100644 --- a/trunk/drivers/usb/class/cdc-wdm.c +++ b/trunk/drivers/usb/class/cdc-wdm.c @@ -157,9 +157,8 @@ static void wdm_out_callback(struct urb *urb) spin_lock(&desc->iuspin); desc->werr = urb->status; spin_unlock(&desc->iuspin); - kfree(desc->outbuf); - desc->outbuf = NULL; clear_bit(WDM_IN_USE, &desc->flags); + kfree(desc->outbuf); wake_up(&desc->wait); } @@ -339,7 +338,7 @@ static ssize_t wdm_write if (we < 0) return -EIO; - buf = kmalloc(count, GFP_KERNEL); + desc->outbuf = buf = kmalloc(count, GFP_KERNEL); if (!buf) { rv = -ENOMEM; goto outnl; @@ -407,12 +406,10 @@ static ssize_t wdm_write req->wIndex = desc->inum; req->wLength = cpu_to_le16(count); set_bit(WDM_IN_USE, &desc->flags); - desc->outbuf = buf; rv = usb_submit_urb(desc->command, GFP_KERNEL); if (rv < 0) { kfree(buf); - desc->outbuf = NULL; clear_bit(WDM_IN_USE, &desc->flags); dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv); } else { diff --git a/trunk/drivers/usb/core/hcd-pci.c b/trunk/drivers/usb/core/hcd-pci.c index 57ed9e400c06..622b4a48e732 100644 --- a/trunk/drivers/usb/core/hcd-pci.c +++ b/trunk/drivers/usb/core/hcd-pci.c @@ -493,15 +493,6 @@ static int hcd_pci_suspend_noirq(struct device *dev) pci_save_state(pci_dev); - /* - * Some systems crash if an EHCI controller is in D3 during - * a sleep transition. We have to leave such controllers in D0. - */ - if (hcd->broken_pci_sleep) { - dev_dbg(dev, "Staying in PCI D0\n"); - return retval; - } - /* If the root hub is dead rather than suspended, disallow remote * wakeup. usb_hc_died() should ensure that both hosts are marked as * dying, so we only need to check the primary roothub. diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index ec6c97dadbe4..a2aa9d652c67 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -1667,6 +1667,7 @@ void usb_disconnect(struct usb_device **pdev) { struct usb_device *udev = *pdev; int i; + struct usb_hcd *hcd = bus_to_hcd(udev->bus); /* mark the device as inactive, so any further urb submissions for * this device (and any of its children) will fail immediately. @@ -1689,7 +1690,9 @@ void usb_disconnect(struct usb_device **pdev) * so that the hardware is now fully quiesced. */ dev_dbg (&udev->dev, "unregistering device\n"); + mutex_lock(hcd->bandwidth_mutex); usb_disable_device(udev, 0); + mutex_unlock(hcd->bandwidth_mutex); usb_hcd_synchronize_unlinks(udev); usb_remove_ep_devs(&udev->ep0); diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index ca717da3be95..aed3e07942d4 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -1136,6 +1136,8 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, * Deallocates hcd/hardware state for the endpoints (nuking all or most * pending urbs) and usbcore state for the interfaces, so that usbcore * must usb_set_configuration() before any interfaces could be used. + * + * Must be called with hcd->bandwidth_mutex held. */ void usb_disable_device(struct usb_device *dev, int skip_ep0) { @@ -1188,9 +1190,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) usb_disable_endpoint(dev, i + USB_DIR_IN, false); } /* Remove endpoints from the host controller internal state */ - mutex_lock(hcd->bandwidth_mutex); usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); - mutex_unlock(hcd->bandwidth_mutex); /* Second pass: remove endpoint pointers */ } for (i = skip_ep0; i < 16; ++i) { @@ -1750,6 +1750,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) /* if it's already configured, clear out old state first. * getting rid of old interfaces means unbinding their drivers. */ + mutex_lock(hcd->bandwidth_mutex); if (dev->state != USB_STATE_ADDRESS) usb_disable_device(dev, 1); /* Skip ep0 */ @@ -1762,7 +1763,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration) * host controller will not allow submissions to dropped endpoints. If * this call fails, the device state is unchanged. */ - mutex_lock(hcd->bandwidth_mutex); ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); if (ret < 0) { mutex_unlock(hcd->bandwidth_mutex); diff --git a/trunk/drivers/usb/dwc3/core.c b/trunk/drivers/usb/dwc3/core.c index 99b58d84553a..7bd815a507e8 100644 --- a/trunk/drivers/usb/dwc3/core.c +++ b/trunk/drivers/usb/dwc3/core.c @@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc) for (i = 0; i < dwc->num_event_buffers; i++) { evt = dwc->ev_buffs[i]; - if (evt) + if (evt) { dwc3_free_one_event_buffer(dwc, evt); + dwc->ev_buffs[i] = NULL; + } } - - kfree(dwc->ev_buffs); } /** diff --git a/trunk/drivers/usb/dwc3/ep0.c b/trunk/drivers/usb/dwc3/ep0.c index 3584a169886f..25910e251c04 100644 --- a/trunk/drivers/usb/dwc3/ep0.c +++ b/trunk/drivers/usb/dwc3/ep0.c @@ -353,9 +353,6 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc, dwc->test_mode_nr = wIndex >> 8; dwc->test_mode = true; - break; - default: - return -EINVAL; } break; @@ -562,20 +559,15 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, length = trb->size & DWC3_TRB_SIZE_MASK; if (dwc->ep0_bounced) { - unsigned transfer_size = ur->length; - unsigned maxp = ep0->endpoint.maxpacket; - - transfer_size += (maxp - (transfer_size % maxp)); transferred = min_t(u32, ur->length, - transfer_size - length); + ep0->endpoint.maxpacket - length); memcpy(ur->buf, dwc->ep0_bounce, transferred); dwc->ep0_bounced = false; } else { transferred = ur->length - length; + ur->actual += transferred; } - ur->actual += transferred; - if ((epnum & 1) && ur->actual < ur->length) { /* for some reason we did not get everything out */ diff --git a/trunk/drivers/usb/gadget/at91_udc.c b/trunk/drivers/usb/gadget/at91_udc.c index 9d7bcd910074..0c935d7c65bd 100644 --- a/trunk/drivers/usb/gadget/at91_udc.c +++ b/trunk/drivers/usb/gadget/at91_udc.c @@ -1863,8 +1863,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev) mod_timer(&udc->vbus_timer, jiffies + VBUS_POLL_TIMEOUT); } else { - if (request_irq(gpio_to_irq(udc->board.vbus_pin), - at91_vbus_irq, 0, driver_name, udc)) { + if (request_irq(udc->board.vbus_pin, at91_vbus_irq, + 0, driver_name, udc)) { DBG("request vbus irq %d failed\n", udc->board.vbus_pin); retval = -EBUSY; @@ -1886,7 +1886,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) return 0; fail4: if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled) - free_irq(gpio_to_irq(udc->board.vbus_pin), udc); + free_irq(udc->board.vbus_pin, udc); fail3: if (gpio_is_valid(udc->board.vbus_pin)) gpio_free(udc->board.vbus_pin); @@ -1924,7 +1924,7 @@ static int __exit at91udc_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); remove_debug_file(udc); if (gpio_is_valid(udc->board.vbus_pin)) { - free_irq(gpio_to_irq(udc->board.vbus_pin), udc); + free_irq(udc->board.vbus_pin, udc); gpio_free(udc->board.vbus_pin); } free_irq(udc->udp_irq, udc); diff --git a/trunk/drivers/usb/gadget/dummy_hcd.c b/trunk/drivers/usb/gadget/dummy_hcd.c index 170cbe89d9f8..a6dfd2164166 100644 --- a/trunk/drivers/usb/gadget/dummy_hcd.c +++ b/trunk/drivers/usb/gadget/dummy_hcd.c @@ -927,6 +927,7 @@ static int dummy_udc_stop(struct usb_gadget *g, dum->driver = NULL; + dummy_pullup(&dum->gadget, 0); return 0; } diff --git a/trunk/drivers/usb/gadget/f_fs.c b/trunk/drivers/usb/gadget/f_fs.c index f52cb1ae45d9..1cbba70836bc 100644 --- a/trunk/drivers/usb/gadget/f_fs.c +++ b/trunk/drivers/usb/gadget/f_fs.c @@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value) if (code == FUNCTIONFS_INTERFACE_REVMAP) { struct ffs_function *func = ffs->func; ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV; - } else if (gadget && gadget->ops->ioctl) { + } else if (gadget->ops->ioctl) { ret = gadget->ops->ioctl(gadget, code, value); } else { ret = -ENOTTY; @@ -1382,7 +1382,6 @@ static void functionfs_unbind(struct ffs_data *ffs) ffs->ep0req = NULL; ffs->gadget = NULL; ffs_data_put(ffs); - clear_bit(FFS_FL_BOUND, &ffs->flags); } } diff --git a/trunk/drivers/usb/gadget/f_mass_storage.c b/trunk/drivers/usb/gadget/f_mass_storage.c index cb8c162cae5a..a371e966425f 100644 --- a/trunk/drivers/usb/gadget/f_mass_storage.c +++ b/trunk/drivers/usb/gadget/f_mass_storage.c @@ -2189,7 +2189,7 @@ static int do_scsi_command(struct fsg_common *common) common->data_size_from_cmnd = 0; sprintf(unknown, "Unknown x%02x", common->cmnd[0]); reply = check_command(common, common->cmnd_size, - DATA_DIR_UNKNOWN, ~0, 0, unknown); + DATA_DIR_UNKNOWN, 0xff, 0, unknown); if (reply == 0) { common->curlun->sense_data = SS_INVALID_COMMAND; reply = -EINVAL; diff --git a/trunk/drivers/usb/gadget/f_rndis.c b/trunk/drivers/usb/gadget/f_rndis.c index 52343654f5df..7b1cf18df5e3 100644 --- a/trunk/drivers/usb/gadget/f_rndis.c +++ b/trunk/drivers/usb/gadget/f_rndis.c @@ -500,7 +500,6 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) if (buf) { memcpy(req->buf, buf, n); req->complete = rndis_response_complete; - req->context = rndis; rndis_free_response(rndis->config, buf); value = n; } diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index a896d73f7a93..4fac56927741 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -2579,7 +2579,7 @@ static int do_scsi_command(struct fsg_dev *fsg) fsg->data_size_from_cmnd = 0; sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]); if ((reply = check_command(fsg, fsg->cmnd_size, - DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) { + DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) { fsg->curlun->sense_data = SS_INVALID_COMMAND; reply = -EINVAL; } diff --git a/trunk/drivers/usb/gadget/fsl_udc_core.c b/trunk/drivers/usb/gadget/fsl_udc_core.c index 55abfb6bd612..5f94e79cd6b9 100644 --- a/trunk/drivers/usb/gadget/fsl_udc_core.c +++ b/trunk/drivers/usb/gadget/fsl_udc_core.c @@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req) : (1 << (ep_index(ep))); /* check if the pipe is empty */ - if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) { + if (!(list_empty(&ep->queue))) { /* Add td to the end */ struct fsl_req *lastreq; lastreq = list_entry(ep->queue.prev, struct fsl_req, queue); @@ -918,6 +918,10 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) return -ENOMEM; } + /* Update ep0 state */ + if ((ep_index(ep) == 0)) + udc->ep0_state = DATA_STATE_XMIT; + /* irq handler advances the queue */ if (req != NULL) list_add_tail(&req->queue, &ep->queue); @@ -1275,8 +1279,7 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) udc->ep0_dir = USB_DIR_OUT; ep = &udc->eps[0]; - if (udc->ep0_state != DATA_STATE_XMIT) - udc->ep0_state = WAIT_FOR_OUT_STATUS; + udc->ep0_state = WAIT_FOR_OUT_STATUS; req->ep = ep; req->req.length = 0; @@ -1381,9 +1384,6 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, list_add_tail(&req->queue, &ep->queue); udc->ep0_state = DATA_STATE_XMIT; - if (ep0_prime_status(udc, EP_DIR_OUT)) - ep0stall(udc); - return; stall: ep0stall(udc); @@ -1492,14 +1492,6 @@ static void setup_received_irq(struct fsl_udc *udc, spin_lock(&udc->lock); udc->ep0_state = (setup->bRequestType & USB_DIR_IN) ? DATA_STATE_XMIT : DATA_STATE_RECV; - /* - * If the data stage is IN, send status prime immediately. - * See 2.0 Spec chapter 8.5.3.3 for detail. - */ - if (udc->ep0_state == DATA_STATE_XMIT) - if (ep0_prime_status(udc, EP_DIR_OUT)) - ep0stall(udc); - } else { /* No data phase, IN status from gadget */ udc->ep0_dir = USB_DIR_IN; @@ -1528,8 +1520,9 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0, switch (udc->ep0_state) { case DATA_STATE_XMIT: - /* already primed at setup_received_irq */ - udc->ep0_state = WAIT_FOR_OUT_STATUS; + /* receive status phase */ + if (ep0_prime_status(udc, EP_DIR_OUT)) + ep0stall(udc); break; case DATA_STATE_RECV: /* send status phase */ diff --git a/trunk/drivers/usb/gadget/g_ffs.c b/trunk/drivers/usb/gadget/g_ffs.c index a85eaf40b948..331cd6729d3c 100644 --- a/trunk/drivers/usb/gadget/g_ffs.c +++ b/trunk/drivers/usb/gadget/g_ffs.c @@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = { static struct ffs_data *gfs_ffs_data; static unsigned long gfs_registered; -static int __init gfs_init(void) +static int gfs_init(void) { ENTER(); @@ -169,7 +169,7 @@ static int __init gfs_init(void) } module_init(gfs_init); -static void __exit gfs_exit(void) +static void gfs_exit(void) { ENTER(); diff --git a/trunk/drivers/usb/gadget/s3c-hsotg.c b/trunk/drivers/usb/gadget/s3c-hsotg.c index 105b206cd844..69295ba9d99a 100644 --- a/trunk/drivers/usb/gadget/s3c-hsotg.c +++ b/trunk/drivers/usb/gadget/s3c-hsotg.c @@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg) /* currently we allocate TX FIFOs for all possible endpoints, * and assume that they are all the same size. */ - for (ep = 1; ep <= 15; ep++) { + for (ep = 0; ep <= 15; ep++) { val = addr; val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT; addr += size; @@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg, /* write size / packets */ writel(epsize, hsotg->regs + epsize_reg); - if (using_dma(hsotg) && !continuing) { + if (using_dma(hsotg)) { unsigned int dma_reg; /* write DMA address to control register, buffer already @@ -1696,12 +1696,10 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg, reg |= mpsval; writel(reg, regs + S3C_DIEPCTL(ep)); - if (ep) { - reg = readl(regs + S3C_DOEPCTL(ep)); - reg &= ~S3C_DxEPCTL_MPS_MASK; - reg |= mpsval; - writel(reg, regs + S3C_DOEPCTL(ep)); - } + reg = readl(regs + S3C_DOEPCTL(ep)); + reg &= ~S3C_DxEPCTL_MPS_MASK; + reg |= mpsval; + writel(reg, regs + S3C_DOEPCTL(ep)); return; @@ -1921,8 +1919,7 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx, ints & S3C_DIEPMSK_TxFIFOEmpty) { dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n", __func__, idx); - if (!using_dma(hsotg)) - s3c_hsotg_trytx(hsotg, hs_ep); + s3c_hsotg_trytx(hsotg, hs_ep); } } } diff --git a/trunk/drivers/usb/gadget/udc-core.c b/trunk/drivers/usb/gadget/udc-core.c index e5e44f8cde9a..56da49f31d6c 100644 --- a/trunk/drivers/usb/gadget/udc-core.c +++ b/trunk/drivers/usb/gadget/udc-core.c @@ -263,9 +263,9 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) if (udc_is_newstyle(udc)) { udc->driver->disconnect(udc->gadget); - usb_gadget_disconnect(udc->gadget); udc->driver->unbind(udc->gadget); usb_gadget_udc_stop(udc->gadget, udc->driver); + usb_gadget_disconnect(udc->gadget); } else { usb_gadget_stop(udc->gadget, udc->driver); } @@ -411,13 +411,9 @@ static ssize_t usb_udc_softconn_store(struct device *dev, struct usb_udc *udc = container_of(dev, struct usb_udc, dev); if (sysfs_streq(buf, "connect")) { - if (udc_is_newstyle(udc)) - usb_gadget_udc_start(udc->gadget, udc->driver); usb_gadget_connect(udc->gadget); } else if (sysfs_streq(buf, "disconnect")) { usb_gadget_disconnect(udc->gadget); - if (udc_is_newstyle(udc)) - usb_gadget_udc_stop(udc->gadget, udc->driver); } else { dev_err(dev, "unsupported command '%s'\n", buf); return -EINVAL; diff --git a/trunk/drivers/usb/gadget/uvc.h b/trunk/drivers/usb/gadget/uvc.h index ca4e03a1c73a..bc78c606c12b 100644 --- a/trunk/drivers/usb/gadget/uvc.h +++ b/trunk/drivers/usb/gadget/uvc.h @@ -28,7 +28,7 @@ struct uvc_request_data { - __s32 length; + unsigned int length; __u8 data[60]; }; diff --git a/trunk/drivers/usb/gadget/uvc_queue.c b/trunk/drivers/usb/gadget/uvc_queue.c index 0cdf89d32a15..d776adb2da67 100644 --- a/trunk/drivers/usb/gadget/uvc_queue.c +++ b/trunk/drivers/usb/gadget/uvc_queue.c @@ -543,11 +543,11 @@ static int uvc_queue_enable(struct uvc_video_queue *queue, int enable) return ret; } -/* called with queue->irqlock held.. */ static struct uvc_buffer * uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) { struct uvc_buffer *nextbuf; + unsigned long flags; if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) && buf->buf.length != buf->buf.bytesused) { @@ -556,12 +556,14 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf) return buf; } + spin_lock_irqsave(&queue->irqlock, flags); list_del(&buf->queue); if (!list_empty(&queue->irqqueue)) nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer, queue); else nextbuf = NULL; + spin_unlock_irqrestore(&queue->irqlock, flags); buf->buf.sequence = queue->sequence++; do_gettimeofday(&buf->buf.timestamp); diff --git a/trunk/drivers/usb/gadget/uvc_v4l2.c b/trunk/drivers/usb/gadget/uvc_v4l2.c index 54d7ca559cb2..f6e083b50191 100644 --- a/trunk/drivers/usb/gadget/uvc_v4l2.c +++ b/trunk/drivers/usb/gadget/uvc_v4l2.c @@ -39,7 +39,7 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data) if (data->length < 0) return usb_ep_set_halt(cdev->gadget->ep0); - req->length = min_t(unsigned int, uvc->event_length, data->length); + req->length = min(uvc->event_length, data->length); req->zero = data->length < uvc->event_length; req->dma = DMA_ADDR_INVALID; diff --git a/trunk/drivers/usb/host/ehci-fsl.c b/trunk/drivers/usb/host/ehci-fsl.c index d0a84bd3f3eb..3e7345172e03 100644 --- a/trunk/drivers/usb/host/ehci-fsl.c +++ b/trunk/drivers/usb/host/ehci-fsl.c @@ -218,9 +218,6 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, u32 portsc; struct usb_hcd *hcd = ehci_to_hcd(ehci); void __iomem *non_ehci = hcd->regs; - struct fsl_usb2_platform_data *pdata; - - pdata = hcd->self.controller->platform_data; portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]); portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW); @@ -237,9 +234,7 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, /* fall through */ case FSL_USB2_PHY_UTMI: /* enable UTMI PHY */ - if (pdata->have_sysif_regs) - setbits32(non_ehci + FSL_SOC_USB_CTRL, - CTRL_UTMI_PHY_EN); + setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN); portsc |= PORT_PTS_UTMI; break; case FSL_USB2_PHY_NONE: diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index 4a3bc5b7a06f..806cc95317aa 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -858,13 +858,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) goto dead; } - /* - * We don't use STS_FLR, but some controllers don't like it to - * remain on, so mask it out along with the other status bits. - */ - masked_status = status & (INTR_MASK | STS_FLR); - /* Shared IRQ? */ + masked_status = status & INTR_MASK; if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) { spin_unlock(&ehci->lock); return IRQ_NONE; @@ -915,7 +910,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) pcd_status = status; /* resume root hub? */ - if (ehci->rh_state == EHCI_RH_SUSPENDED) + if (!(cmd & CMD_RUN)) usb_hcd_resume_root_hub(hcd); /* get per-port change detect bits */ diff --git a/trunk/drivers/usb/host/ehci-omap.c b/trunk/drivers/usb/host/ehci-omap.c index 5c78f9e71466..bba9850f32f0 100644 --- a/trunk/drivers/usb/host/ehci-omap.c +++ b/trunk/drivers/usb/host/ehci-omap.c @@ -42,7 +42,6 @@ #include #include #include -#include /* EHCI Register Set */ #define EHCI_INSNREG04 (0xA0) @@ -192,19 +191,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) } } - if (pdata->phy_reset) { - if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_request_one(pdata->reset_gpio_port[0], - GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); - - if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_request_one(pdata->reset_gpio_port[1], - GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); - - /* Hold the PHY in RESET for enough time till DIR is high */ - udelay(10); - } - pm_runtime_enable(dev); pm_runtime_get_sync(dev); @@ -251,19 +237,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) /* root ports should always stay powered */ ehci_port_power(omap_ehci, 1); - if (pdata->phy_reset) { - /* Hold the PHY in RESET for enough time till - * PHY is settled and ready - */ - udelay(10); - - if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_set_value(pdata->reset_gpio_port[0], 1); - - if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_set_value(pdata->reset_gpio_port[1], 1); - } - return 0; err_add_hcd: @@ -286,9 +259,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) */ static int ehci_hcd_omap_remove(struct platform_device *pdev) { - struct device *dev = &pdev->dev; - struct usb_hcd *hcd = dev_get_drvdata(dev); - struct ehci_hcd_omap_platform_data *pdata = dev->platform_data; + struct device *dev = &pdev->dev; + struct usb_hcd *hcd = dev_get_drvdata(dev); usb_remove_hcd(hcd); disable_put_regulator(dev->platform_data); @@ -297,13 +269,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) pm_runtime_put_sync(dev); pm_runtime_disable(dev); - if (pdata->phy_reset) { - if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_free(pdata->reset_gpio_port[0]); - - if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_free(pdata->reset_gpio_port[1]); - } return 0; } diff --git a/trunk/drivers/usb/host/ehci-pci.c b/trunk/drivers/usb/host/ehci-pci.c index fe8dc069164e..01bb7241d6ef 100644 --- a/trunk/drivers/usb/host/ehci-pci.c +++ b/trunk/drivers/usb/host/ehci-pci.c @@ -144,14 +144,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd) hcd->has_tt = 1; tdi_reset(ehci); } - if (pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK) { - /* EHCI #1 or #2 on 6 Series/C200 Series chipset */ - if (pdev->device == 0x1c26 || pdev->device == 0x1c2d) { - ehci_info(ehci, "broken D3 during system sleep on ASUS\n"); - hcd->broken_pci_sleep = 1; - device_set_wakeup_capable(&pdev->dev, false); - } - } break; case PCI_VENDOR_ID_TDI: if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { diff --git a/trunk/drivers/usb/host/ehci-tegra.c b/trunk/drivers/usb/host/ehci-tegra.c index f214a80cdee2..73544bd440bd 100644 --- a/trunk/drivers/usb/host/ehci-tegra.c +++ b/trunk/drivers/usb/host/ehci-tegra.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -38,7 +37,9 @@ struct tegra_ehci_hcd { struct clk *emc_clk; struct usb_phy *transceiver; int host_resumed; + int bus_suspended; int port_resuming; + int power_down_on_bus_suspend; enum tegra_usb_phy_port_speed port_speed; }; @@ -272,6 +273,120 @@ static void tegra_ehci_restart(struct usb_hcd *hcd) up_write(&ehci_cf_port_reset_rwsem); } +static int tegra_usb_suspend(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + struct ehci_regs __iomem *hw = tegra->ehci->regs; + unsigned long flags; + + spin_lock_irqsave(&tegra->ehci->lock, flags); + + tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3; + ehci_halt(tegra->ehci); + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + + spin_unlock_irqrestore(&tegra->ehci->lock, flags); + + tegra_ehci_power_down(hcd); + return 0; +} + +static int tegra_usb_resume(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + struct ehci_regs __iomem *hw = ehci->regs; + unsigned long val; + + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + tegra_ehci_power_up(hcd); + + if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) { + /* Wait for the phy to detect new devices + * before we restart the controller */ + msleep(10); + goto restart; + } + + /* Force the phy to keep data lines in suspend state */ + tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); + + /* Enable host mode */ + tdi_reset(ehci); + + /* Enable Port Power */ + val = readl(&hw->port_status[0]); + val |= PORT_POWER; + writel(val, &hw->port_status[0]); + udelay(10); + + /* Check if the phy resume from LP0. When the phy resume from LP0 + * USB register will be reset. */ + if (!readl(&hw->async_next)) { + /* Program the field PTC based on the saved speed mode */ + val = readl(&hw->port_status[0]); + val &= ~PORT_TEST(~0); + if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH) + val |= PORT_TEST_FORCE; + else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL) + val |= PORT_TEST(6); + else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) + val |= PORT_TEST(7); + writel(val, &hw->port_status[0]); + udelay(10); + + /* Disable test mode by setting PTC field to NORMAL_OP */ + val = readl(&hw->port_status[0]); + val &= ~PORT_TEST(~0); + writel(val, &hw->port_status[0]); + udelay(10); + } + + /* Poll until CCS is enabled */ + if (handshake(ehci, &hw->port_status[0], PORT_CONNECT, + PORT_CONNECT, 2000)) { + pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__); + goto restart; + } + + /* Poll until PE is enabled */ + if (handshake(ehci, &hw->port_status[0], PORT_PE, + PORT_PE, 2000)) { + pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__); + goto restart; + } + + /* Clear the PCI status, to avoid an interrupt taken upon resume */ + val = readl(&hw->status); + val |= STS_PCD; + writel(val, &hw->status); + + /* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ + val = readl(&hw->port_status[0]); + if ((val & PORT_POWER) && (val & PORT_PE)) { + val |= PORT_SUSPEND; + writel(val, &hw->port_status[0]); + + /* Wait until port suspend completes */ + if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND, + PORT_SUSPEND, 1000)) { + pr_err("%s: timeout waiting for PORT_SUSPEND\n", + __func__); + goto restart; + } + } + + tegra_ehci_phy_restore_end(tegra->phy); + return 0; + +restart: + if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) + tegra_ehci_phy_restore_end(tegra->phy); + + tegra_ehci_restart(hcd); + return 0; +} + static void tegra_ehci_shutdown(struct usb_hcd *hcd) { struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); @@ -319,6 +434,36 @@ static int tegra_ehci_setup(struct usb_hcd *hcd) return retval; } +#ifdef CONFIG_PM +static int tegra_ehci_bus_suspend(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + int error_status = 0; + + error_status = ehci_bus_suspend(hcd); + if (!error_status && tegra->power_down_on_bus_suspend) { + tegra_usb_suspend(hcd); + tegra->bus_suspended = 1; + } + + return error_status; +} + +static int tegra_ehci_bus_resume(struct usb_hcd *hcd) +{ + struct tegra_ehci_hcd *tegra = dev_get_drvdata(hcd->self.controller); + + if (tegra->bus_suspended && tegra->power_down_on_bus_suspend) { + tegra_usb_resume(hcd); + tegra->bus_suspended = 0; + } + + tegra_usb_phy_preresume(tegra->phy); + tegra->port_resuming = 1; + return ehci_bus_resume(hcd); +} +#endif + struct temp_buffer { void *kmalloc_ptr; void *old_xfer_buffer; @@ -429,8 +574,8 @@ static const struct hc_driver tegra_ehci_hc_driver = { .hub_control = tegra_ehci_hub_control, .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, #ifdef CONFIG_PM - .bus_suspend = ehci_bus_suspend, - .bus_resume = ehci_bus_resume, + .bus_suspend = tegra_ehci_bus_suspend, + .bus_resume = tegra_ehci_bus_resume, #endif .relinquish_port = ehci_relinquish_port, .port_handed_over = ehci_port_handed_over, @@ -458,187 +603,11 @@ static int setup_vbus_gpio(struct platform_device *pdev) dev_err(&pdev->dev, "can't enable vbus\n"); return err; } + gpio_set_value(gpio, 1); return err; } -#ifdef CONFIG_PM - -static int controller_suspend(struct device *dev) -{ - struct tegra_ehci_hcd *tegra = - platform_get_drvdata(to_platform_device(dev)); - struct ehci_hcd *ehci = tegra->ehci; - struct usb_hcd *hcd = ehci_to_hcd(ehci); - struct ehci_regs __iomem *hw = ehci->regs; - unsigned long flags; - - if (time_before(jiffies, ehci->next_statechange)) - msleep(10); - - spin_lock_irqsave(&ehci->lock, flags); - - tegra->port_speed = (readl(&hw->port_status[0]) >> 26) & 0x3; - ehci_halt(ehci); - clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - - spin_unlock_irqrestore(&ehci->lock, flags); - - tegra_ehci_power_down(hcd); - return 0; -} - -static int controller_resume(struct device *dev) -{ - struct tegra_ehci_hcd *tegra = - platform_get_drvdata(to_platform_device(dev)); - struct ehci_hcd *ehci = tegra->ehci; - struct usb_hcd *hcd = ehci_to_hcd(ehci); - struct ehci_regs __iomem *hw = ehci->regs; - unsigned long val; - - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - tegra_ehci_power_up(hcd); - - if (tegra->port_speed > TEGRA_USB_PHY_PORT_SPEED_HIGH) { - /* Wait for the phy to detect new devices - * before we restart the controller */ - msleep(10); - goto restart; - } - - /* Force the phy to keep data lines in suspend state */ - tegra_ehci_phy_restore_start(tegra->phy, tegra->port_speed); - - /* Enable host mode */ - tdi_reset(ehci); - - /* Enable Port Power */ - val = readl(&hw->port_status[0]); - val |= PORT_POWER; - writel(val, &hw->port_status[0]); - udelay(10); - - /* Check if the phy resume from LP0. When the phy resume from LP0 - * USB register will be reset. */ - if (!readl(&hw->async_next)) { - /* Program the field PTC based on the saved speed mode */ - val = readl(&hw->port_status[0]); - val &= ~PORT_TEST(~0); - if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_HIGH) - val |= PORT_TEST_FORCE; - else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_FULL) - val |= PORT_TEST(6); - else if (tegra->port_speed == TEGRA_USB_PHY_PORT_SPEED_LOW) - val |= PORT_TEST(7); - writel(val, &hw->port_status[0]); - udelay(10); - - /* Disable test mode by setting PTC field to NORMAL_OP */ - val = readl(&hw->port_status[0]); - val &= ~PORT_TEST(~0); - writel(val, &hw->port_status[0]); - udelay(10); - } - - /* Poll until CCS is enabled */ - if (handshake(ehci, &hw->port_status[0], PORT_CONNECT, - PORT_CONNECT, 2000)) { - pr_err("%s: timeout waiting for PORT_CONNECT\n", __func__); - goto restart; - } - - /* Poll until PE is enabled */ - if (handshake(ehci, &hw->port_status[0], PORT_PE, - PORT_PE, 2000)) { - pr_err("%s: timeout waiting for USB_PORTSC1_PE\n", __func__); - goto restart; - } - - /* Clear the PCI status, to avoid an interrupt taken upon resume */ - val = readl(&hw->status); - val |= STS_PCD; - writel(val, &hw->status); - - /* Put controller in suspend mode by writing 1 to SUSP bit of PORTSC */ - val = readl(&hw->port_status[0]); - if ((val & PORT_POWER) && (val & PORT_PE)) { - val |= PORT_SUSPEND; - writel(val, &hw->port_status[0]); - - /* Wait until port suspend completes */ - if (handshake(ehci, &hw->port_status[0], PORT_SUSPEND, - PORT_SUSPEND, 1000)) { - pr_err("%s: timeout waiting for PORT_SUSPEND\n", - __func__); - goto restart; - } - } - - tegra_ehci_phy_restore_end(tegra->phy); - goto done; - - restart: - if (tegra->port_speed <= TEGRA_USB_PHY_PORT_SPEED_HIGH) - tegra_ehci_phy_restore_end(tegra->phy); - - tegra_ehci_restart(hcd); - - done: - tegra_usb_phy_preresume(tegra->phy); - tegra->port_resuming = 1; - return 0; -} - -static int tegra_ehci_suspend(struct device *dev) -{ - struct tegra_ehci_hcd *tegra = - platform_get_drvdata(to_platform_device(dev)); - struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); - int rc = 0; - - /* - * When system sleep is supported and USB controller wakeup is - * implemented: If the controller is runtime-suspended and the - * wakeup setting needs to be changed, call pm_runtime_resume(). - */ - if (HCD_HW_ACCESSIBLE(hcd)) - rc = controller_suspend(dev); - return rc; -} - -static int tegra_ehci_resume(struct device *dev) -{ - int rc; - - rc = controller_resume(dev); - if (rc == 0) { - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - } - return rc; -} - -static int tegra_ehci_runtime_suspend(struct device *dev) -{ - return controller_suspend(dev); -} - -static int tegra_ehci_runtime_resume(struct device *dev) -{ - return controller_resume(dev); -} - -static const struct dev_pm_ops tegra_ehci_pm_ops = { - .suspend = tegra_ehci_suspend, - .resume = tegra_ehci_resume, - .runtime_suspend = tegra_ehci_runtime_suspend, - .runtime_resume = tegra_ehci_runtime_resume, -}; - -#endif - static u64 tegra_ehci_dma_mask = DMA_BIT_MASK(32); static int tegra_ehci_probe(struct platform_device *pdev) @@ -753,6 +722,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) } tegra->host_resumed = 1; + tegra->power_down_on_bus_suspend = pdata->power_down_on_bus_suspend; tegra->ehci = hcd_to_ehci(hcd); irq = platform_get_irq(pdev, 0); @@ -761,6 +731,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) err = -ENODEV; goto fail; } + set_irq_flags(irq, IRQF_VALID); #ifdef CONFIG_USB_OTG_UTILS if (pdata->operating_mode == TEGRA_USB_OTG) { @@ -776,14 +747,6 @@ static int tegra_ehci_probe(struct platform_device *pdev) goto fail; } - pm_runtime_set_active(&pdev->dev); - pm_runtime_get_noresume(&pdev->dev); - - /* Don't skip the pm_runtime_forbid call if wakeup isn't working */ - /* if (!pdata->power_down_on_bus_suspend) */ - pm_runtime_forbid(&pdev->dev); - pm_runtime_enable(&pdev->dev); - pm_runtime_put_sync(&pdev->dev); return err; fail: @@ -810,6 +773,33 @@ static int tegra_ehci_probe(struct platform_device *pdev) return err; } +#ifdef CONFIG_PM +static int tegra_ehci_resume(struct platform_device *pdev) +{ + struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); + struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); + + if (tegra->bus_suspended) + return 0; + + return tegra_usb_resume(hcd); +} + +static int tegra_ehci_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); + struct usb_hcd *hcd = ehci_to_hcd(tegra->ehci); + + if (tegra->bus_suspended) + return 0; + + if (time_before(jiffies, tegra->ehci->next_statechange)) + msleep(10); + + return tegra_usb_suspend(hcd); +} +#endif + static int tegra_ehci_remove(struct platform_device *pdev) { struct tegra_ehci_hcd *tegra = platform_get_drvdata(pdev); @@ -818,10 +808,6 @@ static int tegra_ehci_remove(struct platform_device *pdev) if (tegra == NULL || hcd == NULL) return -EINVAL; - pm_runtime_get_sync(&pdev->dev); - pm_runtime_disable(&pdev->dev); - pm_runtime_put_noidle(&pdev->dev); - #ifdef CONFIG_USB_OTG_UTILS if (tegra->transceiver) { otg_set_host(tegra->transceiver->otg, NULL); @@ -862,12 +848,13 @@ static struct of_device_id tegra_ehci_of_match[] __devinitdata = { static struct platform_driver tegra_ehci_driver = { .probe = tegra_ehci_probe, .remove = tegra_ehci_remove, +#ifdef CONFIG_PM + .suspend = tegra_ehci_suspend, + .resume = tegra_ehci_resume, +#endif .shutdown = tegra_ehci_hcd_shutdown, .driver = { .name = "tegra-ehci", .of_match_table = tegra_ehci_of_match, -#ifdef CONFIG_PM - .pm = &tegra_ehci_pm_ops, -#endif } }; diff --git a/trunk/drivers/usb/host/ohci-at91.c b/trunk/drivers/usb/host/ohci-at91.c index 13ebeca8e73e..09f597ad6e00 100644 --- a/trunk/drivers/usb/host/ohci-at91.c +++ b/trunk/drivers/usb/host/ohci-at91.c @@ -94,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ -static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); +static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); /* configure so an HC device and id are always provided */ /* always called with process context; sleeping is OK */ @@ -108,7 +108,7 @@ static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_dev * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. */ -static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver, +static int usb_hcd_at91_probe(const struct hc_driver *driver, struct platform_device *pdev) { int retval; @@ -203,7 +203,7 @@ static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver, * context, "rmmod" or something similar. * */ -static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd, +static void usb_hcd_at91_remove(struct usb_hcd *hcd, struct platform_device *pdev) { usb_remove_hcd(hcd); @@ -545,7 +545,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev) /*-------------------------------------------------------------------------*/ -static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev) +static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) { struct at91_usbh_data *pdata; int i; @@ -620,7 +620,7 @@ static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev) return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev); } -static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev) +static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) { struct at91_usbh_data *pdata = pdev->dev.platform_data; int i; @@ -696,7 +696,7 @@ MODULE_ALIAS("platform:at91_ohci"); static struct platform_driver ohci_hcd_at91_driver = { .probe = ohci_hcd_at91_drv_probe, - .remove = __devexit_p(ohci_hcd_at91_drv_remove), + .remove = ohci_hcd_at91_drv_remove, .shutdown = usb_hcd_platform_shutdown, .suspend = ohci_hcd_at91_drv_suspend, .resume = ohci_hcd_at91_drv_resume, diff --git a/trunk/drivers/usb/misc/usbtest.c b/trunk/drivers/usb/misc/usbtest.c index 9dcb68f04f03..959145baf3cf 100644 --- a/trunk/drivers/usb/misc/usbtest.c +++ b/trunk/drivers/usb/misc/usbtest.c @@ -423,7 +423,7 @@ alloc_sglist(int nents, int max, int vary) unsigned i; unsigned size = max; - sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL); + sg = kmalloc(nents * sizeof *sg, GFP_KERNEL); if (!sg) return NULL; sg_init_table(sg, nents); @@ -904,9 +904,6 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param) struct ctrl_ctx context; int i; - if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen) - return -EOPNOTSUPP; - spin_lock_init(&context.lock); context.dev = dev; init_completion(&context.complete); @@ -1984,6 +1981,8 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf) /* queued control messaging */ case 10: + if (param->sglen == 0) + break; retval = 0; dev_info(&intf->dev, "TEST 10: queue %d control calls, %d times\n", @@ -2277,8 +2276,6 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id) if (status < 0) { WARNING(dev, "couldn't get endpoints, %d\n", status); - kfree(dev->buf); - kfree(dev); return status; } /* may find bulk or ISO pipes */ diff --git a/trunk/drivers/usb/misc/yurex.c b/trunk/drivers/usb/misc/yurex.c index 70201462e19c..897edda42270 100644 --- a/trunk/drivers/usb/misc/yurex.c +++ b/trunk/drivers/usb/misc/yurex.c @@ -99,7 +99,9 @@ static void yurex_delete(struct kref *kref) usb_put_dev(dev->udev); if (dev->cntl_urb) { usb_kill_urb(dev->cntl_urb); - kfree(dev->cntl_req); + if (dev->cntl_req) + usb_free_coherent(dev->udev, YUREX_BUF_SIZE, + dev->cntl_req, dev->cntl_urb->setup_dma); if (dev->cntl_buffer) usb_free_coherent(dev->udev, YUREX_BUF_SIZE, dev->cntl_buffer, dev->cntl_urb->transfer_dma); @@ -232,7 +234,9 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ } /* allocate buffer for control req */ - dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL); + dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE, + GFP_KERNEL, + &dev->cntl_urb->setup_dma); if (!dev->cntl_req) { err("Could not allocate cntl_req"); goto error; @@ -282,7 +286,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr), dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt, dev, 1); - dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; if (usb_submit_urb(dev->urb, GFP_KERNEL)) { retval = -EIO; err("Could not submitting URB"); diff --git a/trunk/drivers/usb/musb/davinci.c b/trunk/drivers/usb/musb/davinci.c index 768b4b55c816..97ab975fa442 100644 --- a/trunk/drivers/usb/musb/davinci.c +++ b/trunk/drivers/usb/musb/davinci.c @@ -386,7 +386,7 @@ static int davinci_musb_init(struct musb *musb) usb_nop_xceiv_register(); musb->xceiv = usb_get_transceiver(); if (!musb->xceiv) - goto unregister; + return -ENODEV; musb->mregs += DAVINCI_BASE_OFFSET; @@ -444,7 +444,6 @@ static int davinci_musb_init(struct musb *musb) fail: usb_put_transceiver(musb->xceiv); -unregister: usb_nop_xceiv_unregister(); return -ENODEV; } diff --git a/trunk/drivers/usb/musb/musb_core.c b/trunk/drivers/usb/musb/musb_core.c index 66aaccf04490..0f8b82918a40 100644 --- a/trunk/drivers/usb/musb/musb_core.c +++ b/trunk/drivers/usb/musb/musb_core.c @@ -137,9 +137,6 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset) int i = 0; u8 r; u8 power; - int ret; - - pm_runtime_get_sync(phy->io_dev); /* Make sure the transceiver is not in low power mode */ power = musb_readb(addr, MUSB_POWER); @@ -157,22 +154,15 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset) while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) & MUSB_ULPI_REG_CMPLT)) { i++; - if (i == 10000) { - ret = -ETIMEDOUT; - goto out; - } + if (i == 10000) + return -ETIMEDOUT; } r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); r &= ~MUSB_ULPI_REG_CMPLT; musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); - ret = musb_readb(addr, MUSB_ULPI_REG_DATA); - -out: - pm_runtime_put(phy->io_dev); - - return ret; + return musb_readb(addr, MUSB_ULPI_REG_DATA); } static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) @@ -181,9 +171,6 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) int i = 0; u8 r = 0; u8 power; - int ret = 0; - - pm_runtime_get_sync(phy->io_dev); /* Make sure the transceiver is not in low power mode */ power = musb_readb(addr, MUSB_POWER); @@ -197,20 +184,15 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data) while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL) & MUSB_ULPI_REG_CMPLT)) { i++; - if (i == 10000) { - ret = -ETIMEDOUT; - goto out; - } + if (i == 10000) + return -ETIMEDOUT; } r = musb_readb(addr, MUSB_ULPI_REG_CONTROL); r &= ~MUSB_ULPI_REG_CMPLT; musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r); -out: - pm_runtime_put(phy->io_dev); - - return ret; + return 0; } #else #define musb_ulpi_read NULL @@ -1922,17 +1904,14 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (!musb->isr) { status = -ENODEV; - goto fail2; + goto fail3; } if (!musb->xceiv->io_ops) { - musb->xceiv->io_dev = musb->controller; musb->xceiv->io_priv = musb->mregs; musb->xceiv->io_ops = &musb_ulpi_access; } - pm_runtime_get_sync(musb->controller); - #ifndef CONFIG_MUSB_PIO_ONLY if (use_dma && dev->dma_mask) { struct dma_controller *c; @@ -2044,8 +2023,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) goto fail5; #endif - pm_runtime_put(musb->controller); - dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n", ({char *s; switch (musb->board_mode) { @@ -2070,9 +2047,6 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) musb_gadget_cleanup(musb); fail3: - pm_runtime_put_sync(musb->controller); - -fail2: if (musb->irq_wake) device_init_wakeup(dev, 0); musb_platform_exit(musb); diff --git a/trunk/drivers/usb/musb/musb_core.h b/trunk/drivers/usb/musb/musb_core.h index f4a40f001c88..93de517a32a0 100644 --- a/trunk/drivers/usb/musb/musb_core.h +++ b/trunk/drivers/usb/musb/musb_core.h @@ -449,7 +449,7 @@ struct musb { * We added this flag to forcefully disable double * buffering until we get it working. */ - unsigned double_buffer_not_ok:1; + unsigned double_buffer_not_ok:1 __deprecated; struct musb_hdrc_config *config; diff --git a/trunk/drivers/usb/musb/musb_host.c b/trunk/drivers/usb/musb/musb_host.c index ef8d744800ac..79cb0af779fa 100644 --- a/trunk/drivers/usb/musb/musb_host.c +++ b/trunk/drivers/usb/musb/musb_host.c @@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh) } /* turn off DMA requests, discard state, stop polling ... */ - if (ep->epnum && is_in) { + if (is_in) { /* giveback saves bulk toggle */ csr = musb_h_flush_rxfifo(ep, 0); diff --git a/trunk/drivers/usb/musb/omap2430.c b/trunk/drivers/usb/musb/omap2430.c index c7785e81254c..2ae0bb309994 100644 --- a/trunk/drivers/usb/musb/omap2430.c +++ b/trunk/drivers/usb/musb/omap2430.c @@ -282,8 +282,7 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work) static int omap2430_musb_init(struct musb *musb) { - u32 l; - int status = 0; + u32 l, status = 0; struct device *dev = musb->controller; struct musb_hdrc_platform_data *plat = dev->platform_data; struct omap_musb_board_data *data = plat->board_data; @@ -302,7 +301,7 @@ static int omap2430_musb_init(struct musb *musb) status = pm_runtime_get_sync(dev); if (status < 0) { - dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status); + dev_err(dev, "pm_runtime_get_sync FAILED"); goto err1; } @@ -334,7 +333,6 @@ static int omap2430_musb_init(struct musb *musb) setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb); - pm_runtime_put_noidle(musb->controller); return 0; err1: @@ -454,14 +452,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev) goto err2; } - pm_runtime_enable(&pdev->dev); - ret = platform_device_add(musb); if (ret) { dev_err(&pdev->dev, "failed to register musb device\n"); goto err2; } + pm_runtime_enable(&pdev->dev); + return 0; err2: @@ -480,6 +478,7 @@ static int __devexit omap2430_remove(struct platform_device *pdev) platform_device_del(glue->musb); platform_device_put(glue->musb); + pm_runtime_put(&pdev->dev); kfree(glue); return 0; @@ -492,13 +491,11 @@ static int omap2430_runtime_suspend(struct device *dev) struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - if (musb) { - musb->context.otg_interfsel = musb_readl(musb->mregs, - OTG_INTERFSEL); + musb->context.otg_interfsel = musb_readl(musb->mregs, + OTG_INTERFSEL); - omap2430_low_level_exit(musb); - usb_phy_set_suspend(musb->xceiv, 1); - } + omap2430_low_level_exit(musb); + usb_phy_set_suspend(musb->xceiv, 1); return 0; } @@ -508,13 +505,11 @@ static int omap2430_runtime_resume(struct device *dev) struct omap2430_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - if (musb) { - omap2430_low_level_init(musb); - musb_writel(musb->mregs, OTG_INTERFSEL, - musb->context.otg_interfsel); + omap2430_low_level_init(musb); + musb_writel(musb->mregs, OTG_INTERFSEL, + musb->context.otg_interfsel); - usb_phy_set_suspend(musb->xceiv, 0); - } + usb_phy_set_suspend(musb->xceiv, 0); return 0; } diff --git a/trunk/drivers/usb/otg/gpio_vbus.c b/trunk/drivers/usb/otg/gpio_vbus.c index a0a2178974fe..3ece43a2e4c1 100644 --- a/trunk/drivers/usb/otg/gpio_vbus.c +++ b/trunk/drivers/usb/otg/gpio_vbus.c @@ -96,7 +96,7 @@ static void gpio_vbus_work(struct work_struct *work) struct gpio_vbus_data *gpio_vbus = container_of(work, struct gpio_vbus_data, work); struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; - int gpio, status; + int gpio; if (!gpio_vbus->phy.otg->gadget) return; @@ -108,9 +108,7 @@ static void gpio_vbus_work(struct work_struct *work) */ gpio = pdata->gpio_pullup; if (is_vbus_powered(pdata)) { - status = USB_EVENT_VBUS; gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL; - gpio_vbus->phy.last_event = status; usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget); /* drawing a "unit load" is *always* OK, except for OTG */ @@ -119,9 +117,6 @@ static void gpio_vbus_work(struct work_struct *work) /* optionally enable D+ pullup */ if (gpio_is_valid(gpio)) gpio_set_value(gpio, !pdata->gpio_pullup_inverted); - - atomic_notifier_call_chain(&gpio_vbus->phy.notifier, - status, gpio_vbus->phy.otg->gadget); } else { /* optionally disable D+ pullup */ if (gpio_is_valid(gpio)) @@ -130,12 +125,7 @@ static void gpio_vbus_work(struct work_struct *work) set_vbus_draw(gpio_vbus, 0); usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget); - status = USB_EVENT_NONE; gpio_vbus->phy.state = OTG_STATE_B_IDLE; - gpio_vbus->phy.last_event = status; - - atomic_notifier_call_chain(&gpio_vbus->phy.notifier, - status, gpio_vbus->phy.otg->gadget); } } @@ -297,9 +287,6 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) irq, err); goto err_irq; } - - ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier); - INIT_WORK(&gpio_vbus->work, gpio_vbus_work); gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw"); diff --git a/trunk/drivers/usb/serial/cp210x.c b/trunk/drivers/usb/serial/cp210x.c index ec30f95ef399..0310e2df59f5 100644 --- a/trunk/drivers/usb/serial/cp210x.c +++ b/trunk/drivers/usb/serial/cp210x.c @@ -287,8 +287,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, /* Issue the request, attempting to read 'size' bytes */ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), request, REQTYPE_DEVICE_TO_HOST, 0x0000, - port_priv->bInterfaceNumber, buf, size, - USB_CTRL_GET_TIMEOUT); + port_priv->bInterfaceNumber, buf, size, 300); /* Convert data into an array of integers */ for (i = 0; i < length; i++) @@ -341,14 +340,12 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, 0x0000, - port_priv->bInterfaceNumber, buf, size, - USB_CTRL_SET_TIMEOUT); + port_priv->bInterfaceNumber, buf, size, 300); } else { result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_DEVICE, data[0], - port_priv->bInterfaceNumber, NULL, 0, - USB_CTRL_SET_TIMEOUT); + port_priv->bInterfaceNumber, NULL, 0, 300); } kfree(buf); diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index 8c8bf806f6fa..fdd5aa2c8d82 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -221,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = { }; /* 'blacklist' of interfaces not served by this driver */ -static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 }; +static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 }; static const struct sierra_iface_info direct_ip_interface_blacklist = { .infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces), .ifaceinfo = direct_ip_non_serial_ifaces, @@ -289,6 +289,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1199, 0x6856) }, /* Sierra Wireless AirCard 881 U */ { USB_DEVICE(0x1199, 0x6859) }, /* Sierra Wireless AirCard 885 E */ { USB_DEVICE(0x1199, 0x685A) }, /* Sierra Wireless AirCard 885 E */ + { USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */ /* Sierra Wireless C885 */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)}, /* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */ @@ -298,9 +299,6 @@ static const struct usb_device_id id_table[] = { /* Sierra Wireless HSPA Non-Composite Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, { USB_DEVICE(0x1199, 0x6893) }, /* Sierra Wireless Device */ - { USB_DEVICE(0x1199, 0x68A2), /* Sierra Wireless MC77xx in QMI mode */ - .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist - }, { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, diff --git a/trunk/drivers/uwb/hwa-rc.c b/trunk/drivers/uwb/hwa-rc.c index 810c90ae2c55..66797e9c5010 100644 --- a/trunk/drivers/uwb/hwa-rc.c +++ b/trunk/drivers/uwb/hwa-rc.c @@ -645,8 +645,7 @@ void hwarc_neep_cb(struct urb *urb) dev_err(dev, "NEEP: URB error %d\n", urb->status); } result = usb_submit_urb(urb, GFP_ATOMIC); - if (result < 0 && result != -ENODEV && result != -EPERM) { - /* ignoring unrecoverable errors */ + if (result < 0) { dev_err(dev, "NEEP: Can't resubmit URB (%d) resetting device\n", result); goto error; diff --git a/trunk/drivers/uwb/neh.c b/trunk/drivers/uwb/neh.c index 8cb71bb333c2..a269937be1b8 100644 --- a/trunk/drivers/uwb/neh.c +++ b/trunk/drivers/uwb/neh.c @@ -107,7 +107,6 @@ struct uwb_rc_neh { u8 evt_type; __le16 evt; u8 context; - u8 completed; uwb_rc_cmd_cb_f cb; void *arg; @@ -410,7 +409,6 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size struct device *dev = &rc->uwb_dev.dev; struct uwb_rc_neh *neh; struct uwb_rceb *notif; - unsigned long flags; if (rceb->bEventContext == 0) { notif = kmalloc(size, GFP_ATOMIC); @@ -424,11 +422,7 @@ static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size } else { neh = uwb_rc_neh_lookup(rc, rceb); if (neh) { - spin_lock_irqsave(&rc->neh_lock, flags); - /* to guard against a timeout */ - neh->completed = 1; - del_timer(&neh->timer); - spin_unlock_irqrestore(&rc->neh_lock, flags); + del_timer_sync(&neh->timer); uwb_rc_neh_cb(neh, rceb, size); } else dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n", @@ -574,10 +568,6 @@ static void uwb_rc_neh_timer(unsigned long arg) unsigned long flags; spin_lock_irqsave(&rc->neh_lock, flags); - if (neh->completed) { - spin_unlock_irqrestore(&rc->neh_lock, flags); - return; - } if (neh->context) __uwb_rc_neh_rm(rc, neh); else diff --git a/trunk/drivers/vhost/net.c b/trunk/drivers/vhost/net.c index 1f21d2a1e528..f0da2c32fbde 100644 --- a/trunk/drivers/vhost/net.c +++ b/trunk/drivers/vhost/net.c @@ -238,7 +238,7 @@ static void handle_tx(struct vhost_net *net) vq->heads[vq->upend_idx].len = len; ubuf->callback = vhost_zerocopy_callback; - ubuf->ctx = vq->ubufs; + ubuf->arg = vq->ubufs; ubuf->desc = vq->upend_idx; msg.msg_control = ubuf; msg.msg_controllen = sizeof(ubuf); diff --git a/trunk/drivers/vhost/test.c b/trunk/drivers/vhost/test.c index 3de00d9fae2e..fc9a1d75281f 100644 --- a/trunk/drivers/vhost/test.c +++ b/trunk/drivers/vhost/test.c @@ -155,7 +155,7 @@ static int vhost_test_release(struct inode *inode, struct file *f) vhost_test_stop(n, &private); vhost_test_flush(n); - vhost_dev_cleanup(&n->dev, false); + vhost_dev_cleanup(&n->dev); /* We do an extra flush before freeing memory, * since jobs can re-queue themselves. */ vhost_test_flush(n); diff --git a/trunk/drivers/vhost/vhost.c b/trunk/drivers/vhost/vhost.c index 51e4c1eeec4f..947f00d8e091 100644 --- a/trunk/drivers/vhost/vhost.c +++ b/trunk/drivers/vhost/vhost.c @@ -1598,9 +1598,10 @@ void vhost_ubuf_put_and_wait(struct vhost_ubuf_ref *ubufs) kfree(ubufs); } -void vhost_zerocopy_callback(struct ubuf_info *ubuf) +void vhost_zerocopy_callback(void *arg) { - struct vhost_ubuf_ref *ubufs = ubuf->ctx; + struct ubuf_info *ubuf = arg; + struct vhost_ubuf_ref *ubufs = ubuf->arg; struct vhost_virtqueue *vq = ubufs->vq; /* set len = 1 to mark this desc buffers done DMA */ diff --git a/trunk/drivers/vhost/vhost.h b/trunk/drivers/vhost/vhost.h index 8de1fd5b8efb..8dcf4cca6bf2 100644 --- a/trunk/drivers/vhost/vhost.h +++ b/trunk/drivers/vhost/vhost.h @@ -188,7 +188,7 @@ bool vhost_enable_notify(struct vhost_dev *, struct vhost_virtqueue *); int vhost_log_write(struct vhost_virtqueue *vq, struct vhost_log *log, unsigned int log_num, u64 len); -void vhost_zerocopy_callback(struct ubuf_info *); +void vhost_zerocopy_callback(void *arg); int vhost_zerocopy_signal_used(struct vhost_virtqueue *vq); #define vq_err(vq, fmt, ...) do { \ diff --git a/trunk/drivers/video/bfin-lq035q1-fb.c b/trunk/drivers/video/bfin-lq035q1-fb.c index 353c02fe8a95..86922ac84412 100644 --- a/trunk/drivers/video/bfin-lq035q1-fb.c +++ b/trunk/drivers/video/bfin-lq035q1-fb.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/virtio/virtio_balloon.c b/trunk/drivers/virtio/virtio_balloon.c index c2d05a8279fd..05f0a80818a2 100644 --- a/trunk/drivers/virtio/virtio_balloon.c +++ b/trunk/drivers/virtio/virtio_balloon.c @@ -28,13 +28,6 @@ #include #include -/* - * Balloon device works in 4K page units. So each page is pointed to by - * multiple balloon pages. All memory counters in this driver are in balloon - * page units. - */ -#define VIRTIO_BALLOON_PAGES_PER_PAGE (PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT) - struct virtio_balloon { struct virtio_device *vdev; @@ -49,13 +42,8 @@ struct virtio_balloon /* Waiting for host to ack the pages we released. */ struct completion acked; - /* Number of balloon pages we've told the Host we're not using. */ + /* The pages we've told the Host we're not using. */ unsigned int num_pages; - /* - * The pages we've told the Host we're not using. - * Each page on this list adds VIRTIO_BALLOON_PAGES_PER_PAGE - * to num_pages above. - */ struct list_head pages; /* The array of pfns we tell the Host about. */ @@ -78,13 +66,7 @@ static u32 page_to_balloon_pfn(struct page *page) BUILD_BUG_ON(PAGE_SHIFT < VIRTIO_BALLOON_PFN_SHIFT); /* Convert pfn from Linux page size to balloon page size. */ - return pfn * VIRTIO_BALLOON_PAGES_PER_PAGE; -} - -static struct page *balloon_pfn_to_page(u32 pfn) -{ - BUG_ON(pfn % VIRTIO_BALLOON_PAGES_PER_PAGE); - return pfn_to_page(pfn / VIRTIO_BALLOON_PAGES_PER_PAGE); + return pfn >> (PAGE_SHIFT - VIRTIO_BALLOON_PFN_SHIFT); } static void balloon_ack(struct virtqueue *vq) @@ -114,23 +96,12 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) wait_for_completion(&vb->acked); } -static void set_page_pfns(u32 pfns[], struct page *page) -{ - unsigned int i; - - /* Set balloon pfns pointing at this page. - * Note that the first pfn points at start of the page. */ - for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++) - pfns[i] = page_to_balloon_pfn(page) + i; -} - static void fill_balloon(struct virtio_balloon *vb, size_t num) { /* We can only do one array worth at a time. */ num = min(num, ARRAY_SIZE(vb->pfns)); - for (vb->num_pfns = 0; vb->num_pfns < num; - vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) { + for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { struct page *page = alloc_page(GFP_HIGHUSER | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); if (!page) { @@ -142,9 +113,9 @@ static void fill_balloon(struct virtio_balloon *vb, size_t num) msleep(200); break; } - set_page_pfns(vb->pfns + vb->num_pfns, page); - vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE; + vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); totalram_pages--; + vb->num_pages++; list_add(&page->lru, &vb->pages); } @@ -159,9 +130,8 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num) { unsigned int i; - /* Find pfns pointing at start of each page, get pages and free them. */ - for (i = 0; i < num; i += VIRTIO_BALLOON_PAGES_PER_PAGE) { - __free_page(balloon_pfn_to_page(pfns[i])); + for (i = 0; i < num; i++) { + __free_page(pfn_to_page(pfns[i])); totalram_pages++; } } @@ -173,12 +143,11 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) /* We can only do one array worth at a time. */ num = min(num, ARRAY_SIZE(vb->pfns)); - for (vb->num_pfns = 0; vb->num_pfns < num; - vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) { + for (vb->num_pfns = 0; vb->num_pfns < num; vb->num_pfns++) { page = list_first_entry(&vb->pages, struct page, lru); list_del(&page->lru); - set_page_pfns(vb->pfns + vb->num_pfns, page); - vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE; + vb->pfns[vb->num_pfns] = page_to_balloon_pfn(page); + vb->num_pages--; } /* @@ -265,14 +234,11 @@ static void virtballoon_changed(struct virtio_device *vdev) static inline s64 towards_target(struct virtio_balloon *vb) { - __le32 v; - s64 target; - + u32 v; vb->vdev->config->get(vb->vdev, offsetof(struct virtio_balloon_config, num_pages), &v, sizeof(v)); - target = le32_to_cpu(v); - return target - vb->num_pages; + return (s64)v - vb->num_pages; } static void update_balloon_size(struct virtio_balloon *vb) diff --git a/trunk/drivers/watchdog/hpwdt.c b/trunk/drivers/watchdog/hpwdt.c index 9f13b897fd64..cbc7ceef2786 100644 --- a/trunk/drivers/watchdog/hpwdt.c +++ b/trunk/drivers/watchdog/hpwdt.c @@ -435,16 +435,16 @@ static void hpwdt_start(void) { reload = SECS_TO_TICKS(soft_margin); iowrite16(reload, hpwdt_timer_reg); - iowrite8(0x85, hpwdt_timer_con); + iowrite16(0x85, hpwdt_timer_con); } static void hpwdt_stop(void) { unsigned long data; - data = ioread8(hpwdt_timer_con); + data = ioread16(hpwdt_timer_con); data &= 0xFE; - iowrite8(data, hpwdt_timer_con); + iowrite16(data, hpwdt_timer_con); } static void hpwdt_ping(void) diff --git a/trunk/drivers/xen/events.c b/trunk/drivers/xen/events.c index 0a8a17cd80be..4b33acd8ed4e 100644 --- a/trunk/drivers/xen/events.c +++ b/trunk/drivers/xen/events.c @@ -274,7 +274,7 @@ static unsigned int cpu_from_evtchn(unsigned int evtchn) static bool pirq_check_eoi_map(unsigned irq) { - return test_bit(pirq_from_irq(irq), pirq_eoi_map); + return test_bit(irq, pirq_eoi_map); } static bool pirq_needs_eoi_flag(unsigned irq) diff --git a/trunk/drivers/xen/gntdev.c b/trunk/drivers/xen/gntdev.c index 1ffd03bf8e10..99d8151c824a 100644 --- a/trunk/drivers/xen/gntdev.c +++ b/trunk/drivers/xen/gntdev.c @@ -722,7 +722,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED|VM_DONTEXPAND; if (use_ptemod) - vma->vm_flags |= VM_DONTCOPY; + vma->vm_flags |= VM_DONTCOPY|VM_PFNMAP; vma->vm_private_data = map; diff --git a/trunk/drivers/xen/grant-table.c b/trunk/drivers/xen/grant-table.c index f100ce20b16b..b4d4eac761db 100644 --- a/trunk/drivers/xen/grant-table.c +++ b/trunk/drivers/xen/grant-table.c @@ -1029,7 +1029,6 @@ int gnttab_init(void) int i; unsigned int max_nr_glist_frames, nr_glist_frames; unsigned int nr_init_grefs; - int ret; nr_grant_frames = 1; boot_max_nr_grant_frames = __max_nr_grant_frames(); @@ -1048,16 +1047,12 @@ int gnttab_init(void) nr_glist_frames = (nr_grant_frames * GREFS_PER_GRANT_FRAME + RPP - 1) / RPP; for (i = 0; i < nr_glist_frames; i++) { gnttab_list[i] = (grant_ref_t *)__get_free_page(GFP_KERNEL); - if (gnttab_list[i] == NULL) { - ret = -ENOMEM; + if (gnttab_list[i] == NULL) goto ini_nomem; - } } - if (gnttab_resume() < 0) { - ret = -ENODEV; - goto ini_nomem; - } + if (gnttab_resume() < 0) + return -ENODEV; nr_init_grefs = nr_grant_frames * GREFS_PER_GRANT_FRAME; @@ -1075,7 +1070,7 @@ int gnttab_init(void) for (i--; i >= 0; i--) free_page((unsigned long)gnttab_list[i]); kfree(gnttab_list); - return ret; + return -ENOMEM; } EXPORT_SYMBOL_GPL(gnttab_init); diff --git a/trunk/drivers/xen/manage.c b/trunk/drivers/xen/manage.c index 412b96cc5305..9e14ae6cd49c 100644 --- a/trunk/drivers/xen/manage.c +++ b/trunk/drivers/xen/manage.c @@ -132,7 +132,6 @@ static void do_suspend(void) err = dpm_suspend_end(PMSG_FREEZE); if (err) { printk(KERN_ERR "dpm_suspend_end failed: %d\n", err); - si.cancelled = 0; goto out_resume; } diff --git a/trunk/drivers/xen/xen-acpi-processor.c b/trunk/drivers/xen/xen-acpi-processor.c index 0b48579a9cd6..174b5653cd8a 100644 --- a/trunk/drivers/xen/xen-acpi-processor.c +++ b/trunk/drivers/xen/xen-acpi-processor.c @@ -128,10 +128,7 @@ static int push_cxx_to_hypervisor(struct acpi_processor *_pr) pr_debug(" C%d: %s %d uS\n", cx->type, cx->desc, (u32)cx->latency); } - } else if (ret != -EINVAL) - /* EINVAL means the ACPI ID is incorrect - meaning the ACPI - * table is referencing a non-existing CPU - which can happen - * with broken ACPI tables. */ + } else pr_err(DRV_NAME "(CX): Hypervisor error (%d) for ACPI CPU%u\n", ret, _pr->acpi_id); diff --git a/trunk/drivers/xen/xenbus/xenbus_probe_frontend.c b/trunk/drivers/xen/xenbus/xenbus_probe_frontend.c index a31b54d48839..f20c5f178b40 100644 --- a/trunk/drivers/xen/xenbus/xenbus_probe_frontend.c +++ b/trunk/drivers/xen/xenbus/xenbus_probe_frontend.c @@ -135,7 +135,7 @@ static int read_backend_details(struct xenbus_device *xendev) return xenbus_read_otherend_details(xendev, "backend-id", "backend"); } -static int is_device_connecting(struct device *dev, void *data, bool ignore_nonessential) +static int is_device_connecting(struct device *dev, void *data) { struct xenbus_device *xendev = to_xenbus_device(dev); struct device_driver *drv = data; @@ -152,41 +152,16 @@ static int is_device_connecting(struct device *dev, void *data, bool ignore_none if (drv && (dev->driver != drv)) return 0; - if (ignore_nonessential) { - /* With older QEMU, for PVonHVM guests the guest config files - * could contain: vfb = [ 'vnc=1, vnclisten=0.0.0.0'] - * which is nonsensical as there is no PV FB (there can be - * a PVKB) running as HVM guest. */ - - if ((strncmp(xendev->nodename, "device/vkbd", 11) == 0)) - return 0; - - if ((strncmp(xendev->nodename, "device/vfb", 10) == 0)) - return 0; - } xendrv = to_xenbus_driver(dev->driver); return (xendev->state < XenbusStateConnected || (xendev->state == XenbusStateConnected && xendrv->is_ready && !xendrv->is_ready(xendev))); } -static int essential_device_connecting(struct device *dev, void *data) -{ - return is_device_connecting(dev, data, true /* ignore PV[KBB+FB] */); -} -static int non_essential_device_connecting(struct device *dev, void *data) -{ - return is_device_connecting(dev, data, false); -} -static int exists_essential_connecting_device(struct device_driver *drv) +static int exists_connecting_device(struct device_driver *drv) { return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, - essential_device_connecting); -} -static int exists_non_essential_connecting_device(struct device_driver *drv) -{ - return bus_for_each_dev(&xenbus_frontend.bus, NULL, drv, - non_essential_device_connecting); + is_device_connecting); } static int print_device_status(struct device *dev, void *data) @@ -217,23 +192,6 @@ static int print_device_status(struct device *dev, void *data) /* We only wait for device setup after most initcalls have run. */ static int ready_to_wait_for_devices; -static bool wait_loop(unsigned long start, unsigned int max_delay, - unsigned int *seconds_waited) -{ - if (time_after(jiffies, start + (*seconds_waited+5)*HZ)) { - if (!*seconds_waited) - printk(KERN_WARNING "XENBUS: Waiting for " - "devices to initialise: "); - *seconds_waited += 5; - printk("%us...", max_delay - *seconds_waited); - if (*seconds_waited == max_delay) - return true; - } - - schedule_timeout_interruptible(HZ/10); - - return false; -} /* * On a 5-minute timeout, wait for all devices currently configured. We need * to do this to guarantee that the filesystems and / or network devices @@ -257,14 +215,19 @@ static void wait_for_devices(struct xenbus_driver *xendrv) if (!ready_to_wait_for_devices || !xen_domain()) return; - while (exists_non_essential_connecting_device(drv)) - if (wait_loop(start, 30, &seconds_waited)) - break; - - /* Skips PVKB and PVFB check.*/ - while (exists_essential_connecting_device(drv)) - if (wait_loop(start, 270, &seconds_waited)) - break; + while (exists_connecting_device(drv)) { + if (time_after(jiffies, start + (seconds_waited+5)*HZ)) { + if (!seconds_waited) + printk(KERN_WARNING "XENBUS: Waiting for " + "devices to initialise: "); + seconds_waited += 5; + printk("%us...", 300 - seconds_waited); + if (seconds_waited == 300) + break; + } + + schedule_timeout_interruptible(HZ/10); + } if (seconds_waited) printk("\n"); diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index 67a6db3e1b6f..da887604dfc5 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -93,8 +93,9 @@ static void aio_free_ring(struct kioctx *ctx) put_page(info->ring_pages[i]); if (info->mmap_size) { - BUG_ON(ctx->mm != current->mm); - vm_munmap(info->mmap_base, info->mmap_size); + down_write(&ctx->mm->mmap_sem); + do_munmap(ctx->mm, info->mmap_base, info->mmap_size); + up_write(&ctx->mm->mmap_sem); } if (info->ring_pages && info->ring_pages != info->internal_pages) @@ -388,17 +389,6 @@ void exit_aio(struct mm_struct *mm) "exit_aio:ioctx still alive: %d %d %d\n", atomic_read(&ctx->users), ctx->dead, ctx->reqs_active); - /* - * We don't need to bother with munmap() here - - * exit_mmap(mm) is coming and it'll unmap everything. - * Since aio_free_ring() uses non-zero ->mmap_size - * as indicator that it needs to unmap the area, - * just set it to 0; aio_free_ring() is the only - * place that uses ->mmap_size, so it's safe. - * That way we get all munmap done to current->mm - - * all other callers have ctx->mm == current->mm. - */ - ctx->ring_info.mmap_size = 0; put_ioctx(ctx); } } diff --git a/trunk/fs/autofs4/autofs_i.h b/trunk/fs/autofs4/autofs_i.h index 908e18455413..eb1cc92cd67d 100644 --- a/trunk/fs/autofs4/autofs_i.h +++ b/trunk/fs/autofs4/autofs_i.h @@ -110,6 +110,7 @@ struct autofs_sb_info { int sub_version; int min_proto; int max_proto; + int compat_daemon; unsigned long exp_timeout; unsigned int type; int reghost_enabled; @@ -269,17 +270,6 @@ int autofs4_fill_super(struct super_block *, void *, int); struct autofs_info *autofs4_new_ino(struct autofs_sb_info *); void autofs4_clean_ino(struct autofs_info *); -static inline int autofs_prepare_pipe(struct file *pipe) -{ - if (!pipe->f_op || !pipe->f_op->write) - return -EINVAL; - if (!S_ISFIFO(pipe->f_dentry->d_inode->i_mode)) - return -EINVAL; - /* We want a packet pipe */ - pipe->f_flags |= O_DIRECT; - return 0; -} - /* Queue management functions */ int autofs4_wait(struct autofs_sb_info *,struct dentry *, enum autofs_notify); diff --git a/trunk/fs/autofs4/dev-ioctl.c b/trunk/fs/autofs4/dev-ioctl.c index aa9103f8f01b..9dacb8586701 100644 --- a/trunk/fs/autofs4/dev-ioctl.c +++ b/trunk/fs/autofs4/dev-ioctl.c @@ -376,7 +376,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp, err = -EBADF; goto out; } - if (autofs_prepare_pipe(pipe) < 0) { + if (!pipe->f_op || !pipe->f_op->write) { err = -EPIPE; fput(pipe); goto out; @@ -385,6 +385,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp, sbi->pipefd = pipefd; sbi->pipe = pipe; sbi->catatonic = 0; + sbi->compat_daemon = is_compat_task(); } out: mutex_unlock(&sbi->wq_mutex); diff --git a/trunk/fs/autofs4/inode.c b/trunk/fs/autofs4/inode.c index 6e488ebe7784..d8dc002e9cc3 100644 --- a/trunk/fs/autofs4/inode.c +++ b/trunk/fs/autofs4/inode.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "autofs_i.h" #include @@ -224,6 +225,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) set_autofs_type_indirect(&sbi->type); sbi->min_proto = 0; sbi->max_proto = 0; + sbi->compat_daemon = is_compat_task(); mutex_init(&sbi->wq_mutex); mutex_init(&sbi->pipe_mutex); spin_lock_init(&sbi->fs_lock); @@ -290,7 +292,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) printk("autofs: could not open pipe file descriptor\n"); goto fail_dput; } - if (autofs_prepare_pipe(pipe) < 0) + if (!pipe->f_op || !pipe->f_op->write) goto fail_fput; sbi->pipe = pipe; sbi->pipefd = pipefd; diff --git a/trunk/fs/autofs4/waitq.c b/trunk/fs/autofs4/waitq.c index da8876d38a7b..9c098db43344 100644 --- a/trunk/fs/autofs4/waitq.c +++ b/trunk/fs/autofs4/waitq.c @@ -91,7 +91,24 @@ static int autofs4_write(struct autofs_sb_info *sbi, return (bytes > 0); } - + +/* + * The autofs_v5 packet was misdesigned. + * + * The packets are identical on x86-32 and x86-64, but have different + * alignment. Which means that 'sizeof()' will give different results. + * Fix it up for the case of running 32-bit user mode on a 64-bit kernel. + */ +static noinline size_t autofs_v5_packet_size(struct autofs_sb_info *sbi) +{ + size_t pktsz = sizeof(struct autofs_v5_packet); +#if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT) + if (sbi->compat_daemon > 0) + pktsz -= 4; +#endif + return pktsz; +} + static void autofs4_notify_daemon(struct autofs_sb_info *sbi, struct autofs_wait_queue *wq, int type) @@ -155,8 +172,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, { struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet; - pktsz = sizeof(*packet); - + pktsz = autofs_v5_packet_size(sbi); packet->wait_queue_token = wq->wait_queue_token; packet->len = wq->name.len; memcpy(packet->name, wq->name.name, wq->name.len); diff --git a/trunk/fs/binfmt_aout.c b/trunk/fs/binfmt_aout.c index d146e181d10d..2eb12f13593d 100644 --- a/trunk/fs/binfmt_aout.c +++ b/trunk/fs/binfmt_aout.c @@ -50,7 +50,9 @@ static int set_brk(unsigned long start, unsigned long end) end = PAGE_ALIGN(end); if (end > start) { unsigned long addr; - addr = vm_brk(start, end - start); + down_write(¤t->mm->mmap_sem); + addr = do_brk(start, end - start); + up_write(¤t->mm->mmap_sem); if (BAD_ADDR(addr)) return addr; } @@ -278,7 +280,9 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) pos = 32; map_size = ex.a_text+ex.a_data; #endif - error = vm_brk(text_addr & PAGE_MASK, map_size); + down_write(¤t->mm->mmap_sem); + error = do_brk(text_addr & PAGE_MASK, map_size); + up_write(¤t->mm->mmap_sem); if (error != (text_addr & PAGE_MASK)) { send_sig(SIGKILL, current, 0); return error; @@ -309,7 +313,9 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { loff_t pos = fd_offset; - vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + down_write(¤t->mm->mmap_sem); + do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data); + up_write(¤t->mm->mmap_sem); bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex), ex.a_text+ex.a_data, &pos); @@ -319,20 +325,24 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) goto beyond_if; } - error = vm_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, fd_offset); + up_write(¤t->mm->mmap_sem); if (error != N_TXTADDR(ex)) { send_sig(SIGKILL, current, 0); return error; } - error = vm_mmap(bprm->file, N_DATADDR(ex), ex.a_data, + down_write(¤t->mm->mmap_sem); + error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, fd_offset + ex.a_text); + up_write(¤t->mm->mmap_sem); if (error != N_DATADDR(ex)) { send_sig(SIGKILL, current, 0); return error; @@ -402,7 +412,9 @@ static int load_aout_library(struct file *file) "N_TXTOFF is not page aligned. Please convert library: %s\n", file->f_path.dentry->d_name.name); } - vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + down_write(¤t->mm->mmap_sem); + do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss); + up_write(¤t->mm->mmap_sem); file->f_op->read(file, (char __user *)start_addr, ex.a_text + ex.a_data, &pos); @@ -413,10 +425,12 @@ static int load_aout_library(struct file *file) goto out; } /* Now use mmap to map the library into memory. */ - error = vm_mmap(file, start_addr, ex.a_text + ex.a_data, + down_write(¤t->mm->mmap_sem); + error = do_mmap(file, start_addr, ex.a_text + ex.a_data, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, N_TXTOFF(ex)); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr) goto out; @@ -424,7 +438,9 @@ static int load_aout_library(struct file *file) len = PAGE_ALIGN(ex.a_text + ex.a_data); bss = ex.a_text + ex.a_data + ex.a_bss; if (bss > len) { - error = vm_brk(start_addr + len, bss - len); + down_write(¤t->mm->mmap_sem); + error = do_brk(start_addr + len, bss - len); + up_write(¤t->mm->mmap_sem); retval = error; if (error != start_addr + len) goto out; diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index 16f735417072..48ffb3dc610a 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -82,7 +82,9 @@ static int set_brk(unsigned long start, unsigned long end) end = ELF_PAGEALIGN(end); if (end > start) { unsigned long addr; - addr = vm_brk(start, end - start); + down_write(¤t->mm->mmap_sem); + addr = do_brk(start, end - start); + up_write(¤t->mm->mmap_sem); if (BAD_ADDR(addr)) return addr; } @@ -512,7 +514,9 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1); /* Map the last of the bss segment */ - error = vm_brk(elf_bss, last_bss - elf_bss); + down_write(¤t->mm->mmap_sem); + error = do_brk(elf_bss, last_bss - elf_bss); + up_write(¤t->mm->mmap_sem); if (BAD_ADDR(error)) goto out_close; } @@ -958,8 +962,10 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) and some applications "depend" upon this behavior. Since we do not have the power to recompile these, we emulate the SVr4 behavior. Sigh. */ - error = vm_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, + down_write(¤t->mm->mmap_sem); + error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); } #ifdef ELF_PLAT_INIT @@ -1044,7 +1050,8 @@ static int load_elf_library(struct file *file) eppnt++; /* Now use mmap to map the library into memory. */ - error = vm_mmap(file, + down_write(¤t->mm->mmap_sem); + error = do_mmap(file, ELF_PAGESTART(eppnt->p_vaddr), (eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr)), @@ -1052,6 +1059,7 @@ static int load_elf_library(struct file *file) MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE, (eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr))); + up_write(¤t->mm->mmap_sem); if (error != ELF_PAGESTART(eppnt->p_vaddr)) goto out_free_ph; @@ -1064,8 +1072,11 @@ static int load_elf_library(struct file *file) len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + ELF_MIN_ALIGN - 1); bss = eppnt->p_memsz + eppnt->p_vaddr; - if (bss > len) - vm_brk(len, bss - len); + if (bss > len) { + down_write(¤t->mm->mmap_sem); + do_brk(len, bss - len); + up_write(¤t->mm->mmap_sem); + } error = 0; out_free_ph: diff --git a/trunk/fs/binfmt_elf_fdpic.c b/trunk/fs/binfmt_elf_fdpic.c index d390a0fffc65..9bd5612a8224 100644 --- a/trunk/fs/binfmt_elf_fdpic.c +++ b/trunk/fs/binfmt_elf_fdpic.c @@ -390,17 +390,21 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC)) stack_prot |= PROT_EXEC; - current->mm->start_brk = vm_mmap(NULL, 0, stack_size, stack_prot, + down_write(¤t->mm->mmap_sem); + current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZED | MAP_GROWSDOWN, 0); if (IS_ERR_VALUE(current->mm->start_brk)) { + up_write(¤t->mm->mmap_sem); retval = current->mm->start_brk; current->mm->start_brk = 0; goto error_kill; } + up_write(¤t->mm->mmap_sem); + current->mm->brk = current->mm->start_brk; current->mm->context.end_brk = current->mm->start_brk; current->mm->context.end_brk += @@ -951,8 +955,10 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( if (params->flags & ELF_FDPIC_FLAG_EXECUTABLE) mflags |= MAP_EXECUTABLE; - maddr = vm_mmap(NULL, load_addr, top - base, + down_write(&mm->mmap_sem); + maddr = do_mmap(NULL, load_addr, top - base, PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0); + up_write(&mm->mmap_sem); if (IS_ERR_VALUE(maddr)) return (int) maddr; @@ -1090,8 +1096,10 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, /* create the mapping */ disp = phdr->p_vaddr & ~PAGE_MASK; - maddr = vm_mmap(file, maddr, phdr->p_memsz + disp, prot, flags, + down_write(&mm->mmap_sem); + maddr = do_mmap(file, maddr, phdr->p_memsz + disp, prot, flags, phdr->p_offset - disp); + up_write(&mm->mmap_sem); kdebug("mmap[%d] sz=%lx pr=%x fl=%x of=%lx --> %08lx", loop, phdr->p_memsz + disp, prot, flags, @@ -1135,8 +1143,10 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, unsigned long xmaddr; flags |= MAP_FIXED | MAP_ANONYMOUS; - xmaddr = vm_mmap(NULL, xaddr, excess - excess1, + down_write(&mm->mmap_sem); + xmaddr = do_mmap(NULL, xaddr, excess - excess1, prot, flags, 0); + up_write(&mm->mmap_sem); kdebug("mmap[%d] " " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx", diff --git a/trunk/fs/binfmt_flat.c b/trunk/fs/binfmt_flat.c index 6b2daf99fab8..024d20ee3ca3 100644 --- a/trunk/fs/binfmt_flat.c +++ b/trunk/fs/binfmt_flat.c @@ -542,8 +542,10 @@ static int load_flat_file(struct linux_binprm * bprm, */ DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); - textpos = vm_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, + down_write(¤t->mm->mmap_sem); + textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_EXECUTABLE, 0); + up_write(¤t->mm->mmap_sem); if (!textpos || IS_ERR_VALUE(textpos)) { if (!textpos) textpos = (unsigned long) -ENOMEM; @@ -554,8 +556,10 @@ static int load_flat_file(struct linux_binprm * bprm, len = data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); len = PAGE_ALIGN(len); - realdatastart = vm_mmap(0, 0, len, + down_write(¤t->mm->mmap_sem); + realdatastart = do_mmap(0, 0, len, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); if (realdatastart == 0 || IS_ERR_VALUE(realdatastart)) { if (!realdatastart) @@ -599,8 +603,10 @@ static int load_flat_file(struct linux_binprm * bprm, len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long); len = PAGE_ALIGN(len); - textpos = vm_mmap(0, 0, len, + down_write(¤t->mm->mmap_sem); + textpos = do_mmap(0, 0, len, PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); if (!textpos || IS_ERR_VALUE(textpos)) { if (!textpos) diff --git a/trunk/fs/binfmt_som.c b/trunk/fs/binfmt_som.c index 4517aaff61b4..e4fc746629a7 100644 --- a/trunk/fs/binfmt_som.c +++ b/trunk/fs/binfmt_som.c @@ -147,8 +147,10 @@ static int map_som_binary(struct file *file, code_size = SOM_PAGEALIGN(hpuxhdr->exec_tsize); current->mm->start_code = code_start; current->mm->end_code = code_start + code_size; - retval = vm_mmap(file, code_start, code_size, prot, + down_write(¤t->mm->mmap_sem); + retval = do_mmap(file, code_start, code_size, prot, flags, SOM_PAGESTART(hpuxhdr->exec_tfile)); + up_write(¤t->mm->mmap_sem); if (retval < 0 && retval > -1024) goto out; @@ -156,16 +158,20 @@ static int map_som_binary(struct file *file, data_size = SOM_PAGEALIGN(hpuxhdr->exec_dsize); current->mm->start_data = data_start; current->mm->end_data = bss_start = data_start + data_size; - retval = vm_mmap(file, data_start, data_size, + down_write(¤t->mm->mmap_sem); + retval = do_mmap(file, data_start, data_size, prot | PROT_WRITE, flags, SOM_PAGESTART(hpuxhdr->exec_dfile)); + up_write(¤t->mm->mmap_sem); if (retval < 0 && retval > -1024) goto out; som_brk = bss_start + SOM_PAGEALIGN(hpuxhdr->exec_bsize); current->mm->start_brk = current->mm->brk = som_brk; - retval = vm_mmap(NULL, bss_start, som_brk - bss_start, + down_write(¤t->mm->mmap_sem); + retval = do_mmap(NULL, bss_start, som_brk - bss_start, prot | PROT_WRITE, MAP_FIXED | MAP_PRIVATE, 0); + up_write(¤t->mm->mmap_sem); if (retval > 0 || retval < -1024) retval = 0; out: diff --git a/trunk/fs/btrfs/backref.c b/trunk/fs/btrfs/backref.c index bcec06750232..f4e90748940a 100644 --- a/trunk/fs/btrfs/backref.c +++ b/trunk/fs/btrfs/backref.c @@ -22,7 +22,6 @@ #include "ulist.h" #include "transaction.h" #include "delayed-ref.h" -#include "locking.h" /* * this structure records all encountered refs on the way up to the root @@ -894,22 +893,18 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, s64 bytes_left = size - 1; struct extent_buffer *eb = eb_in; struct btrfs_key found_key; - int leave_spinning = path->leave_spinning; if (bytes_left >= 0) dest[bytes_left] = '\0'; - path->leave_spinning = 1; while (1) { len = btrfs_inode_ref_name_len(eb, iref); bytes_left -= len; if (bytes_left >= 0) read_extent_buffer(eb, dest + bytes_left, (unsigned long)(iref + 1), len); - if (eb != eb_in) { - btrfs_tree_read_unlock_blocking(eb); + if (eb != eb_in) free_extent_buffer(eb); - } ret = inode_ref_info(parent, 0, fs_root, path, &found_key); if (ret > 0) ret = -ENOENT; @@ -924,11 +919,8 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, slot = path->slots[0]; eb = path->nodes[0]; /* make sure we can use eb after releasing the path */ - if (eb != eb_in) { + if (eb != eb_in) atomic_inc(&eb->refs); - btrfs_tree_read_lock(eb); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); - } btrfs_release_path(path); iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref); @@ -939,7 +931,6 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, } btrfs_release_path(path); - path->leave_spinning = leave_spinning; if (ret) return ERR_PTR(ret); @@ -1256,7 +1247,7 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root, struct btrfs_path *path, iterate_irefs_t *iterate, void *ctx) { - int ret = 0; + int ret; int slot; u32 cur; u32 len; @@ -1268,8 +1259,7 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root, struct btrfs_inode_ref *iref; struct btrfs_key found_key; - while (!ret) { - path->leave_spinning = 1; + while (1) { ret = inode_ref_info(inum, parent ? parent+1 : 0, fs_root, path, &found_key); if (ret < 0) @@ -1285,8 +1275,6 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root, eb = path->nodes[0]; /* make sure we can use eb after releasing the path */ atomic_inc(&eb->refs); - btrfs_tree_read_lock(eb); - btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK); btrfs_release_path(path); item = btrfs_item_nr(eb, slot); @@ -1300,12 +1288,13 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root, (unsigned long long)found_key.objectid, (unsigned long long)fs_root->objectid); ret = iterate(parent, iref, eb, ctx); - if (ret) + if (ret) { + free_extent_buffer(eb); break; + } len = sizeof(*iref) + name_len; iref = (struct btrfs_inode_ref *)((char *)iref + len); } - btrfs_tree_read_unlock_blocking(eb); free_extent_buffer(eb); } @@ -1425,8 +1414,6 @@ struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root, void free_ipath(struct inode_fs_paths *ipath) { - if (!ipath) - return; kfree(ipath->fspath); kfree(ipath); } diff --git a/trunk/fs/btrfs/ctree.c b/trunk/fs/btrfs/ctree.c index 4106264fbc65..e801f226d7e0 100644 --- a/trunk/fs/btrfs/ctree.c +++ b/trunk/fs/btrfs/ctree.c @@ -220,12 +220,10 @@ struct extent_buffer *btrfs_read_lock_root_node(struct btrfs_root *root) */ static void add_root_to_dirty_list(struct btrfs_root *root) { - spin_lock(&root->fs_info->trans_lock); if (root->track_dirty && list_empty(&root->dirty_list)) { list_add(&root->dirty_list, &root->fs_info->dirty_cowonly_roots); } - spin_unlock(&root->fs_info->trans_lock); } /* @@ -725,7 +723,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, cur = btrfs_find_tree_block(root, blocknr, blocksize); if (cur) - uptodate = btrfs_buffer_uptodate(cur, gen, 0); + uptodate = btrfs_buffer_uptodate(cur, gen); else uptodate = 0; if (!cur || !uptodate) { @@ -1360,12 +1358,7 @@ static noinline int reada_for_balance(struct btrfs_root *root, block1 = btrfs_node_blockptr(parent, slot - 1); gen = btrfs_node_ptr_generation(parent, slot - 1); eb = btrfs_find_tree_block(root, block1, blocksize); - /* - * if we get -eagain from btrfs_buffer_uptodate, we - * don't want to return eagain here. That will loop - * forever - */ - if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) + if (eb && btrfs_buffer_uptodate(eb, gen)) block1 = 0; free_extent_buffer(eb); } @@ -1373,7 +1366,7 @@ static noinline int reada_for_balance(struct btrfs_root *root, block2 = btrfs_node_blockptr(parent, slot + 1); gen = btrfs_node_ptr_generation(parent, slot + 1); eb = btrfs_find_tree_block(root, block2, blocksize); - if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0) + if (eb && btrfs_buffer_uptodate(eb, gen)) block2 = 0; free_extent_buffer(eb); } @@ -1511,9 +1504,8 @@ read_block_for_search(struct btrfs_trans_handle *trans, tmp = btrfs_find_tree_block(root, blocknr, blocksize); if (tmp) { - /* first we do an atomic uptodate check */ - if (btrfs_buffer_uptodate(tmp, 0, 1) > 0) { - if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) { + if (btrfs_buffer_uptodate(tmp, 0)) { + if (btrfs_buffer_uptodate(tmp, gen)) { /* * we found an up to date block without * sleeping, return @@ -1531,9 +1523,8 @@ read_block_for_search(struct btrfs_trans_handle *trans, free_extent_buffer(tmp); btrfs_set_path_blocking(p); - /* now we're allowed to do a blocking uptodate check */ tmp = read_tree_block(root, blocknr, blocksize, gen); - if (tmp && btrfs_buffer_uptodate(tmp, gen, 0) > 0) { + if (tmp && btrfs_buffer_uptodate(tmp, gen)) { *eb_ret = tmp; return 0; } @@ -1568,7 +1559,7 @@ read_block_for_search(struct btrfs_trans_handle *trans, * and give up so that our caller doesn't loop forever * on our EAGAINs. */ - if (!btrfs_buffer_uptodate(tmp, 0, 0)) + if (!btrfs_buffer_uptodate(tmp, 0)) ret = -EIO; free_extent_buffer(tmp); } @@ -4052,7 +4043,7 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, tmp = btrfs_find_tree_block(root, blockptr, btrfs_level_size(root, level - 1)); - if (tmp && btrfs_buffer_uptodate(tmp, gen, 1) > 0) { + if (tmp && btrfs_buffer_uptodate(tmp, gen)) { free_extent_buffer(tmp); break; } @@ -4175,8 +4166,7 @@ int btrfs_find_next_key(struct btrfs_root *root, struct btrfs_path *path, struct extent_buffer *cur; cur = btrfs_find_tree_block(root, blockptr, btrfs_level_size(root, level - 1)); - if (!cur || - btrfs_buffer_uptodate(cur, gen, 1) <= 0) { + if (!cur || !btrfs_buffer_uptodate(cur, gen)) { slot++; if (cur) free_extent_buffer(cur); diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index 8fd72331d600..5b8ef8eb3521 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -1078,7 +1078,7 @@ struct btrfs_fs_info { * is required instead of the faster short fsync log commits */ u64 last_trans_log_full_commit; - unsigned long mount_opt; + unsigned long mount_opt:21; unsigned long compress_type:4; u64 max_inline; u64 alloc_start; @@ -2166,7 +2166,7 @@ BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item, static inline bool btrfs_root_readonly(struct btrfs_root *root) { - return (root->root_item.flags & cpu_to_le64(BTRFS_ROOT_SUBVOL_RDONLY)) != 0; + return root->root_item.flags & BTRFS_ROOT_SUBVOL_RDONLY; } /* struct btrfs_root_backup */ diff --git a/trunk/fs/btrfs/disk-io.c b/trunk/fs/btrfs/disk-io.c index a7ffc88a7dbe..20196f411206 100644 --- a/trunk/fs/btrfs/disk-io.c +++ b/trunk/fs/btrfs/disk-io.c @@ -323,8 +323,7 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, * in the wrong place. */ static int verify_parent_transid(struct extent_io_tree *io_tree, - struct extent_buffer *eb, u64 parent_transid, - int atomic) + struct extent_buffer *eb, u64 parent_transid) { struct extent_state *cached_state = NULL; int ret; @@ -332,9 +331,6 @@ static int verify_parent_transid(struct extent_io_tree *io_tree, if (!parent_transid || btrfs_header_generation(eb) == parent_transid) return 0; - if (atomic) - return -EAGAIN; - lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1, 0, &cached_state); if (extent_buffer_uptodate(eb) && @@ -376,8 +372,7 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, ret = read_extent_buffer_pages(io_tree, eb, start, WAIT_COMPLETE, btree_get_extent, mirror_num); - if (!ret && !verify_parent_transid(io_tree, eb, - parent_transid, 0)) + if (!ret && !verify_parent_transid(io_tree, eb, parent_transid)) break; /* @@ -388,16 +383,17 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags)) break; + if (!failed_mirror) { + failed = 1; + printk(KERN_ERR "failed mirror was %d\n", eb->failed_mirror); + failed_mirror = eb->failed_mirror; + } + num_copies = btrfs_num_copies(&root->fs_info->mapping_tree, eb->start, eb->len); if (num_copies == 1) break; - if (!failed_mirror) { - failed = 1; - failed_mirror = eb->read_mirror; - } - mirror_num++; if (mirror_num == failed_mirror) mirror_num++; @@ -568,7 +564,7 @@ struct extent_buffer *find_eb_for_page(struct extent_io_tree *tree, } static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, - struct extent_state *state, int mirror) + struct extent_state *state) { struct extent_io_tree *tree; u64 found_start; @@ -593,7 +589,6 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, if (!reads_done) goto err; - eb->read_mirror = mirror; if (test_bit(EXTENT_BUFFER_IOERR, &eb->bflags)) { ret = -EIO; goto err; @@ -657,7 +652,7 @@ static int btree_io_failed_hook(struct page *page, int failed_mirror) eb = (struct extent_buffer *)page->private; set_bit(EXTENT_BUFFER_IOERR, &eb->bflags); - eb->read_mirror = failed_mirror; + eb->failed_mirror = failed_mirror; if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) btree_readahead_hook(root, eb, eb->start, -EIO); return -EIO; /* we fixed nothing */ @@ -1207,7 +1202,7 @@ static int __must_check find_and_setup_root(struct btrfs_root *tree_root, root->commit_root = NULL; root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), blocksize, generation); - if (!root->node || !btrfs_buffer_uptodate(root->node, generation, 0)) { + if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) { free_extent_buffer(root->node); root->node = NULL; return -EIO; @@ -2259,9 +2254,9 @@ int open_ctree(struct super_block *sb, goto fail_sb_buffer; } - if (sectorsize != PAGE_SIZE) { - printk(KERN_WARNING "btrfs: Incompatible sector size(%lu) " - "found on %s\n", (unsigned long)sectorsize, sb->s_id); + if (sectorsize < PAGE_SIZE) { + printk(KERN_WARNING "btrfs: Incompatible sector size " + "found on %s\n", sb->s_id); goto fail_sb_buffer; } @@ -3148,8 +3143,7 @@ int close_ctree(struct btrfs_root *root) return 0; } -int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, - int atomic) +int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid) { int ret; struct inode *btree_inode = buf->pages[0]->mapping->host; @@ -3159,9 +3153,7 @@ int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, return ret; ret = verify_parent_transid(&BTRFS_I(btree_inode)->io_tree, buf, - parent_transid, atomic); - if (ret == -EAGAIN) - return ret; + parent_transid); return !ret; } diff --git a/trunk/fs/btrfs/disk-io.h b/trunk/fs/btrfs/disk-io.h index ab1830aaf0ed..a7ace1a2dd12 100644 --- a/trunk/fs/btrfs/disk-io.h +++ b/trunk/fs/btrfs/disk-io.h @@ -66,8 +66,7 @@ void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr); void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root); void btrfs_mark_buffer_dirty(struct extent_buffer *buf); -int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid, - int atomic); +int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid); int btrfs_set_buffer_uptodate(struct extent_buffer *buf); int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid); u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len); diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index 49fd7b66d57b..2b35f8d14bb9 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -2301,7 +2301,6 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, if (ret) { printk(KERN_DEBUG "btrfs: run_delayed_extent_op returned %d\n", ret); - spin_lock(&delayed_refs->lock); return ret; } @@ -2332,7 +2331,6 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, if (ret) { printk(KERN_DEBUG "btrfs: run_one_delayed_ref returned %d\n", ret); - spin_lock(&delayed_refs->lock); return ret; } @@ -3771,10 +3769,13 @@ static int reserve_metadata_bytes(struct btrfs_root *root, */ if (current->journal_info) return -EAGAIN; - ret = wait_event_killable(space_info->wait, !space_info->flush); - /* Must have been killed, return */ - if (ret) + ret = wait_event_interruptible(space_info->wait, + !space_info->flush); + /* Must have been interrupted, return */ + if (ret) { + printk(KERN_DEBUG "btrfs: %s returning -EINTR\n", __func__); return -EINTR; + } spin_lock(&space_info->lock); } @@ -4214,8 +4215,8 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info) num_bytes = calc_global_metadata_size(fs_info); - spin_lock(&sinfo->lock); spin_lock(&block_rsv->lock); + spin_lock(&sinfo->lock); block_rsv->size = num_bytes; @@ -4241,8 +4242,8 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info) block_rsv->full = 1; } - spin_unlock(&block_rsv->lock); spin_unlock(&sinfo->lock); + spin_unlock(&block_rsv->lock); } static void init_global_block_rsv(struct btrfs_fs_info *fs_info) @@ -6568,7 +6569,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, goto skip; } - if (!btrfs_buffer_uptodate(next, generation, 0)) { + if (!btrfs_buffer_uptodate(next, generation)) { btrfs_tree_unlock(next); free_extent_buffer(next); next = NULL; diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index c9018a05036e..cd4b5e400221 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -402,28 +402,20 @@ static int split_state(struct extent_io_tree *tree, struct extent_state *orig, return 0; } -static struct extent_state *next_state(struct extent_state *state) -{ - struct rb_node *next = rb_next(&state->rb_node); - if (next) - return rb_entry(next, struct extent_state, rb_node); - else - return NULL; -} - /* * utility function to clear some bits in an extent state struct. - * it will optionally wake up any one waiting on this state (wake == 1) + * it will optionally wake up any one waiting on this state (wake == 1), or + * forcibly remove the state from the tree (delete == 1). * * If no bits are set on the state struct after clearing things, the * struct is freed and removed from the tree */ -static struct extent_state *clear_state_bit(struct extent_io_tree *tree, - struct extent_state *state, - int *bits, int wake) +static int clear_state_bit(struct extent_io_tree *tree, + struct extent_state *state, + int *bits, int wake) { - struct extent_state *next; int bits_to_clear = *bits & ~EXTENT_CTLBITS; + int ret = state->state & bits_to_clear; if ((bits_to_clear & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) { u64 range = state->end - state->start + 1; @@ -435,7 +427,6 @@ static struct extent_state *clear_state_bit(struct extent_io_tree *tree, if (wake) wake_up(&state->wq); if (state->state == 0) { - next = next_state(state); if (state->tree) { rb_erase(&state->rb_node, &tree->state); state->tree = NULL; @@ -445,9 +436,8 @@ static struct extent_state *clear_state_bit(struct extent_io_tree *tree, } } else { merge_state(tree, state); - next = next_state(state); } - return next; + return ret; } static struct extent_state * @@ -486,6 +476,7 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, struct extent_state *state; struct extent_state *cached; struct extent_state *prealloc = NULL; + struct rb_node *next_node; struct rb_node *node; u64 last_end; int err; @@ -537,11 +528,14 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, WARN_ON(state->end < start); last_end = state->end; + if (state->end < end && !need_resched()) + next_node = rb_next(&state->rb_node); + else + next_node = NULL; + /* the state doesn't have the wanted bits, go ahead */ - if (!(state->state & bits)) { - state = next_state(state); + if (!(state->state & bits)) goto next; - } /* * | ---- desired range ---- | @@ -599,13 +593,16 @@ int clear_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, goto out; } - state = clear_state_bit(tree, state, &bits, wake); + clear_state_bit(tree, state, &bits, wake); next: if (last_end == (u64)-1) goto out; start = last_end + 1; - if (start <= end && state && !need_resched()) + if (start <= end && next_node) { + state = rb_entry(next_node, struct extent_state, + rb_node); goto hit_next; + } goto search_again; out: @@ -2304,7 +2301,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err) u64 start; u64 end; int whole_page; - int mirror; + int failed_mirror; int ret; if (err) @@ -2343,18 +2340,20 @@ static void end_bio_extent_readpage(struct bio *bio, int err) } spin_unlock(&tree->lock); - mirror = (int)(unsigned long)bio->bi_bdev; if (uptodate && tree->ops && tree->ops->readpage_end_io_hook) { ret = tree->ops->readpage_end_io_hook(page, start, end, - state, mirror); + state); if (ret) uptodate = 0; else clean_io_failure(start, page); } + if (!uptodate) + failed_mirror = (int)(unsigned long)bio->bi_bdev; + if (!uptodate && tree->ops && tree->ops->readpage_io_failed_hook) { - ret = tree->ops->readpage_io_failed_hook(page, mirror); + ret = tree->ops->readpage_io_failed_hook(page, failed_mirror); if (!ret && !err && test_bit(BIO_UPTODATE, &bio->bi_flags)) uptodate = 1; @@ -2369,7 +2368,8 @@ static void end_bio_extent_readpage(struct bio *bio, int err) * can't handle the error it will return -EIO and we * remain responsible for that page. */ - ret = bio_readpage_error(bio, page, start, end, mirror, NULL); + ret = bio_readpage_error(bio, page, start, end, + failed_mirror, NULL); if (ret == 0) { uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); @@ -4120,7 +4120,6 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, if (atomic_inc_not_zero(&exists->refs)) { spin_unlock(&mapping->private_lock); unlock_page(p); - page_cache_release(p); mark_extent_buffer_accessed(exists); goto free_eb; } @@ -4200,7 +4199,8 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, unlock_page(eb->pages[i]); } - WARN_ON(!atomic_dec_and_test(&eb->refs)); + if (!atomic_dec_and_test(&eb->refs)) + return exists; btrfs_release_extent_buffer(eb); return exists; } @@ -4462,7 +4462,7 @@ int read_extent_buffer_pages(struct extent_io_tree *tree, } clear_bit(EXTENT_BUFFER_IOERR, &eb->bflags); - eb->read_mirror = 0; + eb->failed_mirror = 0; atomic_set(&eb->io_pages, num_reads); for (i = start_i; i < num_pages; i++) { page = extent_buffer_page(eb, i); diff --git a/trunk/fs/btrfs/extent_io.h b/trunk/fs/btrfs/extent_io.h index b516c3b8dec6..faf10eb57f75 100644 --- a/trunk/fs/btrfs/extent_io.h +++ b/trunk/fs/btrfs/extent_io.h @@ -79,7 +79,7 @@ struct extent_io_ops { u64 start, u64 end, struct extent_state *state); int (*readpage_end_io_hook)(struct page *page, u64 start, u64 end, - struct extent_state *state, int mirror); + struct extent_state *state); int (*writepage_end_io_hook)(struct page *page, u64 start, u64 end, struct extent_state *state, int uptodate); void (*set_bit_hook)(struct inode *inode, struct extent_state *state, @@ -135,7 +135,7 @@ struct extent_buffer { spinlock_t refs_lock; atomic_t refs; atomic_t io_pages; - int read_mirror; + int failed_mirror; struct list_head leak_list; struct rcu_head rcu_head; pid_t lock_owner; diff --git a/trunk/fs/btrfs/file.c b/trunk/fs/btrfs/file.c index 53bf2d764bbc..d83260d7498f 100644 --- a/trunk/fs/btrfs/file.c +++ b/trunk/fs/btrfs/file.c @@ -567,7 +567,6 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, int extent_type; int recow; int ret; - int modify_tree = -1; if (drop_cache) btrfs_drop_extent_cache(inode, start, end - 1, 0); @@ -576,13 +575,10 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, if (!path) return -ENOMEM; - if (start >= BTRFS_I(inode)->disk_i_size) - modify_tree = 0; - while (1) { recow = 0; ret = btrfs_lookup_file_extent(trans, root, path, ino, - search_start, modify_tree); + search_start, -1); if (ret < 0) break; if (ret > 0 && path->slots[0] > 0 && search_start == start) { @@ -638,8 +634,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode, } search_start = max(key.offset, start); - if (recow || !modify_tree) { - modify_tree = -1; + if (recow) { btrfs_release_path(path); continue; } diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index 61b16c641ce0..115bc05e42b0 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -1947,7 +1947,7 @@ static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end, * extent_io.c will try to find good copies for us. */ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end, - struct extent_state *state, int mirror) + struct extent_state *state) { size_t offset = start - ((u64)page->index << PAGE_CACHE_SHIFT); struct inode *inode = page->mapping->host; @@ -4069,7 +4069,7 @@ static struct inode *new_simple_dir(struct super_block *s, BTRFS_I(inode)->dummy_inode = 1; inode->i_ino = BTRFS_EMPTY_SUBVOL_DIR_OBJECTID; - inode->i_op = &btrfs_dir_ro_inode_operations; + inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; @@ -4140,18 +4140,14 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) static int btrfs_dentry_delete(const struct dentry *dentry) { struct btrfs_root *root; - struct inode *inode = dentry->d_inode; - if (!inode && !IS_ROOT(dentry)) - inode = dentry->d_parent->d_inode; + if (!dentry->d_inode && !IS_ROOT(dentry)) + dentry = dentry->d_parent; - if (inode) { - root = BTRFS_I(inode)->root; + if (dentry->d_inode) { + root = BTRFS_I(dentry->d_inode)->root; if (btrfs_root_refs(&root->root_item) == 0) return 1; - - if (btrfs_ino(inode) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) - return 1; } return 0; } @@ -4192,6 +4188,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, struct btrfs_path *path; struct list_head ins_list; struct list_head del_list; + struct qstr q; int ret; struct extent_buffer *leaf; int slot; @@ -4282,6 +4279,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, while (di_cur < di_total) { struct btrfs_key location; + struct dentry *tmp; if (verify_dir_item(root, leaf, di)) break; @@ -4302,15 +4300,35 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)]; btrfs_dir_item_key_to_cpu(leaf, di, &location); - + q.name = name_ptr; + q.len = name_len; + q.hash = full_name_hash(q.name, q.len); + tmp = d_lookup(filp->f_dentry, &q); + if (!tmp) { + struct btrfs_key *newkey; + + newkey = kzalloc(sizeof(struct btrfs_key), + GFP_NOFS); + if (!newkey) + goto no_dentry; + tmp = d_alloc(filp->f_dentry, &q); + if (!tmp) { + kfree(newkey); + dput(tmp); + goto no_dentry; + } + memcpy(newkey, &location, + sizeof(struct btrfs_key)); + tmp->d_fsdata = newkey; + tmp->d_flags |= DCACHE_NEED_LOOKUP; + d_rehash(tmp); + dput(tmp); + } else { + dput(tmp); + } +no_dentry: /* is this a reference to our own snapshot? If so - * skip it. - * - * In contrast to old kernels, we insert the snapshot's - * dir item and dir index after it has been created, so - * we won't find a reference to our own snapshot. We - * still keep the following code for backward - * compatibility. + * skip it */ if (location.type == BTRFS_ROOT_ITEM_KEY && location.objectid == root->root_key.objectid) { diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index 14f8e1faa46e..18cc23d164a8 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -2262,10 +2262,7 @@ static long btrfs_ioctl_dev_info(struct btrfs_root *root, void __user *arg) di_args->bytes_used = dev->bytes_used; di_args->total_bytes = dev->total_bytes; memcpy(di_args->uuid, dev->uuid, sizeof(di_args->uuid)); - if (dev->name) - strncpy(di_args->path, dev->name, sizeof(di_args->path)); - else - di_args->path[0] = '\0'; + strncpy(di_args->path, dev->name, sizeof(di_args->path)); out: if (ret == 0 && copy_to_user(arg, di_args, sizeof(*di_args))) diff --git a/trunk/fs/btrfs/ioctl.h b/trunk/fs/btrfs/ioctl.h index 086e6bdae1c4..4f69028a68c4 100644 --- a/trunk/fs/btrfs/ioctl.h +++ b/trunk/fs/btrfs/ioctl.h @@ -252,7 +252,7 @@ struct btrfs_data_container { struct btrfs_ioctl_ino_path_args { __u64 inum; /* in */ - __u64 size; /* in */ + __u32 size; /* in */ __u64 reserved[4]; /* struct btrfs_data_container *fspath; out */ __u64 fspath; /* out */ @@ -260,7 +260,7 @@ struct btrfs_ioctl_ino_path_args { struct btrfs_ioctl_logical_ino_args { __u64 logical; /* in */ - __u64 size; /* in */ + __u32 size; /* in */ __u64 reserved[4]; /* struct btrfs_data_container *inodes; out */ __u64 inodes; diff --git a/trunk/fs/btrfs/reada.c b/trunk/fs/btrfs/reada.c index ac5d01085884..dc5d33146fdb 100644 --- a/trunk/fs/btrfs/reada.c +++ b/trunk/fs/btrfs/reada.c @@ -250,12 +250,14 @@ static struct reada_zone *reada_find_zone(struct btrfs_fs_info *fs_info, struct btrfs_bio *bbio) { int ret; + int looped = 0; struct reada_zone *zone; struct btrfs_block_group_cache *cache = NULL; u64 start; u64 end; int i; +again: zone = NULL; spin_lock(&fs_info->reada_lock); ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, @@ -272,6 +274,9 @@ static struct reada_zone *reada_find_zone(struct btrfs_fs_info *fs_info, spin_unlock(&fs_info->reada_lock); } + if (looped) + return NULL; + cache = btrfs_lookup_block_group(fs_info, logical); if (!cache) return NULL; @@ -302,15 +307,13 @@ static struct reada_zone *reada_find_zone(struct btrfs_fs_info *fs_info, ret = radix_tree_insert(&dev->reada_zones, (unsigned long)(zone->end >> PAGE_CACHE_SHIFT), zone); + spin_unlock(&fs_info->reada_lock); - if (ret == -EEXIST) { + if (ret) { kfree(zone); - ret = radix_tree_gang_lookup(&dev->reada_zones, (void **)&zone, - logical >> PAGE_CACHE_SHIFT, 1); - if (ret == 1) - kref_get(&zone->refcnt); + looped = 1; + goto again; } - spin_unlock(&fs_info->reada_lock); return zone; } @@ -320,26 +323,26 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, struct btrfs_key *top, int level) { int ret; + int looped = 0; struct reada_extent *re = NULL; - struct reada_extent *re_exist = NULL; struct btrfs_fs_info *fs_info = root->fs_info; struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree; struct btrfs_bio *bbio = NULL; struct btrfs_device *dev; - struct btrfs_device *prev_dev; u32 blocksize; u64 length; int nzones = 0; int i; unsigned long index = logical >> PAGE_CACHE_SHIFT; +again: spin_lock(&fs_info->reada_lock); re = radix_tree_lookup(&fs_info->reada_tree, index); if (re) kref_get(&re->refcnt); spin_unlock(&fs_info->reada_lock); - if (re) + if (re || looped) return re; re = kzalloc(sizeof(*re), GFP_NOFS); @@ -395,31 +398,16 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, /* insert extent in reada_tree + all per-device trees, all or nothing */ spin_lock(&fs_info->reada_lock); ret = radix_tree_insert(&fs_info->reada_tree, index, re); - if (ret == -EEXIST) { - re_exist = radix_tree_lookup(&fs_info->reada_tree, index); - BUG_ON(!re_exist); - kref_get(&re_exist->refcnt); - spin_unlock(&fs_info->reada_lock); - goto error; - } if (ret) { spin_unlock(&fs_info->reada_lock); + if (ret != -ENOMEM) { + /* someone inserted the extent in the meantime */ + looped = 1; + } goto error; } - prev_dev = NULL; for (i = 0; i < nzones; ++i) { dev = bbio->stripes[i].dev; - if (dev == prev_dev) { - /* - * in case of DUP, just add the first zone. As both - * are on the same device, there's nothing to gain - * from adding both. - * Also, it wouldn't work, as the tree is per device - * and adding would fail with EEXIST - */ - continue; - } - prev_dev = dev; ret = radix_tree_insert(&dev->reada_extents, index, re); if (ret) { while (--i >= 0) { @@ -462,7 +450,9 @@ static struct reada_extent *reada_find_extent(struct btrfs_root *root, } kfree(bbio); kfree(re); - return re_exist; + if (looped) + goto again; + return NULL; } static void reada_kref_dummy(struct kref *kr) diff --git a/trunk/fs/btrfs/relocation.c b/trunk/fs/btrfs/relocation.c index 646ee21bb035..017281dbb2a7 100644 --- a/trunk/fs/btrfs/relocation.c +++ b/trunk/fs/btrfs/relocation.c @@ -1279,9 +1279,7 @@ static int __update_reloc_root(struct btrfs_root *root, int del) if (rb_node) backref_tree_panic(rb_node, -EEXIST, node->bytenr); } else { - spin_lock(&root->fs_info->trans_lock); list_del_init(&root->root_list); - spin_unlock(&root->fs_info->trans_lock); kfree(node); } return 0; @@ -3813,7 +3811,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) ret = btrfs_block_rsv_check(rc->extent_root, rc->block_rsv, 5); if (ret < 0) { - if (ret != -ENOSPC) { + if (ret != -EAGAIN) { err = ret; WARN_ON(1); break; diff --git a/trunk/fs/btrfs/scrub.c b/trunk/fs/btrfs/scrub.c index 2f3d6f917fb3..bc015f77f3ea 100644 --- a/trunk/fs/btrfs/scrub.c +++ b/trunk/fs/btrfs/scrub.c @@ -998,7 +998,6 @@ static int scrub_setup_recheck_block(struct scrub_dev *sdev, page = sblock->pagev + page_index; page->logical = logical; page->physical = bbio->stripes[mirror_index].physical; - /* for missing devices, bdev is NULL */ page->bdev = bbio->stripes[mirror_index].dev->bdev; page->mirror_num = mirror_index + 1; page->page = alloc_page(GFP_NOFS); @@ -1043,12 +1042,6 @@ static int scrub_recheck_block(struct btrfs_fs_info *fs_info, struct scrub_page *page = sblock->pagev + page_num; DECLARE_COMPLETION_ONSTACK(complete); - if (page->bdev == NULL) { - page->io_error = 1; - sblock->no_io_error_seen = 0; - continue; - } - BUG_ON(!page->page); bio = bio_alloc(GFP_NOFS, 1); if (!bio) @@ -1264,6 +1257,12 @@ static int scrub_checksum_data(struct scrub_block *sblock) if (memcmp(csum, on_disk_csum, sdev->csum_size)) fail = 1; + if (fail) { + spin_lock(&sdev->stat_lock); + ++sdev->stat.csum_errors; + spin_unlock(&sdev->stat_lock); + } + return fail; } @@ -1336,6 +1335,15 @@ static int scrub_checksum_tree_block(struct scrub_block *sblock) if (memcmp(calculated_csum, on_disk_csum, sdev->csum_size)) ++crc_fail; + if (crc_fail || fail) { + spin_lock(&sdev->stat_lock); + if (crc_fail) + ++sdev->stat.csum_errors; + if (fail) + ++sdev->stat.verify_errors; + spin_unlock(&sdev->stat_lock); + } + return fail || crc_fail; } diff --git a/trunk/fs/btrfs/super.c b/trunk/fs/btrfs/super.c index c5f8fca4195f..8d5d380f7bdb 100644 --- a/trunk/fs/btrfs/super.c +++ b/trunk/fs/btrfs/super.c @@ -815,6 +815,7 @@ int btrfs_sync_fs(struct super_block *sb, int wait) return 0; } + btrfs_start_delalloc_inodes(root, 0); btrfs_wait_ordered_extents(root, 0, 0); trans = btrfs_start_transaction(root, 0); @@ -1147,15 +1148,13 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) if (ret) goto restore; } else { - if (fs_info->fs_devices->rw_devices == 0) { + if (fs_info->fs_devices->rw_devices == 0) ret = -EACCES; goto restore; - } - if (btrfs_super_log_root(fs_info->super_copy) != 0) { + if (btrfs_super_log_root(fs_info->super_copy) != 0) ret = -EINVAL; goto restore; - } ret = btrfs_cleanup_fs_roots(fs_info); if (ret) diff --git a/trunk/fs/btrfs/transaction.c b/trunk/fs/btrfs/transaction.c index 36422254ef67..11b77a59db62 100644 --- a/trunk/fs/btrfs/transaction.c +++ b/trunk/fs/btrfs/transaction.c @@ -73,10 +73,8 @@ static noinline int join_transaction(struct btrfs_root *root, int nofail) cur_trans = root->fs_info->running_transaction; if (cur_trans) { - if (cur_trans->aborted) { - spin_unlock(&root->fs_info->trans_lock); + if (cur_trans->aborted) return cur_trans->aborted; - } atomic_inc(&cur_trans->use_count); atomic_inc(&cur_trans->num_writers); cur_trans->num_joined++; @@ -1402,7 +1400,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, ret = commit_fs_roots(trans, root); if (ret) { mutex_unlock(&root->fs_info->tree_log_mutex); - mutex_unlock(&root->fs_info->reloc_mutex); goto cleanup_transaction; } @@ -1414,7 +1411,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, ret = commit_cowonly_roots(trans, root); if (ret) { mutex_unlock(&root->fs_info->tree_log_mutex); - mutex_unlock(&root->fs_info->reloc_mutex); goto cleanup_transaction; } diff --git a/trunk/fs/btrfs/tree-log.c b/trunk/fs/btrfs/tree-log.c index eb1ae908582c..d017283ae6f5 100644 --- a/trunk/fs/btrfs/tree-log.c +++ b/trunk/fs/btrfs/tree-log.c @@ -279,7 +279,7 @@ static int process_one_buffer(struct btrfs_root *log, log->fs_info->extent_root, eb->start, eb->len); - if (btrfs_buffer_uptodate(eb, gen, 0)) { + if (btrfs_buffer_uptodate(eb, gen)) { if (wc->write) btrfs_write_tree_block(eb); if (wc->wait) diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index 1411b99555a4..759d02486d7c 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -3324,14 +3324,12 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, stripe_size = devices_info[ndevs-1].max_avail; num_stripes = ndevs * dev_stripes; - if (stripe_size * ndevs > max_chunk_size * ncopies) { + if (stripe_size * num_stripes > max_chunk_size * ncopies) { stripe_size = max_chunk_size * ncopies; - do_div(stripe_size, ndevs); + do_div(stripe_size, num_stripes); } do_div(stripe_size, dev_stripes); - - /* align to BTRFS_STRIPE_LEN */ do_div(stripe_size, BTRFS_STRIPE_LEN); stripe_size *= BTRFS_STRIPE_LEN; @@ -3807,11 +3805,10 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, else if (mirror_num) stripe_index += mirror_num - 1; else { - int old_stripe_index = stripe_index; stripe_index = find_live_mirror(map, stripe_index, map->sub_stripes, stripe_index + current->pid % map->sub_stripes); - mirror_num = stripe_index - old_stripe_index + 1; + mirror_num = stripe_index + 1; } } else { /* @@ -4353,10 +4350,8 @@ static int open_seed_devices(struct btrfs_root *root, u8 *fsid) ret = __btrfs_open_devices(fs_devices, FMODE_READ, root->fs_info->bdev_holder); - if (ret) { - free_fs_devices(fs_devices); + if (ret) goto out; - } if (!fs_devices->seeding) { __btrfs_close_devices(fs_devices); diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 351e18ea2e53..36d66653b931 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -985,6 +985,7 @@ grow_dev_page(struct block_device *bdev, sector_t block, return page; failed: + BUG(); unlock_page(page); page_cache_release(page); return NULL; diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index ca6a3796a33b..d34212822444 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -370,13 +370,13 @@ cifs_show_options(struct seq_file *s, struct dentry *root) (int)(srcaddr->sa_family)); } - seq_printf(s, ",uid=%u", cifs_sb->mnt_uid); + seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) seq_printf(s, ",forceuid"); else seq_printf(s, ",noforceuid"); - seq_printf(s, ",gid=%u", cifs_sb->mnt_gid); + seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) seq_printf(s, ",forcegid"); else @@ -434,15 +434,11 @@ cifs_show_options(struct seq_file *s, struct dentry *root) seq_printf(s, ",noperm"); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) seq_printf(s, ",strictcache"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) - seq_printf(s, ",backupuid=%u", cifs_sb->mnt_backupuid); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) - seq_printf(s, ",backupgid=%u", cifs_sb->mnt_backupgid); - seq_printf(s, ",rsize=%u", cifs_sb->rsize); - seq_printf(s, ",wsize=%u", cifs_sb->wsize); + seq_printf(s, ",rsize=%d", cifs_sb->rsize); + seq_printf(s, ",wsize=%d", cifs_sb->wsize); /* convert actimeo and display it in seconds */ - seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); + seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); return 0; } diff --git a/trunk/fs/cifs/cifsfs.h b/trunk/fs/cifs/cifsfs.h index 65365358c976..d1389bb33ceb 100644 --- a/trunk/fs/cifs/cifsfs.h +++ b/trunk/fs/cifs/cifsfs.h @@ -125,5 +125,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); extern const struct export_operations cifs_export_ops; #endif /* CONFIG_CIFS_NFSD_EXPORT */ -#define CIFS_VERSION "1.78" +#define CIFS_VERSION "1.77" #endif /* _CIFSFS_H */ diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index da2f5446fa7a..f52c5ab78f9d 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -4844,12 +4844,8 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr, max_len = data_end - temp; node->node_name = cifs_strndup_from_utf16(temp, max_len, is_unicode, nls_codepage); - if (!node->node_name) { + if (!node->node_name) rc = -ENOMEM; - goto parse_DFS_referrals_exit; - } - - ref++; } parse_DFS_referrals_exit: diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 5dcc55197fb3..d81e933a796b 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -109,8 +109,6 @@ enum { /* Options which could be blank */ Opt_blank_pass, - Opt_blank_user, - Opt_blank_ip, Opt_err }; @@ -185,15 +183,11 @@ static const match_table_t cifs_mount_option_tokens = { { Opt_wsize, "wsize=%s" }, { Opt_actimeo, "actimeo=%s" }, - { Opt_blank_user, "user=" }, - { Opt_blank_user, "username=" }, { Opt_user, "user=%s" }, { Opt_user, "username=%s" }, { Opt_blank_pass, "pass=" }, { Opt_pass, "pass=%s" }, { Opt_pass, "password=%s" }, - { Opt_blank_ip, "ip=" }, - { Opt_blank_ip, "addr=" }, { Opt_ip, "ip=%s" }, { Opt_ip, "addr=%s" }, { Opt_unc, "unc=%s" }, @@ -215,8 +209,6 @@ static const match_table_t cifs_mount_option_tokens = { { Opt_ignore, "cred" }, { Opt_ignore, "credentials" }, - { Opt_ignore, "cred=%s" }, - { Opt_ignore, "credentials=%s" }, { Opt_ignore, "guest" }, { Opt_ignore, "rw" }, { Opt_ignore, "ro" }, @@ -1125,7 +1117,7 @@ static int get_option_ul(substring_t args[], unsigned long *option) string = match_strdup(args); if (string == NULL) return -ENOMEM; - rc = kstrtoul(string, 0, option); + rc = kstrtoul(string, 10, option); kfree(string); return rc; @@ -1542,17 +1534,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, /* String Arguments */ - case Opt_blank_user: - /* null user, ie. anonymous authentication */ - vol->nullauth = 1; - vol->username = NULL; - break; case Opt_user: string = match_strdup(args); if (string == NULL) goto out_nomem; - if (strnlen(string, MAX_USERNAME_SIZE) > + if (!*string) { + /* null user, ie. anonymous authentication */ + vol->nullauth = 1; + } else if (strnlen(string, MAX_USERNAME_SIZE) > MAX_USERNAME_SIZE) { printk(KERN_WARNING "CIFS: username too long\n"); goto cifs_parse_mount_err; @@ -1621,15 +1611,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, } vol->password[j] = '\0'; break; - case Opt_blank_ip: - vol->UNCip = NULL; - break; case Opt_ip: string = match_strdup(args); if (string == NULL) goto out_nomem; - if (strnlen(string, INET6_ADDRSTRLEN) > + if (!*string) { + vol->UNCip = NULL; + } else if (strnlen(string, INET6_ADDRSTRLEN) > INET6_ADDRSTRLEN) { printk(KERN_WARNING "CIFS: ip address " "too long\n"); @@ -1647,6 +1636,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + printk(KERN_WARNING "CIFS: invalid path to " + "network resource\n"); + goto cifs_parse_mount_err; + } + temp_len = strnlen(string, 300); if (temp_len == 300) { printk(KERN_WARNING "CIFS: UNC name too long\n"); @@ -1675,7 +1670,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (strnlen(string, 256) == 256) { + if (!*string) { + printk(KERN_WARNING "CIFS: invalid domain" + " name\n"); + goto cifs_parse_mount_err; + } else if (strnlen(string, 256) == 256) { printk(KERN_WARNING "CIFS: domain name too" " long\n"); goto cifs_parse_mount_err; @@ -1694,7 +1693,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (!cifs_convert_address( + if (!*string) { + printk(KERN_WARNING "CIFS: srcaddr value not" + " specified\n"); + goto cifs_parse_mount_err; + } else if (!cifs_convert_address( (struct sockaddr *)&vol->srcaddr, string, strlen(string))) { printk(KERN_WARNING "CIFS: Could not parse" @@ -1707,6 +1710,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + printk(KERN_WARNING "CIFS: Invalid path" + " prefix\n"); + goto cifs_parse_mount_err; + } temp_len = strnlen(string, 1024); if (string[0] != '/') temp_len++; /* missing leading slash */ @@ -1734,7 +1742,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; - if (strnlen(string, 1024) >= 65) { + if (!*string) { + printk(KERN_WARNING "CIFS: Invalid iocharset" + " specified\n"); + goto cifs_parse_mount_err; + } else if (strnlen(string, 1024) >= 65) { printk(KERN_WARNING "CIFS: iocharset name " "too long.\n"); goto cifs_parse_mount_err; @@ -1759,6 +1771,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + printk(KERN_WARNING "CIFS: No socket option" + " specified\n"); + goto cifs_parse_mount_err; + } if (strnicmp(string, "TCP_NODELAY", 11) == 0) vol->sockopt_tcp_nodelay = 1; break; @@ -1767,6 +1784,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + printk(KERN_WARNING "CIFS: Invalid (empty)" + " netbiosname\n"); + break; + } + memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN); /* @@ -1794,6 +1817,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + printk(KERN_WARNING "CIFS: Empty server" + " netbiosname specified\n"); + break; + } /* last byte, type, is 0x20 for servr type */ memset(vol->target_rfc1001_name, 0x20, RFC1001_NAME_LEN_WITH_NULL); @@ -1820,6 +1848,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + cERROR(1, "no protocol version specified" + " after vers= mount option"); + goto cifs_parse_mount_err; + } + if (strnicmp(string, "cifs", 4) == 0 || strnicmp(string, "1", 1) == 0) { /* This is the default */ @@ -1834,6 +1868,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, if (string == NULL) goto out_nomem; + if (!*string) { + printk(KERN_WARNING "CIFS: no security flavor" + " specified\n"); + break; + } + if (cifs_parse_security_flavors(string, vol) != 0) goto cifs_parse_mount_err; break; @@ -2185,7 +2225,6 @@ cifs_get_tcp_session(struct smb_vol *volume_info) tcp_ses->session_estab = false; tcp_ses->sequence_number = 0; tcp_ses->lstrp = jiffies; - spin_lock_init(&tcp_ses->req_lock); INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); INIT_LIST_HEAD(&tcp_ses->smb_ses_list); INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); @@ -3231,6 +3270,10 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, cifs_sb->mnt_uid = pvolume_info->linux_uid; cifs_sb->mnt_gid = pvolume_info->linux_gid; + if (pvolume_info->backupuid_specified) + cifs_sb->mnt_backupuid = pvolume_info->backupuid; + if (pvolume_info->backupgid_specified) + cifs_sb->mnt_backupgid = pvolume_info->backupgid; cifs_sb->mnt_file_mode = pvolume_info->file_mode; cifs_sb->mnt_dir_mode = pvolume_info->dir_mode; cFYI(1, "file mode: 0x%hx dir mode: 0x%hx", @@ -3261,14 +3304,10 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD; if (pvolume_info->cifs_acl) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; - if (pvolume_info->backupuid_specified) { + if (pvolume_info->backupuid_specified) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID; - cifs_sb->mnt_backupuid = pvolume_info->backupuid; - } - if (pvolume_info->backupgid_specified) { + if (pvolume_info->backupgid_specified) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID; - cifs_sb->mnt_backupgid = pvolume_info->backupgid; - } if (pvolume_info->override_uid) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; if (pvolume_info->override_gid) @@ -3617,6 +3656,22 @@ cifs_get_volume_info(char *mount_data, const char *devname) return volume_info; } +/* make sure ra_pages is a multiple of rsize */ +static inline unsigned int +cifs_ra_pages(struct cifs_sb_info *cifs_sb) +{ + unsigned int reads; + unsigned int rsize_pages = cifs_sb->rsize / PAGE_CACHE_SIZE; + + if (rsize_pages >= default_backing_dev_info.ra_pages) + return default_backing_dev_info.ra_pages; + else if (rsize_pages == 0) + return rsize_pages; + + reads = default_backing_dev_info.ra_pages / rsize_pages; + return reads * rsize_pages; +} + int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) { @@ -3704,7 +3759,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) cifs_sb->rsize = cifs_negotiate_rsize(tcon, volume_info); /* tune readahead according to rsize */ - cifs_sb->bdi.ra_pages = cifs_sb->rsize / PAGE_CACHE_SIZE; + cifs_sb->bdi.ra_pages = cifs_ra_pages(cifs_sb); remote_path_check: #ifdef CONFIG_CIFS_DFS_UPCALL diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index ec4e9a2a12f8..d172c8ed9017 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -668,19 +668,12 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) return 0; else { /* - * If the inode wasn't known to be a dfs entry when - * the dentry was instantiated, such as when created - * via ->readdir(), it needs to be set now since the - * attributes will have been updated by - * cifs_revalidate_dentry(). + * Forcibly invalidate automounting directory inodes + * (remote DFS directories) so to have them + * instantiated again for automount */ - if (IS_AUTOMOUNT(direntry->d_inode) && - !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) { - spin_lock(&direntry->d_lock); - direntry->d_flags |= DCACHE_NEED_AUTOMOUNT; - spin_unlock(&direntry->d_lock); - } - + if (IS_AUTOMOUNT(direntry->d_inode)) + return 0; return 1; } } diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index 81725e9286e9..fae765dac934 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -2178,7 +2178,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, unsigned long nr_pages, i; size_t copied, len, cur_len; ssize_t total_written = 0; - loff_t offset; + loff_t offset = *poffset; struct iov_iter it; struct cifsFileInfo *open_file; struct cifs_tcon *tcon; @@ -2200,7 +2200,6 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); open_file = file->private_data; tcon = tlink_tcon(open_file->tlink); - offset = *poffset; if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) pid = open_file->pid; diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index b80531c91779..b60ddc41d783 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -141,29 +141,18 @@ int proc_nr_dentry(ctl_table *table, int write, void __user *buffer, * Compare 2 name strings, return 0 if they match, otherwise non-zero. * The strings are both count bytes long, and count is non-zero. */ -#ifdef CONFIG_DCACHE_WORD_ACCESS - -#include -/* - * NOTE! 'cs' and 'scount' come from a dentry, so it has a - * aligned allocation for this particular component. We don't - * strictly need the load_unaligned_zeropad() safety, but it - * doesn't hurt either. - * - * In contrast, 'ct' and 'tcount' can be from a pathname, and do - * need the careful unaligned handling. - */ static inline int dentry_cmp(const unsigned char *cs, size_t scount, const unsigned char *ct, size_t tcount) { +#ifdef CONFIG_DCACHE_WORD_ACCESS unsigned long a,b,mask; if (unlikely(scount != tcount)) return 1; for (;;) { - a = load_unaligned_zeropad(cs); - b = load_unaligned_zeropad(ct); + a = *(unsigned long *)cs; + b = *(unsigned long *)ct; if (tcount < sizeof(unsigned long)) break; if (unlikely(a != b)) @@ -176,13 +165,7 @@ static inline int dentry_cmp(const unsigned char *cs, size_t scount, } mask = ~(~0ul << tcount*8); return unlikely(!!((a ^ b) & mask)); -} - #else - -static inline int dentry_cmp(const unsigned char *cs, size_t scount, - const unsigned char *ct, size_t tcount) -{ if (scount != tcount) return 1; @@ -194,9 +177,8 @@ static inline int dentry_cmp(const unsigned char *cs, size_t scount, tcount--; } while (tcount); return 0; -} - #endif +} static void __d_free(struct rcu_head *head) { diff --git a/trunk/fs/dlm/lock.c b/trunk/fs/dlm/lock.c index 4c58d4a3adc4..fa5c07d51dcc 100644 --- a/trunk/fs/dlm/lock.c +++ b/trunk/fs/dlm/lock.c @@ -1736,18 +1736,6 @@ static int _can_be_granted(struct dlm_rsb *r, struct dlm_lkb *lkb, int now) if (now && conv && !(lkb->lkb_exflags & DLM_LKF_QUECVT)) return 1; - /* - * Even if the convert is compat with all granted locks, - * QUECVT forces it behind other locks on the convert queue. - */ - - if (now && conv && (lkb->lkb_exflags & DLM_LKF_QUECVT)) { - if (list_empty(&r->res_convertqueue)) - return 1; - else - goto out; - } - /* * The NOORDER flag is set to avoid the standard vms rules on grant * order. diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index c0b3c70ee87a..739b0985b398 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -1663,10 +1663,8 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd, if (op == EPOLL_CTL_ADD) { if (is_file_epoll(tfile)) { error = -ELOOP; - if (ep_loop_check(ep, tfile) != 0) { - clear_tfile_check_list(); + if (ep_loop_check(ep, tfile) != 0) goto error_tgt_fput; - } } else list_add(&tfile->f_tfile_llink, &tfile_check_list); } diff --git a/trunk/fs/ext4/ext4.h b/trunk/fs/ext4/ext4.h index 0e01e90add8b..ab2594a30f86 100644 --- a/trunk/fs/ext4/ext4.h +++ b/trunk/fs/ext4/ext4.h @@ -1203,6 +1203,9 @@ struct ext4_sb_info { unsigned long s_ext_blocks; unsigned long s_ext_extents; #endif + /* ext4 extent cache stats */ + unsigned long extent_cache_hits; + unsigned long extent_cache_misses; /* for buddy allocator */ struct ext4_group_info ***s_group_info; diff --git a/trunk/fs/ext4/extents.c b/trunk/fs/ext4/extents.c index abcdeab67f52..1421938e6792 100644 --- a/trunk/fs/ext4/extents.c +++ b/trunk/fs/ext4/extents.c @@ -2066,6 +2066,10 @@ static int ext4_ext_check_cache(struct inode *inode, ext4_lblk_t block, ret = 1; } errout: + if (!ret) + sbi->extent_cache_misses++; + else + sbi->extent_cache_hits++; trace_ext4_ext_in_cache(inode, block, ret); spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); return ret; @@ -2878,7 +2882,7 @@ static int ext4_split_extent_at(handle_t *handle, if (err) goto fix_extent_len; /* update the extent length and mark as initialized */ - ex->ee_len = cpu_to_le16(ee_len); + ex->ee_len = cpu_to_le32(ee_len); ext4_ext_try_to_merge(inode, path, ex); err = ext4_ext_dirty(handle, inode, path + depth); goto out; diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index e1fb1d5de58e..ceebaf853beb 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -1305,20 +1305,20 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) ext4_msg(sb, KERN_ERR, "Cannot change journaled " "quota options when quota turned on"); - return -1; + return 0; } qname = match_strdup(args); if (!qname) { ext4_msg(sb, KERN_ERR, "Not enough memory for storing quotafile name"); - return -1; + return 0; } if (sbi->s_qf_names[qtype] && strcmp(sbi->s_qf_names[qtype], qname)) { ext4_msg(sb, KERN_ERR, "%s quota file already specified", QTYPE2NAME(qtype)); kfree(qname); - return -1; + return 0; } sbi->s_qf_names[qtype] = qname; if (strchr(sbi->s_qf_names[qtype], '/')) { @@ -1326,7 +1326,7 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) "quotafile must be on filesystem root"); kfree(sbi->s_qf_names[qtype]); sbi->s_qf_names[qtype] = NULL; - return -1; + return 0; } set_opt(sb, QUOTA); return 1; @@ -1341,7 +1341,7 @@ static int clear_qf_name(struct super_block *sb, int qtype) sbi->s_qf_names[qtype]) { ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options" " when quota turned on"); - return -1; + return 0; } /* * The space will be released later when all options are confirmed @@ -1450,16 +1450,6 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, const struct mount_opts *m; int arg = 0; -#ifdef CONFIG_QUOTA - if (token == Opt_usrjquota) - return set_qf_name(sb, USRQUOTA, &args[0]); - else if (token == Opt_grpjquota) - return set_qf_name(sb, GRPQUOTA, &args[0]); - else if (token == Opt_offusrjquota) - return clear_qf_name(sb, USRQUOTA); - else if (token == Opt_offgrpjquota) - return clear_qf_name(sb, GRPQUOTA); -#endif if (args->from && match_int(args, &arg)) return -1; switch (token) { @@ -1559,6 +1549,18 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, sbi->s_mount_opt |= m->mount_opt; } #ifdef CONFIG_QUOTA + } else if (token == Opt_usrjquota) { + if (!set_qf_name(sb, USRQUOTA, &args[0])) + return -1; + } else if (token == Opt_grpjquota) { + if (!set_qf_name(sb, GRPQUOTA, &args[0])) + return -1; + } else if (token == Opt_offusrjquota) { + if (!clear_qf_name(sb, USRQUOTA)) + return -1; + } else if (token == Opt_offgrpjquota) { + if (!clear_qf_name(sb, GRPQUOTA)) + return -1; } else if (m->flags & MOPT_QFMT) { if (sb_any_quota_loaded(sb) && sbi->s_jquota_fmt != m->mount_opt) { @@ -1597,9 +1599,7 @@ static int parse_options(char *options, struct super_block *sb, unsigned int *journal_ioprio, int is_remount) { -#ifdef CONFIG_QUOTA struct ext4_sb_info *sbi = EXT4_SB(sb); -#endif char *p; substring_t args[MAX_OPT_ARGS]; int token; @@ -2366,6 +2366,18 @@ static ssize_t lifetime_write_kbytes_show(struct ext4_attr *a, EXT4_SB(sb)->s_sectors_written_start) >> 1))); } +static ssize_t extent_cache_hits_show(struct ext4_attr *a, + struct ext4_sb_info *sbi, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_hits); +} + +static ssize_t extent_cache_misses_show(struct ext4_attr *a, + struct ext4_sb_info *sbi, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%lu\n", sbi->extent_cache_misses); +} + static ssize_t inode_readahead_blks_store(struct ext4_attr *a, struct ext4_sb_info *sbi, const char *buf, size_t count) @@ -2423,6 +2435,8 @@ static struct ext4_attr ext4_attr_##name = __ATTR(name, mode, show, store) EXT4_RO_ATTR(delayed_allocation_blocks); EXT4_RO_ATTR(session_write_kbytes); EXT4_RO_ATTR(lifetime_write_kbytes); +EXT4_RO_ATTR(extent_cache_hits); +EXT4_RO_ATTR(extent_cache_misses); EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, sbi_ui_show, inode_readahead_blks_store, s_inode_readahead_blks); EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal); @@ -2438,6 +2452,8 @@ static struct attribute *ext4_attrs[] = { ATTR_LIST(delayed_allocation_blocks), ATTR_LIST(session_write_kbytes), ATTR_LIST(lifetime_write_kbytes), + ATTR_LIST(extent_cache_hits), + ATTR_LIST(extent_cache_misses), ATTR_LIST(inode_readahead_blks), ATTR_LIST(inode_goal), ATTR_LIST(mb_stats), diff --git a/trunk/fs/fuse/dir.c b/trunk/fs/fuse/dir.c index df5ac048dc74..206632887bb4 100644 --- a/trunk/fs/fuse/dir.c +++ b/trunk/fs/fuse/dir.c @@ -387,6 +387,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, if (fc->no_create) return -ENOSYS; + if (flags & O_DIRECT) + return -EINVAL; + forget = fuse_alloc_forget(); if (!forget) return -ENOMEM; @@ -641,12 +644,13 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) fuse_put_request(fc, req); if (!err) { struct inode *inode = entry->d_inode; - struct fuse_inode *fi = get_fuse_inode(inode); - spin_lock(&fc->lock); - fi->attr_version = ++fc->attr_version; - drop_nlink(inode); - spin_unlock(&fc->lock); + /* + * Set nlink to zero so the inode can be cleared, if the inode + * does have more links this will be discovered at the next + * lookup/getattr. + */ + clear_nlink(inode); fuse_invalidate_attr(inode); fuse_invalidate_attr(dir); fuse_invalidate_entry_cache(entry); @@ -758,17 +762,8 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, will reflect changes in the backing inode (link count, etc.) */ - if (!err) { - struct fuse_inode *fi = get_fuse_inode(inode); - - spin_lock(&fc->lock); - fi->attr_version = ++fc->attr_version; - inc_nlink(inode); - spin_unlock(&fc->lock); - fuse_invalidate_attr(inode); - } else if (err == -EINTR) { + if (!err || err == -EINTR) fuse_invalidate_attr(inode); - } return err; } diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index 504e61b7fd75..a841868bf9ce 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -194,6 +194,10 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir) struct fuse_conn *fc = get_fuse_conn(inode); int err; + /* VFS checks this, but only _after_ ->open() */ + if (file->f_flags & O_DIRECT) + return -EINVAL; + err = generic_file_open(inode, file); if (err) return err; @@ -928,23 +932,17 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; size_t count = 0; - size_t ocount = 0; ssize_t written = 0; - ssize_t written_buffered = 0; struct inode *inode = mapping->host; ssize_t err; struct iov_iter i; - loff_t endbyte = 0; WARN_ON(iocb->ki_pos != pos); - ocount = 0; - err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ); + err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ); if (err) return err; - count = ocount; - mutex_lock(&inode->i_mutex); vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); @@ -964,41 +962,11 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov, file_update_time(file); - if (file->f_flags & O_DIRECT) { - written = generic_file_direct_write(iocb, iov, &nr_segs, - pos, &iocb->ki_pos, - count, ocount); - if (written < 0 || written == count) - goto out; - - pos += written; - count -= written; + iov_iter_init(&i, iov, nr_segs, count, 0); + written = fuse_perform_write(file, mapping, &i, pos); + if (written >= 0) + iocb->ki_pos = pos + written; - iov_iter_init(&i, iov, nr_segs, count, written); - written_buffered = fuse_perform_write(file, mapping, &i, pos); - if (written_buffered < 0) { - err = written_buffered; - goto out; - } - endbyte = pos + written_buffered - 1; - - err = filemap_write_and_wait_range(file->f_mapping, pos, - endbyte); - if (err) - goto out; - - invalidate_mapping_pages(file->f_mapping, - pos >> PAGE_CACHE_SHIFT, - endbyte >> PAGE_CACHE_SHIFT); - - written += written_buffered; - iocb->ki_pos = pos + written_buffered; - } else { - iov_iter_init(&i, iov, nr_segs, count, 0); - written = fuse_perform_write(file, mapping, &i, pos); - if (written >= 0) - iocb->ki_pos = pos + written; - } out: current->backing_dev_info = NULL; mutex_unlock(&inode->i_mutex); @@ -1133,24 +1101,6 @@ static ssize_t fuse_direct_read(struct file *file, char __user *buf, return res; } -static ssize_t __fuse_direct_write(struct file *file, const char __user *buf, - size_t count, loff_t *ppos) -{ - struct inode *inode = file->f_path.dentry->d_inode; - ssize_t res; - - res = generic_write_checks(file, ppos, &count, 0); - if (!res) { - res = fuse_direct_io(file, buf, count, ppos, 1); - if (res > 0) - fuse_write_update_size(inode, *ppos); - } - - fuse_invalidate_attr(inode); - - return res; -} - static ssize_t fuse_direct_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { @@ -1162,9 +1112,16 @@ static ssize_t fuse_direct_write(struct file *file, const char __user *buf, /* Don't allow parallel writes to the same file */ mutex_lock(&inode->i_mutex); - res = __fuse_direct_write(file, buf, count, ppos); + res = generic_write_checks(file, ppos, &count, 0); + if (!res) { + res = fuse_direct_io(file, buf, count, ppos, 1); + if (res > 0) + fuse_write_update_size(inode, *ppos); + } mutex_unlock(&inode->i_mutex); + fuse_invalidate_attr(inode); + return res; } @@ -2120,57 +2077,6 @@ int fuse_notify_poll_wakeup(struct fuse_conn *fc, return 0; } -static ssize_t fuse_loop_dio(struct file *filp, const struct iovec *iov, - unsigned long nr_segs, loff_t *ppos, int rw) -{ - const struct iovec *vector = iov; - ssize_t ret = 0; - - while (nr_segs > 0) { - void __user *base; - size_t len; - ssize_t nr; - - base = vector->iov_base; - len = vector->iov_len; - vector++; - nr_segs--; - - if (rw == WRITE) - nr = __fuse_direct_write(filp, base, len, ppos); - else - nr = fuse_direct_read(filp, base, len, ppos); - - if (nr < 0) { - if (!ret) - ret = nr; - break; - } - ret += nr; - if (nr != len) - break; - } - - return ret; -} - - -static ssize_t -fuse_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, - loff_t offset, unsigned long nr_segs) -{ - ssize_t ret = 0; - struct file *file = NULL; - loff_t pos = 0; - - file = iocb->ki_filp; - pos = offset; - - ret = fuse_loop_dio(file, iov, nr_segs, &pos, rw); - - return ret; -} - static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, .read = do_sync_read, @@ -2214,7 +2120,6 @@ static const struct address_space_operations fuse_file_aops = { .readpages = fuse_readpages, .set_page_dirty = __set_page_dirty_nobuffers, .bmap = fuse_bmap, - .direct_IO = fuse_direct_IO, }; void fuse_init_file_inode(struct inode *inode) diff --git a/trunk/fs/fuse/inode.c b/trunk/fs/fuse/inode.c index 26783eb2b1fc..4aec5995867e 100644 --- a/trunk/fs/fuse/inode.c +++ b/trunk/fs/fuse/inode.c @@ -947,7 +947,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) sb->s_magic = FUSE_SUPER_MAGIC; sb->s_op = &fuse_super_operations; sb->s_maxbytes = MAX_LFS_FILESIZE; - sb->s_time_gran = 1; sb->s_export_op = &fuse_export_operations; file = fget(d.fd); diff --git a/trunk/fs/gfs2/lock_dlm.c b/trunk/fs/gfs2/lock_dlm.c index 5f5e70e047dc..f8411bd1b805 100644 --- a/trunk/fs/gfs2/lock_dlm.c +++ b/trunk/fs/gfs2/lock_dlm.c @@ -200,11 +200,10 @@ static int make_mode(const unsigned int lmstate) return -1; } -static u32 make_flags(struct gfs2_glock *gl, const unsigned int gfs_flags, +static u32 make_flags(const u32 lkid, const unsigned int gfs_flags, const int req) { u32 lkf = DLM_LKF_VALBLK; - u32 lkid = gl->gl_lksb.sb_lkid; if (gfs_flags & LM_FLAG_TRY) lkf |= DLM_LKF_NOQUEUE; @@ -228,11 +227,8 @@ static u32 make_flags(struct gfs2_glock *gl, const unsigned int gfs_flags, BUG(); } - if (lkid != 0) { + if (lkid != 0) lkf |= DLM_LKF_CONVERT; - if (test_bit(GLF_BLOCKING, &gl->gl_flags)) - lkf |= DLM_LKF_QUECVT; - } return lkf; } @@ -254,7 +250,7 @@ static int gdlm_lock(struct gfs2_glock *gl, unsigned int req_state, char strname[GDLM_STRNAME_BYTES] = ""; req = make_mode(req_state); - lkf = make_flags(gl, flags, req); + lkf = make_flags(gl->gl_lksb.sb_lkid, flags, req); gfs2_glstats_inc(gl, GFS2_LKS_DCOUNT); gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT); if (gl->gl_lksb.sb_lkid) { diff --git a/trunk/fs/hfsplus/catalog.c b/trunk/fs/hfsplus/catalog.c index ec2a9c23f0c9..4dfbfec357e8 100644 --- a/trunk/fs/hfsplus/catalog.c +++ b/trunk/fs/hfsplus/catalog.c @@ -366,10 +366,6 @@ int hfsplus_rename_cat(u32 cnid, err = hfs_brec_find(&src_fd); if (err) goto out; - if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) { - err = -EIO; - goto out; - } hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset, src_fd.entrylength); diff --git a/trunk/fs/hfsplus/dir.c b/trunk/fs/hfsplus/dir.c index 26b53fb09f68..88e155f895c6 100644 --- a/trunk/fs/hfsplus/dir.c +++ b/trunk/fs/hfsplus/dir.c @@ -150,11 +150,6 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) filp->f_pos++; /* fall through */ case 1: - if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { - err = -EIO; - goto out; - } - hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); if (be16_to_cpu(entry.type) != HFSPLUS_FOLDER_THREAD) { @@ -186,12 +181,6 @@ static int hfsplus_readdir(struct file *filp, void *dirent, filldir_t filldir) err = -EIO; goto out; } - - if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { - err = -EIO; - goto out; - } - hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); type = be16_to_cpu(entry.type); diff --git a/trunk/fs/hugetlbfs/inode.c b/trunk/fs/hugetlbfs/inode.c index 001ef01d2fe2..28cf06e4ec84 100644 --- a/trunk/fs/hugetlbfs/inode.c +++ b/trunk/fs/hugetlbfs/inode.c @@ -485,7 +485,6 @@ static struct inode *hugetlbfs_get_root(struct super_block *sb, inode->i_fop = &simple_dir_operations; /* directory inodes start off with i_nlink == 2 (for "." entry) */ inc_nlink(inode); - lockdep_annotate_inode_mutex_key(inode); } return inode; } diff --git a/trunk/fs/jbd2/commit.c b/trunk/fs/jbd2/commit.c index 840f70f50792..806525a7269c 100644 --- a/trunk/fs/jbd2/commit.c +++ b/trunk/fs/jbd2/commit.c @@ -723,7 +723,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) if (commit_transaction->t_need_data_flush && (journal->j_fs_dev != journal->j_dev) && (journal->j_flags & JBD2_BARRIER)) - blkdev_issue_flush(journal->j_fs_dev, GFP_NOFS, NULL); + blkdev_issue_flush(journal->j_fs_dev, GFP_KERNEL, NULL); /* Done it all: now write the commit record asynchronously. */ if (JBD2_HAS_INCOMPAT_FEATURE(journal, @@ -859,7 +859,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) && journal->j_flags & JBD2_BARRIER) { - blkdev_issue_flush(journal->j_dev, GFP_NOFS, NULL); + blkdev_issue_flush(journal->j_dev, GFP_KERNEL, NULL); } if (err) diff --git a/trunk/fs/lockd/clnt4xdr.c b/trunk/fs/lockd/clnt4xdr.c index 13ad1539fbf2..3ddcbb1c0a43 100644 --- a/trunk/fs/lockd/clnt4xdr.c +++ b/trunk/fs/lockd/clnt4xdr.c @@ -241,7 +241,7 @@ static int decode_nlm4_stat(struct xdr_stream *xdr, __be32 *stat) p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) goto out_overflow; - if (unlikely(ntohl(*p) > ntohl(nlm4_failed))) + if (unlikely(*p > nlm4_failed)) goto out_bad_xdr; *stat = *p; return 0; diff --git a/trunk/fs/lockd/clntxdr.c b/trunk/fs/lockd/clntxdr.c index d269ada7670e..3d35e3e80c1c 100644 --- a/trunk/fs/lockd/clntxdr.c +++ b/trunk/fs/lockd/clntxdr.c @@ -236,7 +236,7 @@ static int decode_nlm_stat(struct xdr_stream *xdr, p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) goto out_overflow; - if (unlikely(ntohl(*p) > ntohl(nlm_lck_denied_grace_period))) + if (unlikely(*p > nlm_lck_denied_grace_period)) goto out_enum; *stat = *p; return 0; diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index c42791914f82..0062dd17eb55 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -1429,7 +1429,7 @@ unsigned int full_name_hash(const unsigned char *name, unsigned int len) unsigned long hash = 0; for (;;) { - a = load_unaligned_zeropad(name); + a = *(unsigned long *)name; if (len < sizeof(unsigned long)) break; hash += a; @@ -1459,7 +1459,7 @@ static inline unsigned long hash_name(const char *name, unsigned int *hashp) do { hash = (hash + a) * 9; len += sizeof(unsigned long); - a = load_unaligned_zeropad(name+len); + a = *(unsigned long *)(name+len); /* Do we have any NUL or '/' bytes in this word? */ mask = has_zero(a) | has_zero(a ^ REPEAT_BYTE('/')); } while (!mask); diff --git a/trunk/fs/nfs/blocklayout/blocklayout.c b/trunk/fs/nfs/blocklayout/blocklayout.c index 7f6a23f0244e..9c94297bb70e 100644 --- a/trunk/fs/nfs/blocklayout/blocklayout.c +++ b/trunk/fs/nfs/blocklayout/blocklayout.c @@ -38,8 +38,6 @@ #include /* various write calls */ #include -#include "../pnfs.h" -#include "../internal.h" #include "blocklayout.h" #define NFSDBG_FACILITY NFSDBG_PNFS_LD @@ -870,7 +868,7 @@ nfs4_blk_get_deviceinfo(struct nfs_server *server, const struct nfs_fh *fh, * GETDEVICEINFO's maxcount */ max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; - max_pages = nfs_page_array_len(0, max_resp_sz); + max_pages = max_resp_sz >> PAGE_SHIFT; dprintk("%s max_resp_sz %u max_pages %d\n", __func__, max_resp_sz, max_pages); diff --git a/trunk/fs/nfs/client.c b/trunk/fs/nfs/client.c index 60f7e4ec842c..da7b5e4ff9ec 100644 --- a/trunk/fs/nfs/client.c +++ b/trunk/fs/nfs/client.c @@ -1729,8 +1729,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, */ struct nfs_server *nfs_clone_server(struct nfs_server *source, struct nfs_fh *fh, - struct nfs_fattr *fattr, - rpc_authflavor_t flavor) + struct nfs_fattr *fattr) { struct nfs_server *server; struct nfs_fattr *fattr_fsinfo; @@ -1759,7 +1758,7 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source, error = nfs_init_server_rpcclient(server, source->client->cl_timeout, - flavor); + source->client->cl_auth->au_flavor); if (error < 0) goto out_free_server; if (!IS_ERR(source->client_acl)) diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index 8789210c6905..4aaf0316d76a 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -1429,7 +1429,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry } open_flags = nd->intent.open.flags; - attr.ia_valid = ATTR_OPEN; + attr.ia_valid = 0; ctx = create_nfs_open_context(dentry, open_flags); res = ERR_CAST(ctx); @@ -1536,7 +1536,7 @@ static int nfs_open_revalidate(struct dentry *dentry, struct nameidata *nd) if (IS_ERR(ctx)) goto out; - attr.ia_valid = ATTR_OPEN; + attr.ia_valid = 0; if (openflags & O_TRUNC) { attr.ia_valid |= ATTR_SIZE; attr.ia_size = 0; diff --git a/trunk/fs/nfs/idmap.c b/trunk/fs/nfs/idmap.c index ba3019f5934c..b7f348bb618b 100644 --- a/trunk/fs/nfs/idmap.c +++ b/trunk/fs/nfs/idmap.c @@ -554,16 +554,12 @@ static int rpc_pipefs_event(struct notifier_block *nb, unsigned long event, struct nfs_client *clp; int error = 0; - if (!try_module_get(THIS_MODULE)) - return 0; - while ((clp = nfs_get_client_for_event(sb->s_fs_info, event))) { error = __rpc_pipefs_event(clp, event, sb); nfs_put_client(clp); if (error) break; } - module_put(THIS_MODULE); return error; } diff --git a/trunk/fs/nfs/internal.h b/trunk/fs/nfs/internal.h index b777bdaba4c5..2476dc69365f 100644 --- a/trunk/fs/nfs/internal.h +++ b/trunk/fs/nfs/internal.h @@ -165,8 +165,7 @@ extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, extern void nfs_free_server(struct nfs_server *server); extern struct nfs_server *nfs_clone_server(struct nfs_server *, struct nfs_fh *, - struct nfs_fattr *, - rpc_authflavor_t); + struct nfs_fattr *); extern void nfs_mark_client_ready(struct nfs_client *clp, int state); extern int nfs4_check_client_ready(struct nfs_client *clp); extern struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp, @@ -187,10 +186,10 @@ static inline void nfs_fs_proc_exit(void) /* nfs4namespace.c */ #ifdef CONFIG_NFS_V4 -extern struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry); +extern struct vfsmount *nfs_do_refmount(struct dentry *dentry); #else static inline -struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry) +struct vfsmount *nfs_do_refmount(struct dentry *dentry) { return ERR_PTR(-ENOENT); } @@ -235,6 +234,7 @@ extern const u32 nfs41_maxwrite_overhead; /* nfs4proc.c */ #ifdef CONFIG_NFS_V4 extern struct rpc_procinfo nfs4_procedures[]; +void nfs_fixup_secinfo_attributes(struct nfs_fattr *, struct nfs_fh *); #endif extern int nfs4_init_ds_session(struct nfs_client *clp); diff --git a/trunk/fs/nfs/namespace.c b/trunk/fs/nfs/namespace.c index d51868e5683c..1807866bb3ab 100644 --- a/trunk/fs/nfs/namespace.c +++ b/trunk/fs/nfs/namespace.c @@ -148,31 +148,66 @@ rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *flavors) return pseudoflavor; } -static struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir, - struct qstr *name, - struct nfs_fh *fh, - struct nfs_fattr *fattr) +static int nfs_negotiate_security(const struct dentry *parent, + const struct dentry *dentry, + rpc_authflavor_t *flavor) { - int err; + struct page *page; + struct nfs4_secinfo_flavors *flavors; + int (*secinfo)(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); + int ret = -EPERM; + + secinfo = NFS_PROTO(parent->d_inode)->secinfo; + if (secinfo != NULL) { + page = alloc_page(GFP_KERNEL); + if (!page) { + ret = -ENOMEM; + goto out; + } + flavors = page_address(page); + ret = secinfo(parent->d_inode, &dentry->d_name, flavors); + *flavor = nfs_find_best_sec(flavors); + put_page(page); + } - if (NFS_PROTO(dir)->version == 4) - return nfs4_proc_lookup_mountpoint(dir, name, fh, fattr); +out: + return ret; +} - err = NFS_PROTO(dir)->lookup(NFS_SERVER(dir)->client, dir, name, fh, fattr); - if (err) - return ERR_PTR(err); - return rpc_clone_client(NFS_SERVER(dir)->client); +static int nfs_lookup_with_sec(struct nfs_server *server, struct dentry *parent, + struct dentry *dentry, struct path *path, + struct nfs_fh *fh, struct nfs_fattr *fattr, + rpc_authflavor_t *flavor) +{ + struct rpc_clnt *clone; + struct rpc_auth *auth; + int err; + + err = nfs_negotiate_security(parent, path->dentry, flavor); + if (err < 0) + goto out; + clone = rpc_clone_client(server->client); + auth = rpcauth_create(*flavor, clone); + if (!auth) { + err = -EIO; + goto out_shutdown; + } + err = server->nfs_client->rpc_ops->lookup(clone, parent->d_inode, + &path->dentry->d_name, + fh, fattr); +out_shutdown: + rpc_shutdown_client(clone); +out: + return err; } #else /* CONFIG_NFS_V4 */ -static inline struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir, - struct qstr *name, - struct nfs_fh *fh, - struct nfs_fattr *fattr) +static inline int nfs_lookup_with_sec(struct nfs_server *server, + struct dentry *parent, struct dentry *dentry, + struct path *path, struct nfs_fh *fh, + struct nfs_fattr *fattr, + rpc_authflavor_t *flavor) { - int err = NFS_PROTO(dir)->lookup(NFS_SERVER(dir)->client, dir, name, fh, fattr); - if (err) - return ERR_PTR(err); - return rpc_clone_client(NFS_SERVER(dir)->client); + return -EPERM; } #endif /* CONFIG_NFS_V4 */ @@ -191,10 +226,12 @@ static inline struct rpc_clnt *nfs_lookup_mountpoint(struct inode *dir, struct vfsmount *nfs_d_automount(struct path *path) { struct vfsmount *mnt; + struct nfs_server *server = NFS_SERVER(path->dentry->d_inode); struct dentry *parent; struct nfs_fh *fh = NULL; struct nfs_fattr *fattr = NULL; - struct rpc_clnt *client; + int err; + rpc_authflavor_t flavor = RPC_AUTH_UNIX; dprintk("--> nfs_d_automount()\n"); @@ -212,19 +249,21 @@ struct vfsmount *nfs_d_automount(struct path *path) /* Look it up again to get its attributes */ parent = dget_parent(path->dentry); - client = nfs_lookup_mountpoint(parent->d_inode, &path->dentry->d_name, fh, fattr); + err = server->nfs_client->rpc_ops->lookup(server->client, parent->d_inode, + &path->dentry->d_name, + fh, fattr); + if (err == -EPERM && NFS_PROTO(parent->d_inode)->secinfo != NULL) + err = nfs_lookup_with_sec(server, parent, path->dentry, path, fh, fattr, &flavor); dput(parent); - if (IS_ERR(client)) { - mnt = ERR_CAST(client); + if (err != 0) { + mnt = ERR_PTR(err); goto out; } if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) - mnt = nfs_do_refmount(client, path->dentry); + mnt = nfs_do_refmount(path->dentry); else - mnt = nfs_do_submount(path->dentry, fh, fattr, client->cl_auth->au_flavor); - rpc_shutdown_client(client); - + mnt = nfs_do_submount(path->dentry, fh, fattr, flavor); if (IS_ERR(mnt)) goto out; diff --git a/trunk/fs/nfs/nfs4_fs.h b/trunk/fs/nfs/nfs4_fs.h index 8d75021020b3..97ecc863dd76 100644 --- a/trunk/fs/nfs/nfs4_fs.h +++ b/trunk/fs/nfs/nfs4_fs.h @@ -59,7 +59,6 @@ struct nfs_unique_id { #define NFS_SEQID_CONFIRMED 1 struct nfs_seqid_counter { - ktime_t create_time; int owner_id; int flags; u32 counter; @@ -205,9 +204,6 @@ struct nfs4_state_maintenance_ops { extern const struct dentry_operations nfs4_dentry_operations; extern const struct inode_operations nfs4_dir_inode_operations; -/* nfs4namespace.c */ -struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *); - /* nfs4proc.c */ extern int nfs4_proc_setclientid(struct nfs_client *, u32, unsigned short, struct rpc_cred *, struct nfs4_setclientid_res *); extern int nfs4_proc_setclientid_confirm(struct nfs_client *, struct nfs4_setclientid_res *arg, struct rpc_cred *); @@ -216,11 +212,8 @@ extern int nfs4_init_clientid(struct nfs_client *, struct rpc_cred *); extern int nfs41_init_clientid(struct nfs_client *, struct rpc_cred *); extern int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait, bool roc); extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle); -extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struct qstr *, - struct nfs4_fs_locations *, struct page *); -extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, struct qstr *, - struct nfs_fh *, struct nfs_fattr *); -extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *); +extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, + struct nfs4_fs_locations *fs_locations, struct page *page); extern int nfs4_release_lockowner(struct nfs4_lock_state *); extern const struct xattr_handler *nfs4_xattr_handlers[]; diff --git a/trunk/fs/nfs/nfs4filelayoutdev.c b/trunk/fs/nfs/nfs4filelayoutdev.c index c9cff9adb2d3..a866bbd2890a 100644 --- a/trunk/fs/nfs/nfs4filelayoutdev.c +++ b/trunk/fs/nfs/nfs4filelayoutdev.c @@ -699,7 +699,7 @@ get_device_info(struct inode *inode, struct nfs4_deviceid *dev_id, gfp_t gfp_fla * GETDEVICEINFO's maxcount */ max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; - max_pages = nfs_page_array_len(0, max_resp_sz); + max_pages = max_resp_sz >> PAGE_SHIFT; dprintk("%s inode %p max_resp_sz %u max_pages %d\n", __func__, inode, max_resp_sz, max_pages); diff --git a/trunk/fs/nfs/nfs4namespace.c b/trunk/fs/nfs/nfs4namespace.c index a7f3dedc4ec7..9c8eca315f43 100644 --- a/trunk/fs/nfs/nfs4namespace.c +++ b/trunk/fs/nfs/nfs4namespace.c @@ -51,30 +51,6 @@ static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname, return ERR_PTR(-ENAMETOOLONG); } -/* - * return the path component of ":" - * nfspath - the ":" string - * end - one past the last char that could contain ":" - * returns NULL on failure - */ -static char *nfs_path_component(const char *nfspath, const char *end) -{ - char *p; - - if (*nfspath == '[') { - /* parse [] escaped IPv6 addrs */ - p = strchr(nfspath, ']'); - if (p != NULL && ++p < end && *p == ':') - return p + 1; - } else { - /* otherwise split on first colon */ - p = strchr(nfspath, ':'); - if (p != NULL && p < end) - return p + 1; - } - return NULL; -} - /* * Determine the mount path as a string */ @@ -83,9 +59,9 @@ static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen) char *limit; char *path = nfs_path(&limit, dentry, buffer, buflen); if (!IS_ERR(path)) { - char *path_component = nfs_path_component(path, limit); - if (path_component) - return path_component; + char *colon = strchr(path, ':'); + if (colon && colon < limit) + path = colon + 1; } return path; } @@ -132,58 +108,6 @@ static size_t nfs_parse_server_name(char *string, size_t len, return ret; } -static rpc_authflavor_t nfs4_negotiate_security(struct inode *inode, struct qstr *name) -{ - struct page *page; - struct nfs4_secinfo_flavors *flavors; - rpc_authflavor_t flavor; - int err; - - page = alloc_page(GFP_KERNEL); - if (!page) - return -ENOMEM; - flavors = page_address(page); - - err = nfs4_proc_secinfo(inode, name, flavors); - if (err < 0) { - flavor = err; - goto out; - } - - flavor = nfs_find_best_sec(flavors); - -out: - put_page(page); - return flavor; -} - -/* - * Please call rpc_shutdown_client() when you are done with this client. - */ -struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *clnt, struct inode *inode, - struct qstr *name) -{ - struct rpc_clnt *clone; - struct rpc_auth *auth; - rpc_authflavor_t flavor; - - flavor = nfs4_negotiate_security(inode, name); - if (flavor < 0) - return ERR_PTR(flavor); - - clone = rpc_clone_client(clnt); - if (IS_ERR(clone)) - return clone; - - auth = rpcauth_create(flavor, clone); - if (!auth) { - rpc_shutdown_client(clone); - clone = ERR_PTR(-EIO); - } - - return clone; -} - static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, char *page, char *page2, const struct nfs4_fs_location *location) @@ -300,7 +224,7 @@ static struct vfsmount *nfs_follow_referral(struct dentry *dentry, * @dentry - dentry of referral * */ -struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry) +struct vfsmount *nfs_do_refmount(struct dentry *dentry) { struct vfsmount *mnt = ERR_PTR(-ENOMEM); struct dentry *parent; @@ -326,7 +250,7 @@ struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry) dprintk("%s: getting locations for %s/%s\n", __func__, parent->d_name.name, dentry->d_name.name); - err = nfs4_proc_fs_locations(client, parent->d_inode, &dentry->d_name, fs_locations, page); + err = nfs4_proc_fs_locations(parent->d_inode, &dentry->d_name, fs_locations, page); dput(parent); if (err != 0 || fs_locations->nlocations <= 0 || diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index 99650aaf8937..f82bde005a82 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -838,8 +838,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, p->o_arg.open_flags = flags; p->o_arg.fmode = fmode & (FMODE_READ|FMODE_WRITE); p->o_arg.clientid = server->nfs_client->cl_clientid; - p->o_arg.id.create_time = ktime_to_ns(sp->so_seqid.create_time); - p->o_arg.id.uniquifier = sp->so_seqid.owner_id; + p->o_arg.id = sp->so_seqid.owner_id; p->o_arg.name = &dentry->d_name; p->o_arg.server = server; p->o_arg.bitmask = server->attr_bitmask; @@ -1467,7 +1466,8 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata) goto unlock_no_action; rcu_read_unlock(); } - /* Update client id. */ + /* Update sequence id. */ + data->o_arg.id = sp->so_seqid.owner_id; data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid; if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) { task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR]; @@ -1954,19 +1954,10 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred, }; int err; do { - err = _nfs4_do_setattr(inode, cred, fattr, sattr, state); - switch (err) { - case -NFS4ERR_OPENMODE: - if (state && !(state->state & FMODE_WRITE)) { - err = -EBADF; - if (sattr->ia_valid & ATTR_OPEN) - err = -EACCES; - goto out; - } - } - err = nfs4_handle_exception(server, err, &exception); + err = nfs4_handle_exception(server, + _nfs4_do_setattr(inode, cred, fattr, sattr, state), + &exception); } while (exception.retry); -out: return err; } @@ -2377,9 +2368,8 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, * Note that we'll actually follow the referral later when * we detect fsid mismatch in inode revalidation */ -static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir, - const struct qstr *name, struct nfs_fattr *fattr, - struct nfs_fh *fhandle) +static int nfs4_get_referral(struct inode *dir, const struct qstr *name, + struct nfs_fattr *fattr, struct nfs_fh *fhandle) { int status = -ENOMEM; struct page *page = NULL; @@ -2392,7 +2382,7 @@ static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir, if (locations == NULL) goto out; - status = nfs4_proc_fs_locations(client, dir, name, locations, page); + status = nfs4_proc_fs_locations(dir, name, locations, page); if (status != 0) goto out; /* Make sure server returned a different fsid for the referral */ @@ -2529,84 +2519,39 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, return status; } -static void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr) +void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr, struct nfs_fh *fh) { + memset(fh, 0, sizeof(struct nfs_fh)); + fattr->fsid.major = 1; fattr->valid |= NFS_ATTR_FATTR_TYPE | NFS_ATTR_FATTR_MODE | - NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_MOUNTPOINT; + NFS_ATTR_FATTR_NLINK | NFS_ATTR_FATTR_FSID | NFS_ATTR_FATTR_MOUNTPOINT; fattr->mode = S_IFDIR | S_IRUGO | S_IXUGO; fattr->nlink = 2; } -static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir, - struct qstr *name, struct nfs_fh *fhandle, - struct nfs_fattr *fattr) +static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qstr *name, + struct nfs_fh *fhandle, struct nfs_fattr *fattr) { struct nfs4_exception exception = { }; - struct rpc_clnt *client = *clnt; int err; do { - err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr); - switch (err) { + int status; + + status = _nfs4_proc_lookup(clnt, dir, name, fhandle, fattr); + switch (status) { case -NFS4ERR_BADNAME: - err = -ENOENT; - goto out; + return -ENOENT; case -NFS4ERR_MOVED: - err = nfs4_get_referral(client, dir, name, fattr, fhandle); - goto out; + return nfs4_get_referral(dir, name, fattr, fhandle); case -NFS4ERR_WRONGSEC: - err = -EPERM; - if (client != *clnt) - goto out; - - client = nfs4_create_sec_client(client, dir, name); - if (IS_ERR(client)) - return PTR_ERR(client); - - exception.retry = 1; - break; - default: - err = nfs4_handle_exception(NFS_SERVER(dir), err, &exception); + nfs_fixup_secinfo_attributes(fattr, fhandle); } + err = nfs4_handle_exception(NFS_SERVER(dir), + status, &exception); } while (exception.retry); - -out: - if (err == 0) - *clnt = client; - else if (client != *clnt) - rpc_shutdown_client(client); - return err; } -static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qstr *name, - struct nfs_fh *fhandle, struct nfs_fattr *fattr) -{ - int status; - struct rpc_clnt *client = NFS_CLIENT(dir); - - status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr); - if (client != NFS_CLIENT(dir)) { - rpc_shutdown_client(client); - nfs_fixup_secinfo_attributes(fattr); - } - return status; -} - -struct rpc_clnt * -nfs4_proc_lookup_mountpoint(struct inode *dir, struct qstr *name, - struct nfs_fh *fhandle, struct nfs_fattr *fattr) -{ - int status; - struct rpc_clnt *client = rpc_clone_client(NFS_CLIENT(dir)); - - status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr); - if (status < 0) { - rpc_shutdown_client(client); - return ERR_PTR(status); - } - return client; -} - static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) { struct nfs_server *server = NFS_SERVER(inode); @@ -3674,16 +3619,16 @@ static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_ return ret; } -static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len) +static void nfs4_write_cached_acl(struct inode *inode, const char *buf, size_t acl_len) { struct nfs4_cached_acl *acl; - if (pages && acl_len <= PAGE_SIZE) { + if (buf && acl_len <= PAGE_SIZE) { acl = kmalloc(sizeof(*acl) + acl_len, GFP_KERNEL); if (acl == NULL) goto out; acl->cached = 1; - _copy_from_pages(acl->data, pages, pgbase, acl_len); + memcpy(acl->data, buf, acl_len); } else { acl = kmalloc(sizeof(*acl), GFP_KERNEL); if (acl == NULL) @@ -3716,6 +3661,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu struct nfs_getaclres res = { .acl_len = buflen, }; + void *resp_buf; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL], .rpc_argp = &args, @@ -3729,27 +3675,24 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu if (npages == 0) npages = 1; - /* Add an extra page to handle the bitmap returned */ - npages++; - for (i = 0; i < npages; i++) { pages[i] = alloc_page(GFP_KERNEL); if (!pages[i]) goto out_free; } - - /* for decoding across pages */ - res.acl_scratch = alloc_page(GFP_KERNEL); - if (!res.acl_scratch) - goto out_free; - + if (npages > 1) { + /* for decoding across pages */ + res.acl_scratch = alloc_page(GFP_KERNEL); + if (!res.acl_scratch) + goto out_free; + } args.acl_len = npages * PAGE_SIZE; args.acl_pgbase = 0; - /* Let decode_getfacl know not to fail if the ACL data is larger than * the page we send as a guess */ if (buf == NULL) res.acl_flags |= NFS4_ACL_LEN_REQUEST; + resp_buf = page_address(pages[0]); dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", __func__, buf, buflen, npages, args.acl_len); @@ -3760,9 +3703,9 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu acl_len = res.acl_len - res.acl_data_offset; if (acl_len > args.acl_len) - nfs4_write_cached_acl(inode, NULL, 0, acl_len); + nfs4_write_cached_acl(inode, NULL, acl_len); else - nfs4_write_cached_acl(inode, pages, res.acl_data_offset, + nfs4_write_cached_acl(inode, resp_buf + res.acl_data_offset, acl_len); if (buf) { ret = -ERANGE; @@ -4615,9 +4558,7 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request) { struct nfs_server *server = NFS_SERVER(state->inode); - struct nfs4_exception exception = { - .inode = state->inode, - }; + struct nfs4_exception exception = { }; int err; do { @@ -4635,9 +4576,7 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request) { struct nfs_server *server = NFS_SERVER(state->inode); - struct nfs4_exception exception = { - .inode = state->inode, - }; + struct nfs4_exception exception = { }; int err; err = nfs4_set_lock_state(state, request); @@ -4737,7 +4676,6 @@ static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock * { struct nfs4_exception exception = { .state = state, - .inode = state->inode, }; int err; @@ -4783,20 +4721,6 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request) if (state == NULL) return -ENOLCK; - /* - * Don't rely on the VFS having checked the file open mode, - * since it won't do this for flock() locks. - */ - switch (request->fl_type & (F_RDLCK|F_WRLCK|F_UNLCK)) { - case F_RDLCK: - if (!(filp->f_mode & FMODE_READ)) - return -EBADF; - break; - case F_WRLCK: - if (!(filp->f_mode & FMODE_WRITE)) - return -EBADF; - } - do { status = nfs4_proc_setlk(state, cmd, request); if ((status != -EAGAIN) || IS_SETLK(cmd)) @@ -4967,10 +4891,8 @@ static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr) fattr->nlink = 2; } -static int _nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir, - const struct qstr *name, - struct nfs4_fs_locations *fs_locations, - struct page *page) +int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name, + struct nfs4_fs_locations *fs_locations, struct page *page) { struct nfs_server *server = NFS_SERVER(dir); u32 bitmask[2] = { @@ -5004,26 +4926,11 @@ static int _nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir, nfs_fattr_init(&fs_locations->fattr); fs_locations->server = server; fs_locations->nlocations = 0; - status = nfs4_call_sync(client, server, &msg, &args.seq_args, &res.seq_res, 0); + status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0); dprintk("%s: returned status = %d\n", __func__, status); return status; } -int nfs4_proc_fs_locations(struct rpc_clnt *client, struct inode *dir, - const struct qstr *name, - struct nfs4_fs_locations *fs_locations, - struct page *page) -{ - struct nfs4_exception exception = { }; - int err; - do { - err = nfs4_handle_exception(NFS_SERVER(dir), - _nfs4_proc_fs_locations(client, dir, name, fs_locations, page), - &exception); - } while (exception.retry); - return err; -} - static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct nfs4_secinfo_flavors *flavors) { int status; @@ -5046,8 +4953,8 @@ static int _nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, struct return status; } -int nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, - struct nfs4_secinfo_flavors *flavors) +static int nfs4_proc_secinfo(struct inode *dir, const struct qstr *name, + struct nfs4_secinfo_flavors *flavors) { struct nfs4_exception exception = { }; int err; @@ -5122,9 +5029,10 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred) nfs4_construct_boot_verifier(clp, &verifier); args.id_len = scnprintf(args.id, sizeof(args.id), - "%s/%s/%u", + "%s/%s.%s/%u", clp->cl_ipaddr, - clp->cl_rpcclient->cl_nodename, + init_utsname()->nodename, + init_utsname()->domainname, clp->cl_rpcclient->cl_auth->au_flavor); res.server_scope = kzalloc(sizeof(struct server_scope), GFP_KERNEL); diff --git a/trunk/fs/nfs/nfs4state.c b/trunk/fs/nfs/nfs4state.c index 7f0fcfc1fe9d..0f43414eb25a 100644 --- a/trunk/fs/nfs/nfs4state.c +++ b/trunk/fs/nfs/nfs4state.c @@ -393,7 +393,6 @@ nfs4_remove_state_owner_locked(struct nfs4_state_owner *sp) static void nfs4_init_seqid_counter(struct nfs_seqid_counter *sc) { - sc->create_time = ktime_get(); sc->flags = 0; sc->counter = 0; spin_lock_init(&sc->lock); @@ -435,17 +434,13 @@ nfs4_alloc_state_owner(struct nfs_server *server, static void nfs4_drop_state_owner(struct nfs4_state_owner *sp) { - struct rb_node *rb_node = &sp->so_server_node; - - if (!RB_EMPTY_NODE(rb_node)) { + if (!RB_EMPTY_NODE(&sp->so_server_node)) { struct nfs_server *server = sp->so_server; struct nfs_client *clp = server->nfs_client; spin_lock(&clp->cl_lock); - if (!RB_EMPTY_NODE(rb_node)) { - rb_erase(rb_node, &server->state_owners); - RB_CLEAR_NODE(rb_node); - } + rb_erase(&sp->so_server_node, &server->state_owners); + RB_CLEAR_NODE(&sp->so_server_node); spin_unlock(&clp->cl_lock); } } @@ -521,14 +516,6 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, /** * nfs4_put_state_owner - Release a nfs4_state_owner * @sp: state owner data to release - * - * Note that we keep released state owners on an LRU - * list. - * This caches valid state owners so that they can be - * reused, to avoid the OPEN_CONFIRM on minor version 0. - * It also pins the uniquifier of dropped state owners for - * a while, to ensure that those state owner names are - * never reused. */ void nfs4_put_state_owner(struct nfs4_state_owner *sp) { @@ -538,9 +525,15 @@ void nfs4_put_state_owner(struct nfs4_state_owner *sp) if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock)) return; - sp->so_expires = jiffies; - list_add_tail(&sp->so_lru, &server->state_owners_lru); - spin_unlock(&clp->cl_lock); + if (!RB_EMPTY_NODE(&sp->so_server_node)) { + sp->so_expires = jiffies; + list_add_tail(&sp->so_lru, &server->state_owners_lru); + spin_unlock(&clp->cl_lock); + } else { + nfs4_remove_state_owner_locked(sp); + spin_unlock(&clp->cl_lock); + nfs4_free_state_owner(sp); + } } /** diff --git a/trunk/fs/nfs/nfs4xdr.c b/trunk/fs/nfs/nfs4xdr.c index c54aae364bee..c74fdb114b48 100644 --- a/trunk/fs/nfs/nfs4xdr.c +++ b/trunk/fs/nfs/nfs4xdr.c @@ -74,7 +74,7 @@ static int nfs4_stat_to_errno(int); /* lock,open owner id: * we currently use size 2 (u64) out of (NFS4_OPAQUE_LIMIT >> 2) */ -#define open_owner_id_maxsz (1 + 2 + 1 + 1 + 2) +#define open_owner_id_maxsz (1 + 1 + 4) #define lock_owner_id_maxsz (1 + 1 + 4) #define decode_lockowner_maxsz (1 + XDR_QUADLEN(IDMAP_NAMESZ)) #define compound_encode_hdr_maxsz (3 + (NFS4_MAXTAGLEN >> 2)) @@ -1340,13 +1340,12 @@ static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_opena */ encode_nfs4_seqid(xdr, arg->seqid); encode_share_access(xdr, arg->fmode); - p = reserve_space(xdr, 36); + p = reserve_space(xdr, 32); p = xdr_encode_hyper(p, arg->clientid); - *p++ = cpu_to_be32(24); + *p++ = cpu_to_be32(20); p = xdr_encode_opaque_fixed(p, "open id:", 8); *p++ = cpu_to_be32(arg->server->s_dev); - *p++ = cpu_to_be32(arg->id.uniquifier); - xdr_encode_hyper(p, arg->id.create_time); + xdr_encode_hyper(p, arg->id); } static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_openargs *arg) @@ -4258,6 +4257,8 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, status = decode_attr_error(xdr, bitmap, &err); if (status < 0) goto xdr_error; + if (err == -NFS4ERR_WRONGSEC) + nfs_fixup_secinfo_attributes(fattr, fh); status = decode_attr_filehandle(xdr, bitmap, fh); if (status < 0) @@ -4900,19 +4901,11 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, bitmap[3] = {0}; struct kvec *iov = req->rq_rcv_buf.head; int status; - size_t page_len = xdr->buf->page_len; res->acl_len = 0; if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) goto out; - bm_p = xdr->p; - res->acl_data_offset = be32_to_cpup(bm_p) + 2; - res->acl_data_offset <<= 2; - /* Check if the acl data starts beyond the allocated buffer */ - if (res->acl_data_offset > page_len) - return -ERANGE; - if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) goto out; if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) @@ -4922,24 +4915,28 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { size_t hdrlen; + u32 recvd; /* The bitmap (xdr len + bitmaps) and the attr xdr len words * are stored with the acl data to handle the problem of * variable length bitmaps.*/ xdr->p = bm_p; + res->acl_data_offset = be32_to_cpup(bm_p) + 2; + res->acl_data_offset <<= 2; /* We ignore &savep and don't do consistency checks on * the attr length. Let userspace figure it out.... */ hdrlen = (u8 *)xdr->p - (u8 *)iov->iov_base; attrlen += res->acl_data_offset; - if (attrlen > page_len) { + recvd = req->rq_rcv_buf.len - hdrlen; + if (attrlen > recvd) { if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { /* getxattr interface called with a NULL buf */ res->acl_len = attrlen; goto out; } - dprintk("NFS: acl reply: attrlen %u > page_len %zu\n", - attrlen, page_len); + dprintk("NFS: acl reply: attrlen %u > recvd %u\n", + attrlen, recvd); return -EINVAL; } xdr_read_pages(xdr, attrlen); @@ -5092,13 +5089,16 @@ static int decode_secinfo_gss(struct xdr_stream *xdr, struct nfs4_secinfo_flavor return -EINVAL; } -static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) +static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) { struct nfs4_secinfo_flavor *sec_flavor; int status; __be32 *p; int i, num_flavors; + status = decode_op_hdr(xdr, OP_SECINFO); + if (status) + goto out; p = xdr_inline_decode(xdr, 4); if (unlikely(!p)) goto out_overflow; @@ -5124,7 +5124,6 @@ static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res res->flavors->num_flavors++; } - status = 0; out: return status; out_overflow: @@ -5132,23 +5131,7 @@ static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res return -EIO; } -static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) -{ - int status = decode_op_hdr(xdr, OP_SECINFO); - if (status) - return status; - return decode_secinfo_common(xdr, res); -} - #if defined(CONFIG_NFS_V4_1) -static int decode_secinfo_no_name(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) -{ - int status = decode_op_hdr(xdr, OP_SECINFO_NO_NAME); - if (status) - return status; - return decode_secinfo_common(xdr, res); -} - static int decode_exchange_id(struct xdr_stream *xdr, struct nfs41_exchange_id_res *res) { @@ -6833,7 +6816,7 @@ static int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp, status = decode_putrootfh(xdr); if (status) goto out; - status = decode_secinfo_no_name(xdr, res); + status = decode_secinfo(xdr, res); out: return status; } diff --git a/trunk/fs/nfs/objlayout/objlayout.c b/trunk/fs/nfs/objlayout/objlayout.c index 595c5fc21a19..8d45f1c318ce 100644 --- a/trunk/fs/nfs/objlayout/objlayout.c +++ b/trunk/fs/nfs/objlayout/objlayout.c @@ -604,6 +604,7 @@ int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay, { struct objlayout_deviceinfo *odi; struct pnfs_device pd; + struct super_block *sb; struct page *page, **pages; u32 *p; int err; @@ -622,6 +623,7 @@ int objlayout_get_deviceinfo(struct pnfs_layout_hdr *pnfslay, pd.pglen = PAGE_SIZE; pd.mincount = 0; + sb = pnfslay->plh_inode->i_sb; err = nfs4_proc_getdeviceinfo(NFS_SERVER(pnfslay->plh_inode), &pd); dprintk("%s nfs_getdeviceinfo returned %d\n", __func__, err); if (err) diff --git a/trunk/fs/nfs/pnfs.c b/trunk/fs/nfs/pnfs.c index 38512bcd2e98..b5d451586943 100644 --- a/trunk/fs/nfs/pnfs.c +++ b/trunk/fs/nfs/pnfs.c @@ -587,7 +587,7 @@ send_layoutget(struct pnfs_layout_hdr *lo, /* allocate pages for xdr post processing */ max_resp_sz = server->nfs_client->cl_session->fc_attrs.max_resp_sz; - max_pages = nfs_page_array_len(0, max_resp_sz); + max_pages = max_resp_sz >> PAGE_SHIFT; pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags); if (!pages) diff --git a/trunk/fs/nfs/read.c b/trunk/fs/nfs/read.c index 0a4be28c2ea3..9a0e8ef4a409 100644 --- a/trunk/fs/nfs/read.c +++ b/trunk/fs/nfs/read.c @@ -322,7 +322,7 @@ static int nfs_pagein_multi(struct nfs_pageio_descriptor *desc, struct list_head while (!list_empty(res)) { data = list_entry(res->next, struct nfs_read_data, list); list_del(&data->list); - nfs_readdata_release(data); + nfs_readdata_free(data); } nfs_readpage_release(req); return -ENOMEM; diff --git a/trunk/fs/nfs/super.c b/trunk/fs/nfs/super.c index 4ac7fca7e4bf..37412f706b32 100644 --- a/trunk/fs/nfs/super.c +++ b/trunk/fs/nfs/super.c @@ -2428,7 +2428,7 @@ nfs_xdev_mount(struct file_system_type *fs_type, int flags, dprintk("--> nfs_xdev_mount()\n"); /* create a new volume representation */ - server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); + server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr); if (IS_ERR(server)) { error = PTR_ERR(server); goto out_err_noserver; @@ -2767,15 +2767,11 @@ static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type, char *root_devname; size_t len; - len = strlen(hostname) + 5; + len = strlen(hostname) + 3; root_devname = kmalloc(len, GFP_KERNEL); if (root_devname == NULL) return ERR_PTR(-ENOMEM); - /* Does hostname needs to be enclosed in brackets? */ - if (strchr(hostname, ':')) - snprintf(root_devname, len, "[%s]:/", hostname); - else - snprintf(root_devname, len, "%s:/", hostname); + snprintf(root_devname, len, "%s:/", hostname); root_mnt = vfs_kern_mount(fs_type, flags, root_devname, data); kfree(root_devname); return root_mnt; @@ -2955,7 +2951,7 @@ nfs4_xdev_mount(struct file_system_type *fs_type, int flags, dprintk("--> nfs4_xdev_mount()\n"); /* create a new volume representation */ - server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); + server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr); if (IS_ERR(server)) { error = PTR_ERR(server); goto out_err_noserver; diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index c07462320f6b..2c68818f68ac 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -682,8 +682,7 @@ static struct nfs_page *nfs_try_to_update_request(struct inode *inode, req->wb_bytes = rqend - req->wb_offset; out_unlock: spin_unlock(&inode->i_lock); - if (req) - nfs_clear_request_commit(req); + nfs_clear_request_commit(req); return req; out_flushme: spin_unlock(&inode->i_lock); @@ -1019,7 +1018,7 @@ static int nfs_flush_multi(struct nfs_pageio_descriptor *desc, struct list_head while (!list_empty(res)) { data = list_entry(res->next, struct nfs_write_data, list); list_del(&data->list); - nfs_writedata_release(data); + nfs_writedata_free(data); } nfs_redirty_request(req); return -ENOMEM; diff --git a/trunk/fs/nfsd/nfs3xdr.c b/trunk/fs/nfsd/nfs3xdr.c index 43f46cd9edea..08c6e36ab2eb 100644 --- a/trunk/fs/nfsd/nfs3xdr.c +++ b/trunk/fs/nfsd/nfs3xdr.c @@ -803,13 +803,13 @@ encode_entry_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, return p; } -static __be32 +static int compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, const char *name, int namlen) { struct svc_export *exp; struct dentry *dparent, *dchild; - __be32 rv = nfserr_noent; + int rv = 0; dparent = cd->fh.fh_dentry; exp = cd->fh.fh_export; @@ -817,20 +817,26 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, if (isdotent(name, namlen)) { if (namlen == 2) { dchild = dget_parent(dparent); - /* filesystem root - cannot return filehandle for ".." */ - if (dchild == dparent) - goto out; + if (dchild == dparent) { + /* filesystem root - cannot return filehandle for ".." */ + dput(dchild); + return -ENOENT; + } } else dchild = dget(dparent); } else dchild = lookup_one_len(name, dparent, namlen); if (IS_ERR(dchild)) - return rv; + return -ENOENT; + rv = -ENOENT; if (d_mountpoint(dchild)) goto out; + rv = fh_compose(fhp, exp, dchild, &cd->fh); + if (rv) + goto out; if (!dchild->d_inode) goto out; - rv = fh_compose(fhp, exp, dchild, &cd->fh); + rv = 0; out: dput(dchild); return rv; @@ -839,7 +845,7 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, static __be32 *encode_entryplus_baggage(struct nfsd3_readdirres *cd, __be32 *p, const char *name, int namlen) { struct svc_fh fh; - __be32 err; + int err; fh_init(&fh, NFS3_FHSIZE); err = compose_entry_fh(cd, &fh, name, namlen); diff --git a/trunk/fs/nfsd/nfs4proc.c b/trunk/fs/nfsd/nfs4proc.c index 987e719fbae8..2ed14dfd00a2 100644 --- a/trunk/fs/nfsd/nfs4proc.c +++ b/trunk/fs/nfsd/nfs4proc.c @@ -235,15 +235,15 @@ do_open_lookup(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_o */ if (open->op_createmode == NFS4_CREATE_EXCLUSIVE && status == 0) open->op_bmval[1] = (FATTR4_WORD1_TIME_ACCESS | - FATTR4_WORD1_TIME_MODIFY); + FATTR4_WORD1_TIME_MODIFY); } else { status = nfsd_lookup(rqstp, current_fh, open->op_fname.data, open->op_fname.len, resfh); fh_unlock(current_fh); + if (status) + goto out; + status = nfsd_check_obj_isreg(resfh); } - if (status) - goto out; - status = nfsd_check_obj_isreg(resfh); if (status) goto out; @@ -841,7 +841,6 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_setattr *setattr) { __be32 status = nfs_ok; - int err; if (setattr->sa_iattr.ia_valid & ATTR_SIZE) { nfs4_lock_state(); @@ -853,9 +852,9 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return status; } } - err = fh_want_write(&cstate->current_fh); - if (err) - return nfserrno(err); + status = fh_want_write(&cstate->current_fh); + if (status) + return status; status = nfs_ok; status = check_attr_support(rqstp, cstate, setattr->sa_bmval, diff --git a/trunk/fs/nfsd/nfs4recover.c b/trunk/fs/nfsd/nfs4recover.c index ed3f9206a0ee..4767429264a2 100644 --- a/trunk/fs/nfsd/nfs4recover.c +++ b/trunk/fs/nfsd/nfs4recover.c @@ -577,7 +577,7 @@ cld_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) struct cld_net *cn = nn->cld_net; if (mlen != sizeof(*cmsg)) { - dprintk("%s: got %zu bytes, expected %zu\n", __func__, mlen, + dprintk("%s: got %lu bytes, expected %lu\n", __func__, mlen, sizeof(*cmsg)); return -EINVAL; } diff --git a/trunk/fs/nfsd/nfs4state.c b/trunk/fs/nfsd/nfs4state.c index 7f71c69cdcdf..1841f8bf845e 100644 --- a/trunk/fs/nfsd/nfs4state.c +++ b/trunk/fs/nfsd/nfs4state.c @@ -4211,14 +4211,16 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, * vfs_test_lock. (Arguably perhaps test_lock should be done with an * inode operation.) */ -static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock) +static int nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock) { struct file *file; - __be32 err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); - if (!err) { - err = nfserrno(vfs_test_lock(file, lock)); - nfsd_close(file); - } + int err; + + err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); + if (err) + return err; + err = vfs_test_lock(file, lock); + nfsd_close(file); return err; } @@ -4232,6 +4234,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct inode *inode; struct file_lock file_lock; struct nfs4_lockowner *lo; + int error; __be32 status; if (locks_in_grace()) @@ -4277,10 +4280,12 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, nfs4_transform_lock_offset(&file_lock); - status = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock); - if (status) + status = nfs_ok; + error = nfsd_test_lock(rqstp, &cstate->current_fh, &file_lock); + if (error) { + status = nfserrno(error); goto out; - + } if (file_lock.fl_type != F_UNLCK) { status = nfserr_denied; nfs4_set_lock_denied(&file_lock, &lockt->lt_denied); diff --git a/trunk/fs/nfsd/nfs4xdr.c b/trunk/fs/nfsd/nfs4xdr.c index 74c00bc92b9a..bcd8904ab1e3 100644 --- a/trunk/fs/nfsd/nfs4xdr.c +++ b/trunk/fs/nfsd/nfs4xdr.c @@ -1392,7 +1392,7 @@ nfsd4_decode_test_stateid(struct nfsd4_compoundargs *argp, struct nfsd4_test_sta for (i = 0; i < test_stateid->ts_num_ids; i++) { stateid = kmalloc(sizeof(struct nfsd4_test_stateid_id), GFP_KERNEL); if (!stateid) { - status = nfserrno(-ENOMEM); + status = PTR_ERR(stateid); goto out; } @@ -3410,7 +3410,7 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, int nfserr, *p++ = htonl(test_stateid->ts_num_ids); list_for_each_entry_safe(stateid, next, &test_stateid->ts_stateid_list, ts_id_list) { - *p++ = stateid->ts_id_status; + *p++ = htonl(stateid->ts_id_status); } ADJUST_ARGS(); diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index 568666156ea4..296d671654d6 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -1458,7 +1458,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, switch (createmode) { case NFS3_CREATE_UNCHECKED: if (! S_ISREG(dchild->d_inode->i_mode)) - goto out; + err = nfserr_exist; else if (truncp) { /* in nfsv4, we need to treat this case a little * differently. we don't want to truncate the diff --git a/trunk/fs/ocfs2/alloc.c b/trunk/fs/ocfs2/alloc.c index 31b9463fba1f..3165aebb43c8 100644 --- a/trunk/fs/ocfs2/alloc.c +++ b/trunk/fs/ocfs2/alloc.c @@ -1134,7 +1134,7 @@ static int ocfs2_adjust_rightmost_branch(handle_t *handle, } el = path_leaf_el(path); - rec = &el->l_recs[le16_to_cpu(el->l_next_free_rec) - 1]; + rec = &el->l_recs[le32_to_cpu(el->l_next_free_rec) - 1]; ocfs2_adjust_rightmost_records(handle, et, path, rec); diff --git a/trunk/fs/ocfs2/refcounttree.c b/trunk/fs/ocfs2/refcounttree.c index 9f32d7cbb7a3..cf7823382664 100644 --- a/trunk/fs/ocfs2/refcounttree.c +++ b/trunk/fs/ocfs2/refcounttree.c @@ -1036,14 +1036,14 @@ static int ocfs2_get_refcount_cpos_end(struct ocfs2_caching_info *ci, tmp_el = left_path->p_node[subtree_root].el; blkno = left_path->p_node[subtree_root+1].bh->b_blocknr; - for (i = 0; i < le16_to_cpu(tmp_el->l_next_free_rec); i++) { + for (i = 0; i < le32_to_cpu(tmp_el->l_next_free_rec); i++) { if (le64_to_cpu(tmp_el->l_recs[i].e_blkno) == blkno) { *cpos_end = le32_to_cpu(tmp_el->l_recs[i+1].e_cpos); break; } } - BUG_ON(i == le16_to_cpu(tmp_el->l_next_free_rec)); + BUG_ON(i == le32_to_cpu(tmp_el->l_next_free_rec)); out: ocfs2_free_path(left_path); @@ -1468,7 +1468,7 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh, trace_ocfs2_divide_leaf_refcount_block( (unsigned long long)ref_leaf_bh->b_blocknr, - le16_to_cpu(rl->rl_count), le16_to_cpu(rl->rl_used)); + le32_to_cpu(rl->rl_count), le32_to_cpu(rl->rl_used)); /* * XXX: Improvement later. @@ -2411,7 +2411,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, rb = (struct ocfs2_refcount_block *) prev_bh->b_data; - if (le16_to_cpu(rb->rf_records.rl_used) + + if (le64_to_cpu(rb->rf_records.rl_used) + recs_add > le16_to_cpu(rb->rf_records.rl_count)) ref_blocks++; @@ -2476,7 +2476,7 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb, if (prev_bh) { rb = (struct ocfs2_refcount_block *)prev_bh->b_data; - if (le16_to_cpu(rb->rf_records.rl_used) + recs_add > + if (le64_to_cpu(rb->rf_records.rl_used) + recs_add > le16_to_cpu(rb->rf_records.rl_count)) ref_blocks++; @@ -3629,7 +3629,7 @@ int ocfs2_refcounted_xattr_delete_need(struct inode *inode, * one will split a refcount rec, so totally we need * clusters * 2 new refcount rec. */ - if (le16_to_cpu(rb->rf_records.rl_used) + clusters * 2 > + if (le64_to_cpu(rb->rf_records.rl_used) + clusters * 2 > le16_to_cpu(rb->rf_records.rl_count)) ref_blocks++; diff --git a/trunk/fs/ocfs2/suballoc.c b/trunk/fs/ocfs2/suballoc.c index f169da4624fd..ba5d97e4a73e 100644 --- a/trunk/fs/ocfs2/suballoc.c +++ b/trunk/fs/ocfs2/suballoc.c @@ -600,7 +600,7 @@ static void ocfs2_bg_alloc_cleanup(handle_t *handle, ret = ocfs2_free_clusters(handle, cluster_ac->ac_inode, cluster_ac->ac_bh, le64_to_cpu(rec->e_blkno), - le16_to_cpu(rec->e_leaf_clusters)); + le32_to_cpu(rec->e_leaf_clusters)); if (ret) mlog_errno(ret); /* Try all the clusters to free */ @@ -1628,7 +1628,7 @@ static int ocfs2_bg_discontig_fix_by_rec(struct ocfs2_suballoc_result *res, { unsigned int bpc = le16_to_cpu(cl->cl_bpc); unsigned int bitoff = le32_to_cpu(rec->e_cpos) * bpc; - unsigned int bitcount = le16_to_cpu(rec->e_leaf_clusters) * bpc; + unsigned int bitcount = le32_to_cpu(rec->e_leaf_clusters) * bpc; if (res->sr_bit_offset < bitoff) return 0; diff --git a/trunk/fs/pipe.c b/trunk/fs/pipe.c index fec5e4ad071a..25feaa3faac0 100644 --- a/trunk/fs/pipe.c +++ b/trunk/fs/pipe.c @@ -346,16 +346,6 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = { .get = generic_pipe_buf_get, }; -static const struct pipe_buf_operations packet_pipe_buf_ops = { - .can_merge = 0, - .map = generic_pipe_buf_map, - .unmap = generic_pipe_buf_unmap, - .confirm = generic_pipe_buf_confirm, - .release = anon_pipe_buf_release, - .steal = generic_pipe_buf_steal, - .get = generic_pipe_buf_get, -}; - static ssize_t pipe_read(struct kiocb *iocb, const struct iovec *_iov, unsigned long nr_segs, loff_t pos) @@ -417,13 +407,6 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, ret += chars; buf->offset += chars; buf->len -= chars; - - /* Was it a packet buffer? Clean up and exit */ - if (buf->flags & PIPE_BUF_FLAG_PACKET) { - total_len = chars; - buf->len = 0; - } - if (!buf->len) { buf->ops = NULL; ops->release(pipe, buf); @@ -476,11 +459,6 @@ pipe_read(struct kiocb *iocb, const struct iovec *_iov, return ret; } -static inline int is_packetized(struct file *file) -{ - return (file->f_flags & O_DIRECT) != 0; -} - static ssize_t pipe_write(struct kiocb *iocb, const struct iovec *_iov, unsigned long nr_segs, loff_t ppos) @@ -615,11 +593,6 @@ pipe_write(struct kiocb *iocb, const struct iovec *_iov, buf->ops = &anon_pipe_buf_ops; buf->offset = 0; buf->len = chars; - buf->flags = 0; - if (is_packetized(filp)) { - buf->ops = &packet_pipe_buf_ops; - buf->flags = PIPE_BUF_FLAG_PACKET; - } pipe->nrbufs = ++bufs; pipe->tmp_page = NULL; @@ -1040,7 +1013,7 @@ struct file *create_write_pipe(int flags) goto err_dentry; f->f_mapping = inode->i_mapping; - f->f_flags = O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)); + f->f_flags = O_WRONLY | (flags & O_NONBLOCK); f->f_version = 0; return f; @@ -1084,7 +1057,7 @@ int do_pipe_flags(int *fd, int flags) int error; int fdw, fdr; - if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT)) + if (flags & ~(O_CLOEXEC | O_NONBLOCK)) return -EINVAL; fw = create_write_pipe(flags); diff --git a/trunk/fs/proc/task_mmu.c b/trunk/fs/proc/task_mmu.c index 2d60492d6df8..2b9a7607cbd5 100644 --- a/trunk/fs/proc/task_mmu.c +++ b/trunk/fs/proc/task_mmu.c @@ -597,6 +597,9 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr, if (!page) continue; + if (PageReserved(page)) + continue; + /* Clear accessed and referenced bits. */ ptep_test_and_clear_young(vma, addr, pte); ClearPageReferenced(page); diff --git a/trunk/include/acpi/actypes.h b/trunk/include/acpi/actypes.h index e8bcc4742e0e..eba66043cf1b 100644 --- a/trunk/include/acpi/actypes.h +++ b/trunk/include/acpi/actypes.h @@ -499,10 +499,9 @@ typedef u64 acpi_integer; #define ACPI_STATE_D0 (u8) 0 #define ACPI_STATE_D1 (u8) 1 #define ACPI_STATE_D2 (u8) 2 -#define ACPI_STATE_D3_HOT (u8) 3 -#define ACPI_STATE_D3 (u8) 4 -#define ACPI_STATE_D3_COLD ACPI_STATE_D3 -#define ACPI_D_STATES_MAX ACPI_STATE_D3 +#define ACPI_STATE_D3 (u8) 3 +#define ACPI_STATE_D3_COLD (u8) 4 +#define ACPI_D_STATES_MAX ACPI_STATE_D3_COLD #define ACPI_D_STATE_COUNT 5 #define ACPI_STATE_C0 (u8) 0 diff --git a/trunk/include/asm-generic/siginfo.h b/trunk/include/asm-generic/siginfo.h index 5e5e3865f1ed..0dd4e87f6fba 100644 --- a/trunk/include/asm-generic/siginfo.h +++ b/trunk/include/asm-generic/siginfo.h @@ -35,14 +35,6 @@ typedef union sigval { #define __ARCH_SI_BAND_T long #endif -#ifndef __ARCH_SI_CLOCK_T -#define __ARCH_SI_CLOCK_T __kernel_clock_t -#endif - -#ifndef __ARCH_SI_ATTRIBUTES -#define __ARCH_SI_ATTRIBUTES -#endif - #ifndef HAVE_ARCH_SIGINFO_T typedef struct siginfo { @@ -80,8 +72,8 @@ typedef struct siginfo { __kernel_pid_t _pid; /* which child */ __ARCH_SI_UID_T _uid; /* sender's uid */ int _status; /* exit code */ - __ARCH_SI_CLOCK_T _utime; - __ARCH_SI_CLOCK_T _stime; + __kernel_clock_t _utime; + __kernel_clock_t _stime; } _sigchld; /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ @@ -99,7 +91,7 @@ typedef struct siginfo { int _fd; } _sigpoll; } _sifields; -} __ARCH_SI_ATTRIBUTES siginfo_t; +} siginfo_t; #endif diff --git a/trunk/include/asm-generic/statfs.h b/trunk/include/asm-generic/statfs.h index c749af9c0983..0fd28e028de1 100644 --- a/trunk/include/asm-generic/statfs.h +++ b/trunk/include/asm-generic/statfs.h @@ -15,7 +15,7 @@ typedef __kernel_fsid_t fsid_t; * with a 10' pole. */ #ifndef __statfs_word -#if __BITS_PER_LONG == 64 +#if BITS_PER_LONG == 64 #define __statfs_word long #else #define __statfs_word __u32 diff --git a/trunk/include/drm/drmP.h b/trunk/include/drm/drmP.h index efd124903761..10a5f371e658 100644 --- a/trunk/include/drm/drmP.h +++ b/trunk/include/drm/drmP.h @@ -1309,8 +1309,8 @@ extern int drm_release(struct inode *inode, struct file *filp); /* Mapping support (drm_vm.h) */ extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma); -extern void drm_vm_open_locked(struct drm_device *dev, struct vm_area_struct *vma); -extern void drm_vm_close_locked(struct drm_device *dev, struct vm_area_struct *vma); +extern void drm_vm_open_locked(struct vm_area_struct *vma); +extern void drm_vm_close_locked(struct vm_area_struct *vma); extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); /* Memory management support (drm_memory.h) */ diff --git a/trunk/include/drm/radeon_drm.h b/trunk/include/drm/radeon_drm.h index 58056865b8e9..7c491b4bcf65 100644 --- a/trunk/include/drm/radeon_drm.h +++ b/trunk/include/drm/radeon_drm.h @@ -926,6 +926,7 @@ struct drm_radeon_cs_chunk { }; /* drm_radeon_cs_reloc.flags */ +#define RADEON_RELOC_DONT_SYNC 0x01 struct drm_radeon_cs_reloc { uint32_t handle; diff --git a/trunk/include/linux/efi.h b/trunk/include/linux/efi.h index ec45ccd8708a..88ec80670d5f 100644 --- a/trunk/include/linux/efi.h +++ b/trunk/include/linux/efi.h @@ -554,18 +554,7 @@ extern int __init efi_setup_pcdp_console(char *); #define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 #define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 #define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 -#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x0000000000000008 -#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x0000000000000010 -#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x0000000000000020 -#define EFI_VARIABLE_APPEND_WRITE 0x0000000000000040 - -#define EFI_VARIABLE_MASK (EFI_VARIABLE_NON_VOLATILE | \ - EFI_VARIABLE_BOOTSERVICE_ACCESS | \ - EFI_VARIABLE_RUNTIME_ACCESS | \ - EFI_VARIABLE_HARDWARE_ERROR_RECORD | \ - EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | \ - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS | \ - EFI_VARIABLE_APPEND_WRITE) + /* * The type of search to perform when calling boottime->locate_handle */ diff --git a/trunk/include/linux/fuse.h b/trunk/include/linux/fuse.h index 8f2ab8fef929..8ba2c9460b28 100644 --- a/trunk/include/linux/fuse.h +++ b/trunk/include/linux/fuse.h @@ -593,7 +593,7 @@ struct fuse_dirent { __u64 off; __u32 namelen; __u32 type; - char name[]; + char name[0]; }; #define FUSE_NAME_OFFSET offsetof(struct fuse_dirent, name) diff --git a/trunk/include/linux/gpio-pxa.h b/trunk/include/linux/gpio-pxa.h index d755b28ba635..05071ee34c3f 100644 --- a/trunk/include/linux/gpio-pxa.h +++ b/trunk/include/linux/gpio-pxa.h @@ -13,8 +13,4 @@ extern int pxa_last_gpio; extern int pxa_irq_to_gpio(int irq); -struct pxa_gpio_platform_data { - int (*gpio_set_wake)(unsigned int gpio, unsigned int on); -}; - #endif /* __GPIO_PXA_H */ diff --git a/trunk/include/linux/hsi/hsi.h b/trunk/include/linux/hsi/hsi.h index 56fae865e272..4b178067f405 100644 --- a/trunk/include/linux/hsi/hsi.h +++ b/trunk/include/linux/hsi/hsi.h @@ -26,9 +26,9 @@ #include #include #include +#include #include #include -#include /* HSI message ttype */ #define HSI_MSG_READ 0 @@ -121,18 +121,18 @@ static inline int hsi_register_board_info(struct hsi_board_info const *info, * @device: Driver model representation of the device * @tx_cfg: HSI TX configuration * @rx_cfg: HSI RX configuration - * @e_handler: Callback for handling port events (RX Wake High/Low) - * @pclaimed: Keeps tracks if the clients claimed its associated HSI port - * @nb: Notifier block for port events + * @hsi_start_rx: Called after incoming wake line goes high + * @hsi_stop_rx: Called after incoming wake line goes low */ struct hsi_client { struct device device; struct hsi_config tx_cfg; struct hsi_config rx_cfg; + void (*hsi_start_rx)(struct hsi_client *cl); + void (*hsi_stop_rx)(struct hsi_client *cl); /* private: */ - void (*ehandler)(struct hsi_client *, unsigned long); unsigned int pclaimed:1; - struct notifier_block nb; + struct list_head link; }; #define to_hsi_client(dev) container_of(dev, struct hsi_client, device) @@ -147,10 +147,6 @@ static inline void *hsi_client_drvdata(struct hsi_client *cl) return dev_get_drvdata(&cl->device); } -int hsi_register_port_event(struct hsi_client *cl, - void (*handler)(struct hsi_client *, unsigned long)); -int hsi_unregister_port_event(struct hsi_client *cl); - /** * struct hsi_client_driver - Driver associated to an HSI client * @driver: Driver model representation of the driver @@ -218,7 +214,8 @@ void hsi_free_msg(struct hsi_msg *msg); * @start_tx: Callback to inform that a client wants to TX data * @stop_tx: Callback to inform that a client no longer wishes to TX data * @release: Callback to inform that a client no longer uses the port - * @n_head: Notifier chain for signaling port events to the clients. + * @clients: List of hsi_clients using the port. + * @clock: Lock to serialize access to the clients list. */ struct hsi_port { struct device device; @@ -234,14 +231,14 @@ struct hsi_port { int (*start_tx)(struct hsi_client *cl); int (*stop_tx)(struct hsi_client *cl); int (*release)(struct hsi_client *cl); - /* private */ - struct atomic_notifier_head n_head; + struct list_head clients; + spinlock_t clock; }; #define to_hsi_port(dev) container_of(dev, struct hsi_port, device) #define hsi_get_port(cl) to_hsi_port((cl)->device.parent) -int hsi_event(struct hsi_port *port, unsigned long event); +void hsi_event(struct hsi_port *port, unsigned int event); int hsi_claim_port(struct hsi_client *cl, unsigned int share); void hsi_release_port(struct hsi_client *cl); @@ -273,13 +270,13 @@ struct hsi_controller { struct module *owner; unsigned int id; unsigned int num_ports; - struct hsi_port **port; + struct hsi_port *port; }; #define to_hsi_controller(dev) container_of(dev, struct hsi_controller, device) struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags); -void hsi_put_controller(struct hsi_controller *hsi); +void hsi_free_controller(struct hsi_controller *hsi); int hsi_register_controller(struct hsi_controller *hsi); void hsi_unregister_controller(struct hsi_controller *hsi); @@ -297,7 +294,7 @@ static inline void *hsi_controller_drvdata(struct hsi_controller *hsi) static inline struct hsi_port *hsi_find_port_num(struct hsi_controller *hsi, unsigned int num) { - return (num < hsi->num_ports) ? hsi->port[num] : NULL; + return (num < hsi->num_ports) ? &hsi->port[num] : NULL; } /* diff --git a/trunk/include/linux/i2c/twl.h b/trunk/include/linux/i2c/twl.h index 1f90de0cfdbe..2463b6100333 100644 --- a/trunk/include/linux/i2c/twl.h +++ b/trunk/include/linux/i2c/twl.h @@ -666,11 +666,23 @@ struct twl4030_codec_data { unsigned int check_defaults:1; unsigned int reset_registers:1; unsigned int hs_extmute:1; + u16 hs_left_step; + u16 hs_right_step; + u16 hf_left_step; + u16 hf_right_step; void (*set_hs_extmute)(int mute); }; struct twl4030_vibra_data { unsigned int coexist; + + /* twl6040 */ + unsigned int vibldrv_res; /* left driver resistance */ + unsigned int vibrdrv_res; /* right driver resistance */ + unsigned int viblmotor_res; /* left motor resistance */ + unsigned int vibrmotor_res; /* right motor resistance */ + int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */ + int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */ }; struct twl4030_audio_data { diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index b27cfcfd3a59..7810406f3d80 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -49,12 +49,6 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data); * IRQ_TYPE_LEVEL_LOW - low level triggered * IRQ_TYPE_LEVEL_MASK - Mask to filter out the level bits * IRQ_TYPE_SENSE_MASK - Mask for all the above bits - * IRQ_TYPE_DEFAULT - For use by some PICs to ask irq_set_type - * to setup the HW to a sane default (used - * by irqdomain map() callbacks to synchronize - * the HW state and SW flags for a newly - * allocated descriptor). - * * IRQ_TYPE_PROBE - Special flag for probing in progress * * Bits which can be modified via irq_set/clear/modify_status_flags() @@ -83,7 +77,6 @@ enum { IRQ_TYPE_LEVEL_LOW = 0x00000008, IRQ_TYPE_LEVEL_MASK = (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH), IRQ_TYPE_SENSE_MASK = 0x0000000f, - IRQ_TYPE_DEFAULT = IRQ_TYPE_SENSE_MASK, IRQ_TYPE_PROBE = 0x00000010, diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index 72cbf08d45fb..665a260c7e09 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -596,7 +596,6 @@ void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); #ifdef CONFIG_IOMMU_API int kvm_iommu_map_pages(struct kvm *kvm, struct kvm_memory_slot *slot); -void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot); int kvm_iommu_map_guest(struct kvm *kvm); int kvm_iommu_unmap_guest(struct kvm *kvm); int kvm_assign_device(struct kvm *kvm, @@ -610,11 +609,6 @@ static inline int kvm_iommu_map_pages(struct kvm *kvm, return 0; } -static inline void kvm_iommu_unmap_pages(struct kvm *kvm, - struct kvm_memory_slot *slot) -{ -} - static inline int kvm_iommu_map_guest(struct kvm *kvm) { return -ENODEV; diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index e926df7b54c9..42378d637ffb 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -996,8 +996,7 @@ extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev, extern void ata_sas_port_destroy(struct ata_port *); extern struct ata_port *ata_sas_port_alloc(struct ata_host *, struct ata_port_info *, struct Scsi_Host *); -extern void ata_sas_async_probe(struct ata_port *ap); -extern int ata_sas_sync_probe(struct ata_port *ap); +extern int ata_sas_async_port_init(struct ata_port *); extern int ata_sas_port_init(struct ata_port *); extern int ata_sas_port_start(struct ata_port *ap); extern void ata_sas_port_stop(struct ata_port *ap); diff --git a/trunk/include/linux/mfd/db5500-prcmu.h b/trunk/include/linux/mfd/db5500-prcmu.h index 5a049dfaf153..9890687f582d 100644 --- a/trunk/include/linux/mfd/db5500-prcmu.h +++ b/trunk/include/linux/mfd/db5500-prcmu.h @@ -8,14 +8,41 @@ #ifndef __MFD_DB5500_PRCMU_H #define __MFD_DB5500_PRCMU_H -static inline int prcmu_resetout(u8 resoutn, u8 state) +#ifdef CONFIG_MFD_DB5500_PRCMU + +void db5500_prcmu_early_init(void); +int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state); +int db5500_prcmu_set_display_clocks(void); +int db5500_prcmu_disable_dsipll(void); +int db5500_prcmu_enable_dsipll(void); +int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); +int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); +void db5500_prcmu_enable_wakeups(u32 wakeups); +int db5500_prcmu_request_clock(u8 clock, bool enable); +void db5500_prcmu_config_abb_event_readout(u32 abb_events); +void db5500_prcmu_get_abb_event_buffer(void __iomem **buf); +int prcmu_resetout(u8 resoutn, u8 state); +int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, + bool keep_ap_pll); +int db5500_prcmu_config_esram0_deep_sleep(u8 state); +void db5500_prcmu_system_reset(u16 reset_code); +u16 db5500_prcmu_get_reset_code(void); +bool db5500_prcmu_is_ac_wake_requested(void); +int db5500_prcmu_set_arm_opp(u8 opp); +int db5500_prcmu_get_arm_opp(void); + +#else /* !CONFIG_UX500_SOC_DB5500 */ + +static inline void db5500_prcmu_early_init(void) {} + +static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) { - return 0; + return -ENOSYS; } -static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state) +static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) { - return 0; + return -ENOSYS; } static inline int db5500_prcmu_request_clock(u8 clock, bool enable) @@ -23,83 +50,70 @@ static inline int db5500_prcmu_request_clock(u8 clock, bool enable) return 0; } -static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, - bool keep_ap_pll) +static inline int db5500_prcmu_set_display_clocks(void) { return 0; } -static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state) +static inline int db5500_prcmu_disable_dsipll(void) { return 0; } -static inline u16 db5500_prcmu_get_reset_code(void) +static inline int db5500_prcmu_enable_dsipll(void) { return 0; } -static inline bool db5500_prcmu_is_ac_wake_requested(void) +static inline int db5500_prcmu_config_esram0_deep_sleep(u8 state) { return 0; } -static inline int db5500_prcmu_set_arm_opp(u8 opp) +static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {} + +static inline int prcmu_resetout(u8 resoutn, u8 state) { return 0; } -static inline int db5500_prcmu_get_arm_opp(void) +static inline int db5500_prcmu_set_epod(u16 epod_id, u8 epod_state) { return 0; } -static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {} - static inline void db5500_prcmu_get_abb_event_buffer(void __iomem **buf) {} +static inline void db5500_prcmu_config_abb_event_readout(u32 abb_events) {} -static inline void db5500_prcmu_system_reset(u16 reset_code) {} - -static inline void db5500_prcmu_enable_wakeups(u32 wakeups) {} - -#ifdef CONFIG_MFD_DB5500_PRCMU - -void db5500_prcmu_early_init(void); -int db5500_prcmu_set_display_clocks(void); -int db5500_prcmu_disable_dsipll(void); -int db5500_prcmu_enable_dsipll(void); -int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size); -int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size); - -#else /* !CONFIG_UX500_SOC_DB5500 */ - -static inline void db5500_prcmu_early_init(void) {} - -static inline int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size) +static inline int db5500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, + bool keep_ap_pll) { - return -ENOSYS; + return 0; } -static inline int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size) +static inline void db5500_prcmu_system_reset(u16 reset_code) {} + +static inline u16 db5500_prcmu_get_reset_code(void) { - return -ENOSYS; + return 0; } -static inline int db5500_prcmu_set_display_clocks(void) +static inline bool db5500_prcmu_is_ac_wake_requested(void) { return 0; } -static inline int db5500_prcmu_disable_dsipll(void) +static inline int db5500_prcmu_set_arm_opp(u8 opp) { return 0; } -static inline int db5500_prcmu_enable_dsipll(void) +static inline int db5500_prcmu_get_arm_opp(void) { return 0; } + #endif /* CONFIG_MFD_DB5500_PRCMU */ #endif /* __MFD_DB5500_PRCMU_H */ diff --git a/trunk/include/linux/mfd/rc5t583.h b/trunk/include/linux/mfd/rc5t583.h index 0b64b19d81ab..a2c61609d21d 100644 --- a/trunk/include/linux/mfd/rc5t583.h +++ b/trunk/include/linux/mfd/rc5t583.h @@ -26,7 +26,6 @@ #include #include -#include #define RC5T583_MAX_REGS 0xF8 @@ -280,44 +279,14 @@ struct rc5t583_platform_data { bool enable_shutdown; }; -static inline int rc5t583_write(struct device *dev, uint8_t reg, uint8_t val) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_write(rc5t583->regmap, reg, val); -} - -static inline int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - unsigned int ival; - int ret; - ret = regmap_read(rc5t583->regmap, reg, &ival); - if (!ret) - *val = (uint8_t)ival; - return ret; -} - -static inline int rc5t583_set_bits(struct device *dev, unsigned int reg, - unsigned int bit_mask) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_update_bits(rc5t583->regmap, reg, bit_mask, bit_mask); -} - -static inline int rc5t583_clear_bits(struct device *dev, unsigned int reg, - unsigned int bit_mask) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_update_bits(rc5t583->regmap, reg, bit_mask, 0); -} - -static inline int rc5t583_update(struct device *dev, unsigned int reg, - unsigned int val, unsigned int mask) -{ - struct rc5t583 *rc5t583 = dev_get_drvdata(dev); - return regmap_update_bits(rc5t583->regmap, reg, mask, val); -} - +int rc5t583_write(struct device *dev, u8 reg, uint8_t val); +int rc5t583_read(struct device *dev, uint8_t reg, uint8_t *val); +int rc5t583_set_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask); +int rc5t583_clear_bits(struct device *dev, unsigned int reg, + unsigned int bit_mask); +int rc5t583_update(struct device *dev, unsigned int reg, + unsigned int val, unsigned int mask); int rc5t583_ext_power_req_config(struct device *dev, int deepsleep_id, int ext_pwr_req, int deepsleep_slot_nr); int rc5t583_irq_init(struct rc5t583 *rc5t583, int irq, int irq_base); diff --git a/trunk/include/linux/mfd/twl6040.h b/trunk/include/linux/mfd/twl6040.h index b15b5f03f5c4..9bc9ac651dad 100644 --- a/trunk/include/linux/mfd/twl6040.h +++ b/trunk/include/linux/mfd/twl6040.h @@ -174,35 +174,8 @@ #define TWL6040_SYSCLK_SEL_LPPLL 0 #define TWL6040_SYSCLK_SEL_HPPLL 1 -struct twl6040_codec_data { - u16 hs_left_step; - u16 hs_right_step; - u16 hf_left_step; - u16 hf_right_step; -}; - -struct twl6040_vibra_data { - unsigned int vibldrv_res; /* left driver resistance */ - unsigned int vibrdrv_res; /* right driver resistance */ - unsigned int viblmotor_res; /* left motor resistance */ - unsigned int vibrmotor_res; /* right motor resistance */ - int vddvibl_uV; /* VDDVIBL volt, set 0 for fixed reg */ - int vddvibr_uV; /* VDDVIBR volt, set 0 for fixed reg */ -}; - -struct twl6040_platform_data { - int audpwron_gpio; /* audio power-on gpio */ - unsigned int irq_base; - - struct twl6040_codec_data *codec; - struct twl6040_vibra_data *vibra; -}; - -struct regmap; - struct twl6040 { struct device *dev; - struct regmap *regmap; struct mutex mutex; struct mutex io_mutex; struct mutex irq_mutex; diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 74aa71bea1e4..d8738a464b94 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -1393,20 +1393,29 @@ extern int install_special_mapping(struct mm_struct *mm, extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); +extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long pgoff); extern unsigned long mmap_region(struct file *file, unsigned long addr, unsigned long len, unsigned long flags, vm_flags_t vm_flags, unsigned long pgoff); -extern unsigned long do_mmap(struct file *, unsigned long, - unsigned long, unsigned long, - unsigned long, unsigned long); + +static inline unsigned long do_mmap(struct file *file, unsigned long addr, + unsigned long len, unsigned long prot, + unsigned long flag, unsigned long offset) +{ + unsigned long ret = -EINVAL; + if ((offset + PAGE_ALIGN(len)) < offset) + goto out; + if (!(offset & ~PAGE_MASK)) + ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); +out: + return ret; +} + extern int do_munmap(struct mm_struct *, unsigned long, size_t); -/* These take the mm semaphore themselves */ -extern unsigned long vm_brk(unsigned long, unsigned long); -extern int vm_munmap(unsigned long, size_t); -extern unsigned long vm_mmap(struct file *, unsigned long, - unsigned long, unsigned long, - unsigned long, unsigned long); +extern unsigned long do_brk(unsigned long, unsigned long); /* truncate.c */ extern void truncate_inode_pages(struct address_space *, loff_t); diff --git a/trunk/include/linux/mmc/card.h b/trunk/include/linux/mmc/card.h index 629b823f8836..01beae78f079 100644 --- a/trunk/include/linux/mmc/card.h +++ b/trunk/include/linux/mmc/card.h @@ -481,7 +481,7 @@ struct mmc_driver { struct device_driver drv; int (*probe)(struct mmc_card *); void (*remove)(struct mmc_card *); - int (*suspend)(struct mmc_card *); + int (*suspend)(struct mmc_card *, pm_message_t); int (*resume)(struct mmc_card *); }; diff --git a/trunk/include/linux/netfilter_bridge.h b/trunk/include/linux/netfilter_bridge.h index 31d2844e6572..0ddd161f3b06 100644 --- a/trunk/include/linux/netfilter_bridge.h +++ b/trunk/include/linux/netfilter_bridge.h @@ -104,18 +104,9 @@ struct bridge_skb_cb { } daddr; }; -static inline void br_drop_fake_rtable(struct sk_buff *skb) -{ - struct dst_entry *dst = skb_dst(skb); - - if (dst && (dst->flags & DST_FAKE_RTABLE)) - skb_dst_drop(skb); -} - #else #define nf_bridge_maybe_copy_header(skb) (0) #define nf_bridge_pad(skb) (0) -#define br_drop_fake_rtable(skb) do { } while (0) #endif /* CONFIG_BRIDGE_NETFILTER */ #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/nfs_xdr.h b/trunk/include/linux/nfs_xdr.h index 7ba3551a0414..bfd0d1bf6707 100644 --- a/trunk/include/linux/nfs_xdr.h +++ b/trunk/include/linux/nfs_xdr.h @@ -312,11 +312,6 @@ struct nfs4_layoutreturn { int rpc_status; }; -struct stateowner_id { - __u64 create_time; - __u32 uniquifier; -}; - /* * Arguments to the open call. */ @@ -326,7 +321,7 @@ struct nfs_openargs { int open_flags; fmode_t fmode; __u64 clientid; - struct stateowner_id id; + __u64 id; union { struct { struct iattr * attrs; /* UNCHECKED, GUARDED */ diff --git a/trunk/include/linux/nfsd/Kbuild b/trunk/include/linux/nfsd/Kbuild index 5b7d84ac954a..b8d4001212b3 100644 --- a/trunk/include/linux/nfsd/Kbuild +++ b/trunk/include/linux/nfsd/Kbuild @@ -1,4 +1,3 @@ -header-y += cld.h header-y += debug.h header-y += export.h header-y += nfsfh.h diff --git a/trunk/include/linux/pinctrl/machine.h b/trunk/include/linux/pinctrl/machine.h index e4d1de742502..fee4349364f7 100644 --- a/trunk/include/linux/pinctrl/machine.h +++ b/trunk/include/linux/pinctrl/machine.h @@ -12,8 +12,6 @@ #ifndef __LINUX_PINCTRL_MACHINE_H #define __LINUX_PINCTRL_MACHINE_H -#include - #include "pinctrl-state.h" enum pinctrl_map_type { @@ -150,7 +148,7 @@ struct pinctrl_map { #define PIN_MAP_CONFIGS_GROUP_HOG_DEFAULT(dev, grp, cfgs) \ PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, cfgs) -#ifdef CONFIG_PINCTRL +#ifdef CONFIG_PINMUX extern int pinctrl_register_mappings(struct pinctrl_map const *map, unsigned num_maps); diff --git a/trunk/include/linux/pipe_fs_i.h b/trunk/include/linux/pipe_fs_i.h index e1ac1ce16fb0..6d626ff0cfd0 100644 --- a/trunk/include/linux/pipe_fs_i.h +++ b/trunk/include/linux/pipe_fs_i.h @@ -6,7 +6,6 @@ #define PIPE_BUF_FLAG_LRU 0x01 /* page is on the LRU */ #define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */ #define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */ -#define PIPE_BUF_FLAG_PACKET 0x08 /* read() as a packet */ /** * struct pipe_buffer - a linux kernel pipe buffer diff --git a/trunk/include/linux/seqlock.h b/trunk/include/linux/seqlock.h index 600060e25ec6..c6db9fb33c44 100644 --- a/trunk/include/linux/seqlock.h +++ b/trunk/include/linux/seqlock.h @@ -141,7 +141,7 @@ static inline unsigned __read_seqcount_begin(const seqcount_t *s) unsigned ret; repeat: - ret = ACCESS_ONCE(s->sequence); + ret = s->sequence; if (unlikely(ret & 1)) { cpu_relax(); goto repeat; @@ -165,27 +165,6 @@ static inline unsigned read_seqcount_begin(const seqcount_t *s) return ret; } -/** - * raw_seqcount_begin - begin a seq-read critical section - * @s: pointer to seqcount_t - * Returns: count to be passed to read_seqcount_retry - * - * raw_seqcount_begin opens a read critical section of the given seqcount. - * Validity of the critical section is tested by checking read_seqcount_retry - * function. - * - * Unlike read_seqcount_begin(), this function will not wait for the count - * to stabilize. If a writer is active when we begin, we will fail the - * read_seqcount_retry() instead of stabilizing at the beginning of the - * critical section. - */ -static inline unsigned raw_seqcount_begin(const seqcount_t *s) -{ - unsigned ret = ACCESS_ONCE(s->sequence); - smp_rmb(); - return ret & ~1; -} - /** * __read_seqcount_retry - end a seq-read critical section (without barrier) * @s: pointer to seqcount_t diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index 111f26b6e28b..70a3f8d49118 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -238,12 +238,11 @@ enum { /* * The callback notifies userspace to release buffers when skb DMA is done in * lower device, the skb last reference should be 0 when calling this. - * The ctx field is used to track device context. - * The desc field is used to track userspace buffer index. + * The desc is used to track userspace buffer index. */ struct ubuf_info { - void (*callback)(struct ubuf_info *); - void *ctx; + void (*callback)(void *); + void *arg; unsigned long desc; }; @@ -1020,7 +1019,7 @@ static inline void skb_queue_splice(const struct sk_buff_head *list, } /** - * skb_queue_splice_init - join two skb lists and reinitialise the emptied list + * skb_queue_splice - join two skb lists and reinitialise the emptied list * @list: the new list to add * @head: the place to add it in the first list * @@ -1051,7 +1050,7 @@ static inline void skb_queue_splice_tail(const struct sk_buff_head *list, } /** - * skb_queue_splice_tail_init - join two skb lists and reinitialise the emptied list + * skb_queue_splice_tail - join two skb lists and reinitialise the emptied list * @list: the new list to add * @head: the place to add it in the first list * diff --git a/trunk/include/linux/spi/spi.h b/trunk/include/linux/spi/spi.h index fa702aeb5038..98679b061b63 100644 --- a/trunk/include/linux/spi/spi.h +++ b/trunk/include/linux/spi/spi.h @@ -254,7 +254,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) * driver is finished with this message, it must call * spi_finalize_current_message() so the subsystem can issue the next * transfer - * @unprepare_transfer_hardware: there are currently no more messages on the + * @prepare_transfer_hardware: there are currently no more messages on the * queue so the subsystem notifies the driver that it may relax the * hardware by issuing this call * diff --git a/trunk/include/linux/usb/hcd.h b/trunk/include/linux/usb/hcd.h index d28cc78a38e4..5de415707c23 100644 --- a/trunk/include/linux/usb/hcd.h +++ b/trunk/include/linux/usb/hcd.h @@ -126,8 +126,6 @@ struct usb_hcd { unsigned wireless:1; /* Wireless USB HCD */ unsigned authorized_default:1; unsigned has_tt:1; /* Integrated TT in root hub */ - unsigned broken_pci_sleep:1; /* Don't put the - controller in PCI-D3 for system sleep */ unsigned int irq; /* irq allocated */ void __iomem *regs; /* device memory/io */ diff --git a/trunk/include/linux/usb/otg.h b/trunk/include/linux/usb/otg.h index 38ab3f46346f..f67810f8f21b 100644 --- a/trunk/include/linux/usb/otg.h +++ b/trunk/include/linux/usb/otg.h @@ -94,7 +94,6 @@ struct usb_phy { struct usb_otg *otg; - struct device *io_dev; struct usb_phy_io_ops *io_ops; void __iomem *io_priv; diff --git a/trunk/include/linux/vgaarb.h b/trunk/include/linux/vgaarb.h index 0ee42d9acdc0..367ab18dccf7 100644 --- a/trunk/include/linux/vgaarb.h +++ b/trunk/include/linux/vgaarb.h @@ -183,13 +183,8 @@ extern void vga_put(struct pci_dev *pdev, unsigned int rsrc); */ #ifndef __ARCH_HAS_VGA_DEFAULT_DEVICE -#ifdef CONFIG_VGA_ARB extern struct pci_dev *vga_default_device(void); extern void vga_set_default_device(struct pci_dev *pdev); -#else -static inline struct pci_dev *vga_default_device(void) { return NULL; }; -static inline void vga_set_default_device(struct pci_dev *pdev) { }; -#endif #endif /** diff --git a/trunk/include/linux/vm_event_item.h b/trunk/include/linux/vm_event_item.h index 06f8e3858251..03b90cdc1921 100644 --- a/trunk/include/linux/vm_event_item.h +++ b/trunk/include/linux/vm_event_item.h @@ -26,14 +26,13 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, PGFREE, PGACTIVATE, PGDEACTIVATE, PGFAULT, PGMAJFAULT, FOR_ALL_ZONES(PGREFILL), - FOR_ALL_ZONES(PGSTEAL_KSWAPD), - FOR_ALL_ZONES(PGSTEAL_DIRECT), + FOR_ALL_ZONES(PGSTEAL), FOR_ALL_ZONES(PGSCAN_KSWAPD), FOR_ALL_ZONES(PGSCAN_DIRECT), #ifdef CONFIG_NUMA PGSCAN_ZONE_RECLAIM_FAILED, #endif - PGINODESTEAL, SLABS_SCANNED, KSWAPD_INODESTEAL, + PGINODESTEAL, SLABS_SCANNED, KSWAPD_STEAL, KSWAPD_INODESTEAL, KSWAPD_LOW_WMARK_HIT_QUICKLY, KSWAPD_HIGH_WMARK_HIT_QUICKLY, KSWAPD_SKIP_CONGESTION_WAIT, PAGEOUTRUN, ALLOCSTALL, PGROTATED, diff --git a/trunk/include/net/bluetooth/hci_core.h b/trunk/include/net/bluetooth/hci_core.h index db1c5df45224..6822d2595aff 100644 --- a/trunk/include/net/bluetooth/hci_core.h +++ b/trunk/include/net/bluetooth/hci_core.h @@ -314,7 +314,6 @@ struct hci_conn { __u8 remote_cap; __u8 remote_auth; - bool flush_key; unsigned int sent; @@ -981,7 +980,7 @@ int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable); int mgmt_connectable(struct hci_dev *hdev, u8 connectable); int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status); int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, - bool persistent); + u8 persistent); int mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u32 flags, u8 *name, u8 name_len, u8 *dev_class); diff --git a/trunk/include/net/dst.h b/trunk/include/net/dst.h index bed833d9796a..59c5d18cc385 100644 --- a/trunk/include/net/dst.h +++ b/trunk/include/net/dst.h @@ -36,11 +36,7 @@ struct dst_entry { struct net_device *dev; struct dst_ops *ops; unsigned long _metrics; - union { - unsigned long expires; - /* point to where the dst_entry copied from */ - struct dst_entry *from; - }; + unsigned long expires; struct dst_entry *path; struct neighbour __rcu *_neighbour; #ifdef CONFIG_XFRM @@ -59,7 +55,6 @@ struct dst_entry { #define DST_NOCACHE 0x0010 #define DST_NOCOUNT 0x0020 #define DST_NOPEER 0x0040 -#define DST_FAKE_RTABLE 0x0080 short error; short obsolete; diff --git a/trunk/include/net/ip6_fib.h b/trunk/include/net/ip6_fib.h index 0ae759a6c76e..b26bb8101981 100644 --- a/trunk/include/net/ip6_fib.h +++ b/trunk/include/net/ip6_fib.h @@ -123,54 +123,6 @@ static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) return ((struct rt6_info *)dst)->rt6i_idev; } -static inline void rt6_clean_expires(struct rt6_info *rt) -{ - if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) - dst_release(rt->dst.from); - - rt->rt6i_flags &= ~RTF_EXPIRES; - rt->dst.from = NULL; -} - -static inline void rt6_set_expires(struct rt6_info *rt, unsigned long expires) -{ - if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) - dst_release(rt->dst.from); - - rt->rt6i_flags |= RTF_EXPIRES; - rt->dst.expires = expires; -} - -static inline void rt6_update_expires(struct rt6_info *rt, int timeout) -{ - if (!(rt->rt6i_flags & RTF_EXPIRES)) { - if (rt->dst.from) - dst_release(rt->dst.from); - /* dst_set_expires relies on expires == 0 - * if it has not been set previously. - */ - rt->dst.expires = 0; - } - - dst_set_expires(&rt->dst, timeout); - rt->rt6i_flags |= RTF_EXPIRES; -} - -static inline void rt6_set_from(struct rt6_info *rt, struct rt6_info *from) -{ - struct dst_entry *new = (struct dst_entry *) from; - - if (!(rt->rt6i_flags & RTF_EXPIRES) && rt->dst.from) { - if (new == rt->dst.from) - return; - dst_release(rt->dst.from); - } - - rt->rt6i_flags &= ~RTF_EXPIRES; - rt->dst.from = new; - dst_hold(new); -} - struct fib6_walker_t { struct list_head lh; struct fib6_node *root, *node; diff --git a/trunk/include/net/ip_vs.h b/trunk/include/net/ip_vs.h index 72522f087375..2bdee51ba30d 100644 --- a/trunk/include/net/ip_vs.h +++ b/trunk/include/net/ip_vs.h @@ -393,7 +393,7 @@ struct ip_vs_protocol { void (*exit)(struct ip_vs_protocol *pp); - int (*init_netns)(struct net *net, struct ip_vs_proto_data *pd); + void (*init_netns)(struct net *net, struct ip_vs_proto_data *pd); void (*exit_netns)(struct net *net, struct ip_vs_proto_data *pd); @@ -1203,8 +1203,6 @@ ip_vs_lookup_real_service(struct net *net, int af, __u16 protocol, extern int ip_vs_use_count_inc(void); extern void ip_vs_use_count_dec(void); -extern int ip_vs_register_nl_ioctl(void); -extern void ip_vs_unregister_nl_ioctl(void); extern int ip_vs_control_init(void); extern void ip_vs_control_cleanup(void); extern struct ip_vs_dest * diff --git a/trunk/include/net/red.h b/trunk/include/net/red.h index ef46058d35bf..77d4c3745cb5 100644 --- a/trunk/include/net/red.h +++ b/trunk/include/net/red.h @@ -245,7 +245,7 @@ static inline unsigned long red_calc_qavg_from_idle_time(const struct red_parms * * dummy packets as a burst after idle time, i.e. * - * v->qavg *= (1-W)^m + * p->qavg *= (1-W)^m * * This is an apparently overcomplicated solution (f.e. we have to * precompute a table to make this calculation in reasonable time) @@ -279,7 +279,7 @@ static inline unsigned long red_calc_qavg_no_idle_time(const struct red_parms *p unsigned int backlog) { /* - * NOTE: v->qavg is fixed point number with point at Wlog. + * NOTE: p->qavg is fixed point number with point at Wlog. * The formula below is equvalent to floating point * version: * @@ -390,7 +390,7 @@ static inline void red_adaptative_algo(struct red_parms *p, struct red_vars *v) if (red_is_idling(v)) qavg = red_calc_qavg_from_idle_time(p, v); - /* v->qavg is fixed point number with point at Wlog */ + /* p->qavg is fixed point number with point at Wlog */ qavg >>= p->Wlog; if (qavg > p->target_max && p->max_P <= MAX_P_MAX) diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 5a0a58ac4126..a6ba1f8871fd 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -246,7 +246,6 @@ struct cg_proto; * @sk_user_data: RPC layer private data * @sk_sndmsg_page: cached page for sendmsg * @sk_sndmsg_off: cached offset for sendmsg - * @sk_peek_off: current peek_offset value * @sk_send_head: front of stuff to transmit * @sk_security: used by security modules * @sk_mark: generic packet mark @@ -1129,9 +1128,9 @@ sk_sockets_allocated_read_positive(struct sock *sk) struct proto *prot = sk->sk_prot; if (mem_cgroup_sockets_enabled && sk->sk_cgrp) - return percpu_counter_read_positive(sk->sk_cgrp->sockets_allocated); + return percpu_counter_sum_positive(sk->sk_cgrp->sockets_allocated); - return percpu_counter_read_positive(prot->sockets_allocated); + return percpu_counter_sum_positive(prot->sockets_allocated); } static inline int diff --git a/trunk/include/scsi/libsas.h b/trunk/include/scsi/libsas.h index f4f1c96dca72..5f5ed1b8b41b 100644 --- a/trunk/include/scsi/libsas.h +++ b/trunk/include/scsi/libsas.h @@ -217,29 +217,11 @@ struct domain_device { struct kref kref; }; -struct sas_work { - struct list_head drain_node; - struct work_struct work; -}; - -static inline void INIT_SAS_WORK(struct sas_work *sw, void (*fn)(struct work_struct *)) -{ - INIT_WORK(&sw->work, fn); - INIT_LIST_HEAD(&sw->drain_node); -} - struct sas_discovery_event { - struct sas_work work; + struct work_struct work; struct asd_sas_port *port; }; -static inline struct sas_discovery_event *to_sas_discovery_event(struct work_struct *work) -{ - struct sas_discovery_event *ev = container_of(work, typeof(*ev), work.work); - - return ev; -} - struct sas_discovery { struct sas_discovery_event disc_work[DISC_NUM_EVENTS]; unsigned long pending; @@ -262,7 +244,7 @@ struct asd_sas_port { struct list_head destroy_list; enum sas_linkrate linkrate; - struct sas_work work; + struct work_struct work; /* public: */ int id; @@ -288,17 +270,10 @@ struct asd_sas_port { }; struct asd_sas_event { - struct sas_work work; + struct work_struct work; struct asd_sas_phy *phy; }; -static inline struct asd_sas_event *to_asd_sas_event(struct work_struct *work) -{ - struct asd_sas_event *ev = container_of(work, typeof(*ev), work.work); - - return ev; -} - /* The phy pretty much is controlled by the LLDD. * The class only reads those fields. */ @@ -358,17 +333,10 @@ struct scsi_core { }; struct sas_ha_event { - struct sas_work work; + struct work_struct work; struct sas_ha_struct *ha; }; -static inline struct sas_ha_event *to_sas_ha_event(struct work_struct *work) -{ - struct sas_ha_event *ev = container_of(work, typeof(*ev), work.work); - - return ev; -} - enum sas_ha_state { SAS_HA_REGISTERED, SAS_HA_DRAINING, diff --git a/trunk/include/scsi/sas_ata.h b/trunk/include/scsi/sas_ata.h index 77670e823ed8..cdccd2eb7b6c 100644 --- a/trunk/include/scsi/sas_ata.h +++ b/trunk/include/scsi/sas_ata.h @@ -37,7 +37,7 @@ static inline int dev_is_sata(struct domain_device *dev) } int sas_get_ata_info(struct domain_device *dev, struct ex_phy *phy); -int sas_ata_init(struct domain_device *dev); +int sas_ata_init_host_and_port(struct domain_device *found_dev); void sas_ata_task_abort(struct sas_task *task); void sas_ata_strategy_handler(struct Scsi_Host *shost); void sas_ata_eh(struct Scsi_Host *shost, struct list_head *work_q, @@ -52,7 +52,7 @@ static inline int dev_is_sata(struct domain_device *dev) { return 0; } -static inline int sas_ata_init(struct domain_device *dev) +static inline int sas_ata_init_host_and_port(struct domain_device *found_dev) { return 0; } diff --git a/trunk/init/do_mounts.c b/trunk/init/do_mounts.c index 42b0707c3481..0e93f92a0345 100644 --- a/trunk/init/do_mounts.c +++ b/trunk/init/do_mounts.c @@ -472,7 +472,7 @@ void __init change_floppy(char *fmt, ...) void __init mount_root(void) { #ifdef CONFIG_ROOT_NFS - if (ROOT_DEV == Root_NFS) { + if (MAJOR(ROOT_DEV) == UNNAMED_MAJOR) { if (mount_nfs_root()) return; diff --git a/trunk/init/main.c b/trunk/init/main.c index 44b2433334c7..9d454f09f3b1 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -225,9 +225,13 @@ static int __init loglevel(char *str) early_param("loglevel", loglevel); -/* Change NUL term back to "=", to make "param" the whole string. */ -static int __init repair_env_string(char *param, char *val) +/* + * Unknown boot options get handed to init, unless they look like + * unused parameters (modprobe will find them in /proc/cmdline). + */ +static int __init unknown_bootoption(char *param, char *val) { + /* Change NUL term back to "=", to make "param" the whole string. */ if (val) { /* param=val or param="val"? */ if (val == param+strlen(param)+1) @@ -239,16 +243,6 @@ static int __init repair_env_string(char *param, char *val) } else BUG(); } - return 0; -} - -/* - * Unknown boot options get handed to init, unless they look like - * unused parameters (modprobe will find them in /proc/cmdline). - */ -static int __init unknown_bootoption(char *param, char *val) -{ - repair_env_string(param, val); /* Handle obsolete-style parameters */ if (obsolete_checksetup(param)) @@ -738,6 +732,11 @@ static char *initcall_level_names[] __initdata = { "late parameters", }; +static int __init ignore_unknown_bootoption(char *param, char *val) +{ + return 0; +} + static void __init do_initcall_level(int level) { extern const struct kernel_param __start___param[], __stop___param[]; @@ -748,7 +747,7 @@ static void __init do_initcall_level(int level) static_command_line, __start___param, __stop___param - __start___param, level, level, - repair_env_string); + ignore_unknown_bootoption); for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) do_one_initcall(*fn); diff --git a/trunk/kernel/events/core.c b/trunk/kernel/events/core.c index fd126f82b57c..a6a9ec4cd8f5 100644 --- a/trunk/kernel/events/core.c +++ b/trunk/kernel/events/core.c @@ -3183,7 +3183,7 @@ static void perf_event_for_each(struct perf_event *event, perf_event_for_each_child(event, func); func(event); list_for_each_entry(sibling, &event->sibling_list, group_entry) - perf_event_for_each_child(sibling, func); + perf_event_for_each_child(event, func); mutex_unlock(&ctx->mutex); } diff --git a/trunk/kernel/irq/debug.h b/trunk/kernel/irq/debug.h index e75e29e4434a..97a8bfadc88a 100644 --- a/trunk/kernel/irq/debug.h +++ b/trunk/kernel/irq/debug.h @@ -4,10 +4,10 @@ #include -#define ___P(f) if (desc->status_use_accessors & f) printk("%14s set\n", #f) -#define ___PS(f) if (desc->istate & f) printk("%14s set\n", #f) +#define P(f) if (desc->status_use_accessors & f) printk("%14s set\n", #f) +#define PS(f) if (desc->istate & f) printk("%14s set\n", #f) /* FIXME */ -#define ___PD(f) do { } while (0) +#define PD(f) do { } while (0) static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) { @@ -23,23 +23,23 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc) print_symbol("%s\n", (unsigned long)desc->action->handler); } - ___P(IRQ_LEVEL); - ___P(IRQ_PER_CPU); - ___P(IRQ_NOPROBE); - ___P(IRQ_NOREQUEST); - ___P(IRQ_NOTHREAD); - ___P(IRQ_NOAUTOEN); + P(IRQ_LEVEL); + P(IRQ_PER_CPU); + P(IRQ_NOPROBE); + P(IRQ_NOREQUEST); + P(IRQ_NOTHREAD); + P(IRQ_NOAUTOEN); - ___PS(IRQS_AUTODETECT); - ___PS(IRQS_REPLAY); - ___PS(IRQS_WAITING); - ___PS(IRQS_PENDING); + PS(IRQS_AUTODETECT); + PS(IRQS_REPLAY); + PS(IRQS_WAITING); + PS(IRQS_PENDING); - ___PD(IRQS_INPROGRESS); - ___PD(IRQS_DISABLED); - ___PD(IRQS_MASKED); + PD(IRQS_INPROGRESS); + PD(IRQS_DISABLED); + PD(IRQS_MASKED); } -#undef ___P -#undef ___PS -#undef ___PD +#undef P +#undef PS +#undef PD diff --git a/trunk/kernel/power/swap.c b/trunk/kernel/power/swap.c index eef311a58a64..8742fd013a94 100644 --- a/trunk/kernel/power/swap.c +++ b/trunk/kernel/power/swap.c @@ -51,23 +51,6 @@ #define MAP_PAGE_ENTRIES (PAGE_SIZE / sizeof(sector_t) - 1) -/* - * Number of free pages that are not high. - */ -static inline unsigned long low_free_pages(void) -{ - return nr_free_pages() - nr_free_highpages(); -} - -/* - * Number of pages required to be kept free while writing the image. Always - * half of all available low pages before the writing starts. - */ -static inline unsigned long reqd_free_pages(void) -{ - return low_free_pages() / 2; -} - struct swap_map_page { sector_t entries[MAP_PAGE_ENTRIES]; sector_t next_swap; @@ -89,7 +72,7 @@ struct swap_map_handle { sector_t cur_swap; sector_t first_sector; unsigned int k; - unsigned long reqd_free_pages; + unsigned long nr_free_pages, written; u32 crc32; }; @@ -333,7 +316,8 @@ static int get_swap_writer(struct swap_map_handle *handle) goto err_rel; } handle->k = 0; - handle->reqd_free_pages = reqd_free_pages(); + handle->nr_free_pages = nr_free_pages() >> 1; + handle->written = 0; handle->first_sector = handle->cur_swap; return 0; err_rel: @@ -368,11 +352,11 @@ static int swap_write_page(struct swap_map_handle *handle, void *buf, handle->cur_swap = offset; handle->k = 0; } - if (bio_chain && low_free_pages() <= handle->reqd_free_pages) { + if (bio_chain && ++handle->written > handle->nr_free_pages) { error = hib_wait_on_bio_chain(bio_chain); if (error) goto out; - handle->reqd_free_pages = reqd_free_pages(); + handle->written = 0; } out: return error; @@ -634,7 +618,7 @@ static int save_image_lzo(struct swap_map_handle *handle, * Adjust number of free pages after all allocations have been done. * We don't want to run out of pages when writing. */ - handle->reqd_free_pages = reqd_free_pages(); + handle->nr_free_pages = nr_free_pages() >> 1; /* * Start the CRC32 thread. diff --git a/trunk/kernel/rcutree.c b/trunk/kernel/rcutree.c index d0c5baf1ab18..1050d6d3922c 100644 --- a/trunk/kernel/rcutree.c +++ b/trunk/kernel/rcutree.c @@ -1820,6 +1820,7 @@ __call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *rcu), * a quiescent state betweentimes. */ local_irq_save(flags); + WARN_ON_ONCE(cpu_is_offline(smp_processor_id())); rdp = this_cpu_ptr(rsp->rda); /* Add the callback to our list. */ diff --git a/trunk/kernel/sched/core.c b/trunk/kernel/sched/core.c index 0533a688ce22..4603b9d8f30a 100644 --- a/trunk/kernel/sched/core.c +++ b/trunk/kernel/sched/core.c @@ -6405,26 +6405,16 @@ static void __sdt_free(const struct cpumask *cpu_map) struct sd_data *sdd = &tl->data; for_each_cpu(j, cpu_map) { - struct sched_domain *sd; - - if (sdd->sd) { - sd = *per_cpu_ptr(sdd->sd, j); - if (sd && (sd->flags & SD_OVERLAP)) - free_sched_groups(sd->groups, 0); - kfree(*per_cpu_ptr(sdd->sd, j)); - } - - if (sdd->sg) - kfree(*per_cpu_ptr(sdd->sg, j)); - if (sdd->sgp) - kfree(*per_cpu_ptr(sdd->sgp, j)); + struct sched_domain *sd = *per_cpu_ptr(sdd->sd, j); + if (sd && (sd->flags & SD_OVERLAP)) + free_sched_groups(sd->groups, 0); + kfree(*per_cpu_ptr(sdd->sd, j)); + kfree(*per_cpu_ptr(sdd->sg, j)); + kfree(*per_cpu_ptr(sdd->sgp, j)); } free_percpu(sdd->sd); - sdd->sd = NULL; free_percpu(sdd->sg); - sdd->sg = NULL; free_percpu(sdd->sgp); - sdd->sgp = NULL; } } diff --git a/trunk/kernel/sched/fair.c b/trunk/kernel/sched/fair.c index e9553640c1c3..0d97ebdc58f0 100644 --- a/trunk/kernel/sched/fair.c +++ b/trunk/kernel/sched/fair.c @@ -784,7 +784,7 @@ account_entity_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se) update_load_add(&rq_of(cfs_rq)->load, se->load.weight); #ifdef CONFIG_SMP if (entity_is_task(se)) - list_add(&se->group_node, &rq_of(cfs_rq)->cfs_tasks); + list_add_tail(&se->group_node, &rq_of(cfs_rq)->cfs_tasks); #endif cfs_rq->nr_running++; } @@ -3215,8 +3215,6 @@ static int move_one_task(struct lb_env *env) static unsigned long task_h_load(struct task_struct *p); -static const unsigned int sched_nr_migrate_break = 32; - /* * move_tasks tries to move up to load_move weighted load from busiest to * this_rq, as part of a balancing operation within domain "sd". @@ -3244,7 +3242,7 @@ static int move_tasks(struct lb_env *env) /* take a breather every nr_migrate tasks */ if (env->loop > env->loop_break) { - env->loop_break += sched_nr_migrate_break; + env->loop_break += sysctl_sched_nr_migrate; env->flags |= LBF_NEED_BREAK; break; } @@ -3254,7 +3252,7 @@ static int move_tasks(struct lb_env *env) load = task_h_load(p); - if (sched_feat(LB_MIN) && load < 16 && !env->sd->nr_balance_failed) + if (load < 16 && !env->sd->nr_balance_failed) goto next; if ((load / 2) > env->load_move) @@ -4409,7 +4407,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, .dst_cpu = this_cpu, .dst_rq = this_rq, .idle = idle, - .loop_break = sched_nr_migrate_break, + .loop_break = sysctl_sched_nr_migrate, }; cpumask_copy(cpus, cpu_active_mask); @@ -4447,10 +4445,10 @@ static int load_balance(int this_cpu, struct rq *this_rq, * correctly treated as an imbalance. */ env.flags |= LBF_ALL_PINNED; - env.load_move = imbalance; - env.src_cpu = busiest->cpu; - env.src_rq = busiest; - env.loop_max = min_t(unsigned long, sysctl_sched_nr_migrate, busiest->nr_running); + env.load_move = imbalance; + env.src_cpu = busiest->cpu; + env.src_rq = busiest; + env.loop_max = busiest->nr_running; more_balance: local_irq_save(flags); diff --git a/trunk/kernel/sched/features.h b/trunk/kernel/sched/features.h index de00a486c5c6..e61fd73913d0 100644 --- a/trunk/kernel/sched/features.h +++ b/trunk/kernel/sched/features.h @@ -68,4 +68,3 @@ SCHED_FEAT(TTWU_QUEUE, true) SCHED_FEAT(FORCE_SD_OVERLAP, false) SCHED_FEAT(RT_RUNTIME_SHARE, true) -SCHED_FEAT(LB_MIN, false) diff --git a/trunk/kernel/time/tick-broadcast.c b/trunk/kernel/time/tick-broadcast.c index f113755695e2..bf57abdc7bd0 100644 --- a/trunk/kernel/time/tick-broadcast.c +++ b/trunk/kernel/time/tick-broadcast.c @@ -346,8 +346,7 @@ int tick_resume_broadcast(void) tick_get_broadcast_mask()); break; case TICKDEV_MODE_ONESHOT: - if (!cpumask_empty(tick_get_broadcast_mask())) - broadcast = tick_resume_broadcast_oneshot(bc); + broadcast = tick_resume_broadcast_oneshot(bc); break; } } @@ -374,9 +373,6 @@ static int tick_broadcast_set_event(ktime_t expires, int force) { struct clock_event_device *bc = tick_broadcast_device.evtdev; - if (bc->mode != CLOCK_EVT_MODE_ONESHOT) - clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); - return clockevents_program_event(bc, expires, force); } @@ -535,6 +531,7 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) int was_periodic = bc->mode == CLOCK_EVT_MODE_PERIODIC; bc->event_handler = tick_handle_oneshot_broadcast; + clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); /* Take the do_timer update */ tick_do_timer_cpu = cpu; @@ -552,7 +549,6 @@ void tick_broadcast_setup_oneshot(struct clock_event_device *bc) to_cpumask(tmpmask)); if (was_periodic && !cpumask_empty(to_cpumask(tmpmask))) { - clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); tick_broadcast_init_next_event(to_cpumask(tmpmask), tick_next_period); tick_broadcast_set_event(tick_next_period, 1); @@ -581,10 +577,15 @@ void tick_broadcast_switch_to_oneshot(void) raw_spin_lock_irqsave(&tick_broadcast_lock, flags); tick_broadcast_device.mode = TICKDEV_MODE_ONESHOT; + + if (cpumask_empty(tick_get_broadcast_mask())) + goto end; + bc = tick_broadcast_device.evtdev; if (bc) tick_broadcast_setup_oneshot(bc); +end: raw_spin_unlock_irqrestore(&tick_broadcast_lock, flags); } diff --git a/trunk/kernel/trace/trace.c b/trunk/kernel/trace/trace.c index 2a22255c1010..ed7b5d1e12f4 100644 --- a/trunk/kernel/trace/trace.c +++ b/trunk/kernel/trace/trace.c @@ -4629,8 +4629,7 @@ static ssize_t rb_simple_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { - struct trace_array *tr = filp->private_data; - struct ring_buffer *buffer = tr->buffer; + struct ring_buffer *buffer = filp->private_data; char buf[64]; int r; @@ -4648,8 +4647,7 @@ static ssize_t rb_simple_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { - struct trace_array *tr = filp->private_data; - struct ring_buffer *buffer = tr->buffer; + struct ring_buffer *buffer = filp->private_data; unsigned long val; int ret; @@ -4736,7 +4734,7 @@ static __init int tracer_init_debugfs(void) &trace_clock_fops); trace_create_file("tracing_on", 0644, d_tracer, - &global_trace, &rb_simple_fops); + global_trace.buffer, &rb_simple_fops); #ifdef CONFIG_DYNAMIC_FTRACE trace_create_file("dyn_ftrace_total_info", 0444, d_tracer, diff --git a/trunk/kernel/trace/trace.h b/trunk/kernel/trace/trace.h index f95d65da6db8..95059f091a24 100644 --- a/trunk/kernel/trace/trace.h +++ b/trunk/kernel/trace/trace.h @@ -836,11 +836,11 @@ extern const char *__stop___trace_bprintk_fmt[]; filter) #include "trace_entries.h" -#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_FUNCTION_TRACER) +#ifdef CONFIG_FUNCTION_TRACER int perf_ftrace_event_register(struct ftrace_event_call *call, enum trace_reg type, void *data); #else #define perf_ftrace_event_register NULL -#endif +#endif /* CONFIG_FUNCTION_TRACER */ #endif /* _LINUX_KERNEL_TRACE_H */ diff --git a/trunk/kernel/trace/trace_output.c b/trunk/kernel/trace/trace_output.c index df611a0e76c5..859fae6b1825 100644 --- a/trunk/kernel/trace/trace_output.c +++ b/trunk/kernel/trace/trace_output.c @@ -652,8 +652,6 @@ int trace_print_lat_context(struct trace_iterator *iter) { u64 next_ts; int ret; - /* trace_find_next_entry will reset ent_size */ - int ent_size = iter->ent_size; struct trace_seq *s = &iter->seq; struct trace_entry *entry = iter->ent, *next_entry = trace_find_next_entry(iter, NULL, @@ -662,9 +660,6 @@ int trace_print_lat_context(struct trace_iterator *iter) unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start); unsigned long rel_usecs; - /* Restore the original ent_size */ - iter->ent_size = ent_size; - if (!next_entry) next_ts = iter->ts; rel_usecs = ns2usecs(next_ts - iter->ts); diff --git a/trunk/lib/mpi/mpi-bit.c b/trunk/lib/mpi/mpi-bit.c index 0c505361da19..2f526627e4f5 100644 --- a/trunk/lib/mpi/mpi-bit.c +++ b/trunk/lib/mpi/mpi-bit.c @@ -177,8 +177,8 @@ int mpi_rshift(MPI x, MPI a, unsigned n) */ int mpi_lshift_limbs(MPI a, unsigned int count) { - const int n = a->nlimbs; - mpi_ptr_t ap; + mpi_ptr_t ap = a->d; + int n = a->nlimbs; int i; if (!count || !n) @@ -187,7 +187,6 @@ int mpi_lshift_limbs(MPI a, unsigned int count) if (RESIZE_IF_NEEDED(a, n + count) < 0) return -ENOMEM; - ap = a->d; for (i = n - 1; i >= 0; i--) ap[i + count] = ap[i]; for (i = 0; i < count; i++) diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index 5a16423a512c..cd65cb19c941 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -532,7 +532,7 @@ static struct page *dequeue_huge_page_vma(struct hstate *h, struct vm_area_struct *vma, unsigned long address, int avoid_reserve) { - struct page *page = NULL; + struct page *page; struct mempolicy *mpol; nodemask_t *nodemask; struct zonelist *zonelist; diff --git a/trunk/mm/memblock.c b/trunk/mm/memblock.c index a44eab3157f8..99f285599501 100644 --- a/trunk/mm/memblock.c +++ b/trunk/mm/memblock.c @@ -330,9 +330,6 @@ static int __init_memblock memblock_add_region(struct memblock_type *type, phys_addr_t end = base + memblock_cap_size(base, &size); int i, nr_new; - if (!size) - return 0; - /* special case for empty array */ if (type->regions[0].size == 0) { WARN_ON(type->cnt != 1 || type->total_size); @@ -433,9 +430,6 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type, *start_rgn = *end_rgn = 0; - if (!size) - return 0; - /* we'll create at most two more regions */ while (type->cnt + 2 > type->max) if (memblock_double_array(type) < 0) @@ -520,6 +514,7 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size) (unsigned long long)base, (unsigned long long)base + size, (void *)_RET_IP_); + BUG_ON(0 == size); return memblock_add_region(_rgn, base, size, MAX_NUMNODES); } diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index 31ab9c3f0178..a7165a60d0a7 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -2476,10 +2476,10 @@ struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page) static void __mem_cgroup_commit_charge(struct mem_cgroup *memcg, struct page *page, unsigned int nr_pages, + struct page_cgroup *pc, enum charge_type ctype, bool lrucare) { - struct page_cgroup *pc = lookup_page_cgroup(page); struct zone *uninitialized_var(zone); bool was_on_lru = false; bool anon; @@ -2716,6 +2716,7 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, { struct mem_cgroup *memcg = NULL; unsigned int nr_pages = 1; + struct page_cgroup *pc; bool oom = true; int ret; @@ -2729,10 +2730,11 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, oom = false; } + pc = lookup_page_cgroup(page); ret = __mem_cgroup_try_charge(mm, gfp_mask, nr_pages, &memcg, oom); if (ret == -ENOMEM) return ret; - __mem_cgroup_commit_charge(memcg, page, nr_pages, ctype, false); + __mem_cgroup_commit_charge(memcg, page, nr_pages, pc, ctype, false); return 0; } @@ -2829,13 +2831,16 @@ static void __mem_cgroup_commit_charge_swapin(struct page *page, struct mem_cgroup *memcg, enum charge_type ctype) { + struct page_cgroup *pc; + if (mem_cgroup_disabled()) return; if (!memcg) return; cgroup_exclude_rmdir(&memcg->css); - __mem_cgroup_commit_charge(memcg, page, 1, ctype, true); + pc = lookup_page_cgroup(page); + __mem_cgroup_commit_charge(memcg, page, 1, pc, ctype, true); /* * Now swap is on-memory. This means this page may be * counted both as mem and swap....double count. @@ -3293,13 +3298,14 @@ int mem_cgroup_prepare_migration(struct page *page, * page. In the case new page is migrated but not remapped, new page's * mapcount will be finally 0 and we call uncharge in end_migration(). */ + pc = lookup_page_cgroup(newpage); if (PageAnon(page)) ctype = MEM_CGROUP_CHARGE_TYPE_MAPPED; else if (page_is_file_cache(page)) ctype = MEM_CGROUP_CHARGE_TYPE_CACHE; else ctype = MEM_CGROUP_CHARGE_TYPE_SHMEM; - __mem_cgroup_commit_charge(memcg, newpage, 1, ctype, false); + __mem_cgroup_commit_charge(memcg, newpage, 1, pc, ctype, false); return ret; } @@ -3386,7 +3392,7 @@ void mem_cgroup_replace_page_cache(struct page *oldpage, * the newpage may be on LRU(or pagevec for LRU) already. We lock * LRU while we overwrite pc->mem_cgroup. */ - __mem_cgroup_commit_charge(memcg, newpage, 1, type, true); + __mem_cgroup_commit_charge(memcg, newpage, 1, pc, type, true); } #ifdef CONFIG_DEBUG_VM diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index b19569137529..cfb6c8678754 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -1361,14 +1361,11 @@ SYSCALL_DEFINE4(migrate_pages, pid_t, pid, unsigned long, maxnode, mm = get_task_mm(task); put_task_struct(task); - - if (!mm) { + if (mm) + err = do_migrate_pages(mm, old, new, + capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE); + else err = -EINVAL; - goto out; - } - - err = do_migrate_pages(mm, old, new, - capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE); mmput(mm); out: diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index 11072383ae12..51c08a0c6f68 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -1388,14 +1388,14 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages, mm = get_task_mm(task); put_task_struct(task); - if (!mm) - return -EINVAL; - - if (nodes) - err = do_pages_move(mm, task_nodes, nr_pages, pages, - nodes, status, flags); - else - err = do_pages_stat(mm, nr_pages, pages, status); + if (mm) { + if (nodes) + err = do_pages_move(mm, task_nodes, nr_pages, pages, + nodes, status, flags); + else + err = do_pages_stat(mm, nr_pages, pages, status); + } else + err = -EINVAL; mmput(mm); return err; diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 848ef52d9603..a7bf6a31c9f6 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -240,8 +240,6 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) return next; } -static unsigned long do_brk(unsigned long addr, unsigned long len); - SYSCALL_DEFINE1(brk, unsigned long, brk) { unsigned long rlim, retval; @@ -953,7 +951,7 @@ static inline unsigned long round_hint_to_min(unsigned long hint) * The caller must hold down_write(¤t->mm->mmap_sem). */ -static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, +unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long pgoff) { @@ -1089,32 +1087,7 @@ static unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, return mmap_region(file, addr, len, flags, vm_flags, pgoff); } - -unsigned long do_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - if (unlikely(offset + PAGE_ALIGN(len) < offset)) - return -EINVAL; - if (unlikely(offset & ~PAGE_MASK)) - return -EINVAL; - return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); -} -EXPORT_SYMBOL(do_mmap); - -unsigned long vm_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - unsigned long ret; - struct mm_struct *mm = current->mm; - - down_write(&mm->mmap_sem); - ret = do_mmap(file, addr, len, prot, flag, offset); - up_write(&mm->mmap_sem); - return ret; -} -EXPORT_SYMBOL(vm_mmap); +EXPORT_SYMBOL(do_mmap_pgoff); SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, @@ -2132,25 +2105,21 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) return 0; } + EXPORT_SYMBOL(do_munmap); -int vm_munmap(unsigned long start, size_t len) +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { int ret; struct mm_struct *mm = current->mm; + profile_munmap(addr); + down_write(&mm->mmap_sem); - ret = do_munmap(mm, start, len); + ret = do_munmap(mm, addr, len); up_write(&mm->mmap_sem); return ret; } -EXPORT_SYMBOL(vm_munmap); - -SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) -{ - profile_munmap(addr); - return vm_munmap(addr, len); -} static inline void verify_mm_writelocked(struct mm_struct *mm) { @@ -2167,7 +2136,7 @@ static inline void verify_mm_writelocked(struct mm_struct *mm) * anonymous maps. eventually we may be able to do some * brk-specific accounting here. */ -static unsigned long do_brk(unsigned long addr, unsigned long len) +unsigned long do_brk(unsigned long addr, unsigned long len) { struct mm_struct * mm = current->mm; struct vm_area_struct * vma, * prev; @@ -2263,17 +2232,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) return addr; } -unsigned long vm_brk(unsigned long addr, unsigned long len) -{ - struct mm_struct *mm = current->mm; - unsigned long ret; - - down_write(&mm->mmap_sem); - ret = do_brk(addr, len); - up_write(&mm->mmap_sem); - return ret; -} -EXPORT_SYMBOL(vm_brk); +EXPORT_SYMBOL(do_brk); /* Release all mmaps. */ void exit_mmap(struct mm_struct *mm) diff --git a/trunk/mm/nobootmem.c b/trunk/mm/nobootmem.c index e53bb8a256b1..24f0fc1a56d6 100644 --- a/trunk/mm/nobootmem.c +++ b/trunk/mm/nobootmem.c @@ -298,19 +298,13 @@ void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size, if (WARN_ON_ONCE(slab_is_available())) return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id); -again: ptr = __alloc_memory_core_early(pgdat->node_id, size, align, goal, -1ULL); if (ptr) return ptr; - ptr = __alloc_memory_core_early(MAX_NUMNODES, size, align, - goal, -1ULL); - if (!ptr && goal) { - goal = 0; - goto again; - } - return ptr; + return __alloc_memory_core_early(MAX_NUMNODES, size, align, + goal, -1ULL); } void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size, diff --git a/trunk/mm/nommu.c b/trunk/mm/nommu.c index bb8f4f004a82..f59e170fceb4 100644 --- a/trunk/mm/nommu.c +++ b/trunk/mm/nommu.c @@ -1233,7 +1233,7 @@ static int do_mmap_private(struct vm_area_struct *vma, /* * handle mapping creation for uClinux */ -static unsigned long do_mmap_pgoff(struct file *file, +unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, @@ -1470,32 +1470,7 @@ static unsigned long do_mmap_pgoff(struct file *file, show_free_areas(0); return -ENOMEM; } - -unsigned long do_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - if (unlikely(offset + PAGE_ALIGN(len) < offset)) - return -EINVAL; - if (unlikely(offset & ~PAGE_MASK)) - return -EINVAL; - return do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); -} -EXPORT_SYMBOL(do_mmap); - -unsigned long vm_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, - unsigned long flag, unsigned long offset) -{ - unsigned long ret; - struct mm_struct *mm = current->mm; - - down_write(&mm->mmap_sem); - ret = do_mmap(file, addr, len, prot, flag, offset); - up_write(&mm->mmap_sem); - return ret; -} -EXPORT_SYMBOL(vm_mmap); +EXPORT_SYMBOL(do_mmap_pgoff); SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, @@ -1734,22 +1709,16 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) } EXPORT_SYMBOL(do_munmap); -int vm_munmap(unsigned long addr, size_t len) +SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { - struct mm_struct *mm = current->mm; int ret; + struct mm_struct *mm = current->mm; down_write(&mm->mmap_sem); ret = do_munmap(mm, addr, len); up_write(&mm->mmap_sem); return ret; } -EXPORT_SYMBOL(vm_munmap); - -SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) -{ - return vm_munmap(addr, len); -} /* * release all the mappings made in a process's VM space @@ -1775,7 +1744,7 @@ void exit_mmap(struct mm_struct *mm) kleave(""); } -unsigned long vm_brk(unsigned long addr, unsigned long len) +unsigned long do_brk(unsigned long addr, unsigned long len) { return -ENOMEM; } diff --git a/trunk/mm/swap_state.c b/trunk/mm/swap_state.c index 4c5ff7f284d9..9d3dd3763cf7 100644 --- a/trunk/mm/swap_state.c +++ b/trunk/mm/swap_state.c @@ -26,7 +26,7 @@ */ static const struct address_space_operations swap_aops = { .writepage = swap_writepage, - .set_page_dirty = __set_page_dirty_no_writeback, + .set_page_dirty = __set_page_dirty_nobuffers, .migratepage = migrate_page, }; diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 33dc256033b5..1a518684a32f 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -1568,14 +1568,9 @@ shrink_inactive_list(unsigned long nr_to_scan, struct mem_cgroup_zone *mz, reclaim_stat->recent_scanned[0] += nr_anon; reclaim_stat->recent_scanned[1] += nr_file; - if (global_reclaim(sc)) { - if (current_is_kswapd()) - __count_zone_vm_events(PGSTEAL_KSWAPD, zone, - nr_reclaimed); - else - __count_zone_vm_events(PGSTEAL_DIRECT, zone, - nr_reclaimed); - } + if (current_is_kswapd()) + __count_vm_events(KSWAPD_STEAL, nr_reclaimed); + __count_zone_vm_events(PGSTEAL, zone, nr_reclaimed); putback_inactive_pages(mz, &page_list); diff --git a/trunk/mm/vmstat.c b/trunk/mm/vmstat.c index 7db1b9bab492..f600557a7659 100644 --- a/trunk/mm/vmstat.c +++ b/trunk/mm/vmstat.c @@ -738,8 +738,7 @@ const char * const vmstat_text[] = { "pgmajfault", TEXTS_FOR_ZONES("pgrefill") - TEXTS_FOR_ZONES("pgsteal_kswapd") - TEXTS_FOR_ZONES("pgsteal_direct") + TEXTS_FOR_ZONES("pgsteal") TEXTS_FOR_ZONES("pgscan_kswapd") TEXTS_FOR_ZONES("pgscan_direct") @@ -748,6 +747,7 @@ const char * const vmstat_text[] = { #endif "pginodesteal", "slabs_scanned", + "kswapd_steal", "kswapd_inodesteal", "kswapd_low_wmark_hit_quickly", "kswapd_high_wmark_hit_quickly", diff --git a/trunk/net/ax25/af_ax25.c b/trunk/net/ax25/af_ax25.c index 9d9a6a3edbd5..0906c194a413 100644 --- a/trunk/net/ax25/af_ax25.c +++ b/trunk/net/ax25/af_ax25.c @@ -2011,17 +2011,16 @@ static void __exit ax25_exit(void) proc_net_remove(&init_net, "ax25_route"); proc_net_remove(&init_net, "ax25"); proc_net_remove(&init_net, "ax25_calls"); + ax25_rt_free(); + ax25_uid_free(); + ax25_dev_free(); - unregister_netdevice_notifier(&ax25_dev_notifier); ax25_unregister_sysctl(); + unregister_netdevice_notifier(&ax25_dev_notifier); dev_remove_pack(&ax25_packet_type); sock_unregister(PF_AX25); proto_unregister(&ax25_proto); - - ax25_rt_free(); - ax25_uid_free(); - ax25_dev_free(); } module_exit(ax25_exit); diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index edfd61addcec..92a857e3786d 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -1215,40 +1215,40 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) return NULL; } -static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, +static int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, u8 key_type, u8 old_key_type) { /* Legacy key */ if (key_type < 0x03) - return true; + return 1; /* Debug keys are insecure so don't store them persistently */ if (key_type == HCI_LK_DEBUG_COMBINATION) - return false; + return 0; /* Changed combination key and there's no previous one */ if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff) - return false; + return 0; /* Security mode 3 case */ if (!conn) - return true; + return 1; /* Neither local nor remote side had no-bonding as requirement */ if (conn->auth_type > 0x01 && conn->remote_auth > 0x01) - return true; + return 1; /* Local side had dedicated bonding as requirement */ if (conn->auth_type == 0x02 || conn->auth_type == 0x03) - return true; + return 1; /* Remote side had dedicated bonding as requirement */ if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) - return true; + return 1; /* If none of the above criteria match, then don't store the key * persistently */ - return false; + return 0; } struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) @@ -1285,8 +1285,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) { struct link_key *key, *old_key; - u8 old_key_type; - bool persistent; + u8 old_key_type, persistent; old_key = hci_find_link_key(hdev, bdaddr); if (old_key) { @@ -1329,8 +1328,10 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, mgmt_new_link_key(hdev, key, persistent); - if (conn) - conn->flush_key = !persistent; + if (!persistent) { + list_del(&key->list); + kfree(key); + } return 0; } diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index 6c065254afc0..b37531094c49 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -1901,8 +1901,6 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff } if (ev->status == 0) { - if (conn->type == ACL_LINK && conn->flush_key) - hci_remove_link_key(hdev, &conn->dst); hci_proto_disconn_cfm(conn, ev->reason); hci_conn_del(conn); } @@ -2313,7 +2311,6 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk case HCI_OP_USER_PASSKEY_NEG_REPLY: hci_cc_user_passkey_neg_reply(hdev, skb); - break; case HCI_OP_LE_SET_SCAN_PARAM: hci_cc_le_set_scan_param(hdev, skb); diff --git a/trunk/net/bluetooth/mgmt.c b/trunk/net/bluetooth/mgmt.c index 4bb03b111122..4ef275c69675 100644 --- a/trunk/net/bluetooth/mgmt.c +++ b/trunk/net/bluetooth/mgmt.c @@ -2884,7 +2884,7 @@ int mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status) return 0; } -int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, bool persistent) +int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, u8 persistent) { struct mgmt_ev_new_link_key ev; diff --git a/trunk/net/bridge/br_forward.c b/trunk/net/bridge/br_forward.c index a2098e3de500..61f65344e711 100644 --- a/trunk/net/bridge/br_forward.c +++ b/trunk/net/bridge/br_forward.c @@ -47,7 +47,6 @@ int br_dev_queue_push_xmit(struct sk_buff *skb) kfree_skb(skb); } else { skb_push(skb, ETH_HLEN); - br_drop_fake_rtable(skb); dev_queue_xmit(skb); } diff --git a/trunk/net/bridge/br_netfilter.c b/trunk/net/bridge/br_netfilter.c index d7f49b63ab0f..dec4f3817133 100644 --- a/trunk/net/bridge/br_netfilter.c +++ b/trunk/net/bridge/br_netfilter.c @@ -156,7 +156,7 @@ void br_netfilter_rtable_init(struct net_bridge *br) rt->dst.dev = br->dev; rt->dst.path = &rt->dst; dst_init_metrics(&rt->dst, br_dst_default_metrics, true); - rt->dst.flags = DST_NOXFRM | DST_NOPEER | DST_FAKE_RTABLE; + rt->dst.flags = DST_NOXFRM | DST_NOPEER; rt->dst.ops = &fake_dst_ops; } @@ -694,7 +694,11 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff *skb, const struct net_device *out, int (*okfn)(struct sk_buff *)) { - br_drop_fake_rtable(skb); + struct rtable *rt = skb_rtable(skb); + + if (rt && rt == bridge_parent_rtable(in)) + skb_dst_drop(skb); + return NF_ACCEPT; } diff --git a/trunk/net/caif/chnl_net.c b/trunk/net/caif/chnl_net.c index d09340e1523f..20618dd3088b 100644 --- a/trunk/net/caif/chnl_net.c +++ b/trunk/net/caif/chnl_net.c @@ -103,7 +103,6 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt) skb->protocol = htons(ETH_P_IPV6); break; default: - kfree_skb(skb); priv->netdev->stats.rx_errors++; return -EINVAL; } @@ -221,16 +220,14 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev) if (skb->len > priv->netdev->mtu) { pr_warn("Size of skb exceeded MTU\n"); - kfree_skb(skb); dev->stats.tx_errors++; - return NETDEV_TX_OK; + return -ENOSPC; } if (!priv->flowenabled) { pr_debug("dropping packets flow off\n"); - kfree_skb(skb); dev->stats.tx_dropped++; - return NETDEV_TX_OK; + return NETDEV_TX_BUSY; } if (priv->conn_req.protocol == CAIFPROTO_DATAGRAM_LOOP) @@ -245,7 +242,7 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev) result = priv->chnl.dn->transmit(priv->chnl.dn, pkt); if (result) { dev->stats.tx_dropped++; - return NETDEV_TX_OK; + return result; } /* Update statistics. */ diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 9bb8f87c4cda..c25d453b2803 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1409,34 +1409,14 @@ EXPORT_SYMBOL(register_netdevice_notifier); * register_netdevice_notifier(). The notifier is unlinked into the * kernel structures and may then be reused. A negative errno code * is returned on a failure. - * - * After unregistering unregister and down device events are synthesized - * for all devices on the device list to the removed notifier to remove - * the need for special case cleanup code. */ int unregister_netdevice_notifier(struct notifier_block *nb) { - struct net_device *dev; - struct net *net; int err; rtnl_lock(); err = raw_notifier_chain_unregister(&netdev_chain, nb); - if (err) - goto unlock; - - for_each_net(net) { - for_each_netdev(net, dev) { - if (dev->flags & IFF_UP) { - nb->notifier_call(nb, NETDEV_GOING_DOWN, dev); - nb->notifier_call(nb, NETDEV_DOWN, dev); - } - nb->notifier_call(nb, NETDEV_UNREGISTER, dev); - nb->notifier_call(nb, NETDEV_UNREGISTER_BATCH, dev); - } - } -unlock: rtnl_unlock(); return err; } diff --git a/trunk/net/core/drop_monitor.c b/trunk/net/core/drop_monitor.c index a7cad741df01..7f36b38e060f 100644 --- a/trunk/net/core/drop_monitor.c +++ b/trunk/net/core/drop_monitor.c @@ -42,14 +42,13 @@ static void send_dm_alert(struct work_struct *unused); * netlink alerts */ static int trace_state = TRACE_OFF; -static DEFINE_MUTEX(trace_state_mutex); +static DEFINE_SPINLOCK(trace_state_lock); struct per_cpu_dm_data { struct work_struct dm_alert_work; - struct sk_buff __rcu *skb; + struct sk_buff *skb; atomic_t dm_hit_count; struct timer_list send_timer; - int cpu; }; struct dm_hw_stat_delta { @@ -80,53 +79,29 @@ static void reset_per_cpu_data(struct per_cpu_dm_data *data) size_t al; struct net_dm_alert_msg *msg; struct nlattr *nla; - struct sk_buff *skb; - struct sk_buff *oskb = rcu_dereference_protected(data->skb, 1); al = sizeof(struct net_dm_alert_msg); al += dm_hit_limit * sizeof(struct net_dm_drop_point); al += sizeof(struct nlattr); - skb = genlmsg_new(al, GFP_KERNEL); - - if (skb) { - genlmsg_put(skb, 0, 0, &net_drop_monitor_family, - 0, NET_DM_CMD_ALERT); - nla = nla_reserve(skb, NLA_UNSPEC, - sizeof(struct net_dm_alert_msg)); - msg = nla_data(nla); - memset(msg, 0, al); - } else - schedule_work_on(data->cpu, &data->dm_alert_work); - - /* - * Don't need to lock this, since we are guaranteed to only - * run this on a single cpu at a time. - * Note also that we only update data->skb if the old and new skb - * pointers don't match. This ensures that we don't continually call - * synchornize_rcu if we repeatedly fail to alloc a new netlink message. - */ - if (skb != oskb) { - rcu_assign_pointer(data->skb, skb); - - synchronize_rcu(); - - atomic_set(&data->dm_hit_count, dm_hit_limit); - } - + data->skb = genlmsg_new(al, GFP_KERNEL); + genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family, + 0, NET_DM_CMD_ALERT); + nla = nla_reserve(data->skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg)); + msg = nla_data(nla); + memset(msg, 0, al); + atomic_set(&data->dm_hit_count, dm_hit_limit); } static void send_dm_alert(struct work_struct *unused) { struct sk_buff *skb; - struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data); - - WARN_ON_ONCE(data->cpu != smp_processor_id()); + struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data); /* * Grab the skb we're about to send */ - skb = rcu_dereference_protected(data->skb, 1); + skb = data->skb; /* * Replace it with a new one @@ -136,10 +111,8 @@ static void send_dm_alert(struct work_struct *unused) /* * Ship it! */ - if (skb) - genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL); + genlmsg_multicast(skb, 0, NET_DM_GRP_ALERT, GFP_KERNEL); - put_cpu_var(dm_cpu_data); } /* @@ -150,11 +123,9 @@ static void send_dm_alert(struct work_struct *unused) */ static void sched_send_work(unsigned long unused) { - struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data); - - schedule_work_on(smp_processor_id(), &data->dm_alert_work); + struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data); - put_cpu_var(dm_cpu_data); + schedule_work(&data->dm_alert_work); } static void trace_drop_common(struct sk_buff *skb, void *location) @@ -163,15 +134,8 @@ static void trace_drop_common(struct sk_buff *skb, void *location) struct nlmsghdr *nlh; struct nlattr *nla; int i; - struct sk_buff *dskb; - struct per_cpu_dm_data *data = &get_cpu_var(dm_cpu_data); - - - rcu_read_lock(); - dskb = rcu_dereference(data->skb); + struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data); - if (!dskb) - goto out; if (!atomic_add_unless(&data->dm_hit_count, -1, 0)) { /* @@ -180,13 +144,12 @@ static void trace_drop_common(struct sk_buff *skb, void *location) goto out; } - nlh = (struct nlmsghdr *)dskb->data; + nlh = (struct nlmsghdr *)data->skb->data; nla = genlmsg_data(nlmsg_data(nlh)); msg = nla_data(nla); for (i = 0; i < msg->entries; i++) { if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) { msg->points[i].count++; - atomic_inc(&data->dm_hit_count); goto out; } } @@ -194,7 +157,7 @@ static void trace_drop_common(struct sk_buff *skb, void *location) /* * We need to create a new entry */ - __nla_reserve_nohdr(dskb, sizeof(struct net_dm_drop_point)); + __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point)); nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point)); memcpy(msg->points[msg->entries].pc, &location, sizeof(void *)); msg->points[msg->entries].count = 1; @@ -206,8 +169,6 @@ static void trace_drop_common(struct sk_buff *skb, void *location) } out: - rcu_read_unlock(); - put_cpu_var(dm_cpu_data); return; } @@ -252,7 +213,7 @@ static int set_all_monitor_traces(int state) struct dm_hw_stat_delta *new_stat = NULL; struct dm_hw_stat_delta *temp; - mutex_lock(&trace_state_mutex); + spin_lock(&trace_state_lock); if (state == trace_state) { rc = -EAGAIN; @@ -291,7 +252,7 @@ static int set_all_monitor_traces(int state) rc = -EINPROGRESS; out_unlock: - mutex_unlock(&trace_state_mutex); + spin_unlock(&trace_state_lock); return rc; } @@ -334,12 +295,12 @@ static int dropmon_net_event(struct notifier_block *ev_block, new_stat->dev = dev; new_stat->last_rx = jiffies; - mutex_lock(&trace_state_mutex); + spin_lock(&trace_state_lock); list_add_rcu(&new_stat->list, &hw_stats_list); - mutex_unlock(&trace_state_mutex); + spin_unlock(&trace_state_lock); break; case NETDEV_UNREGISTER: - mutex_lock(&trace_state_mutex); + spin_lock(&trace_state_lock); list_for_each_entry_safe(new_stat, tmp, &hw_stats_list, list) { if (new_stat->dev == dev) { new_stat->dev = NULL; @@ -350,7 +311,7 @@ static int dropmon_net_event(struct notifier_block *ev_block, } } } - mutex_unlock(&trace_state_mutex); + spin_unlock(&trace_state_lock); break; } out: @@ -406,15 +367,13 @@ static int __init init_net_drop_monitor(void) for_each_present_cpu(cpu) { data = &per_cpu(dm_cpu_data, cpu); - data->cpu = cpu; + reset_per_cpu_data(data); INIT_WORK(&data->dm_alert_work, send_dm_alert); init_timer(&data->send_timer); data->send_timer.data = cpu; data->send_timer.function = sched_send_work; - reset_per_cpu_data(data); } - goto out; out_unreg: diff --git a/trunk/net/core/net_namespace.c b/trunk/net/core/net_namespace.c index 31a5ae51a45c..0e950fda9a0a 100644 --- a/trunk/net/core/net_namespace.c +++ b/trunk/net/core/net_namespace.c @@ -83,29 +83,21 @@ static int net_assign_generic(struct net *net, int id, void *data) static int ops_init(const struct pernet_operations *ops, struct net *net) { - int err = -ENOMEM; - void *data = NULL; - + int err; if (ops->id && ops->size) { - data = kzalloc(ops->size, GFP_KERNEL); + void *data = kzalloc(ops->size, GFP_KERNEL); if (!data) - goto out; + return -ENOMEM; err = net_assign_generic(net, *ops->id, data); - if (err) - goto cleanup; + if (err) { + kfree(data); + return err; + } } - err = 0; if (ops->init) - err = ops->init(net); - if (!err) - return 0; - -cleanup: - kfree(data); - -out: - return err; + return ops->init(net); + return 0; } static void ops_free(const struct pernet_operations *ops, struct net *net) @@ -456,7 +448,12 @@ static void __unregister_pernet_operations(struct pernet_operations *ops) static int __register_pernet_operations(struct list_head *list, struct pernet_operations *ops) { - return ops_init(ops, &init_net); + int err = 0; + err = ops_init(ops, &init_net); + if (err) + ops_free(ops, &init_net); + return err; + } static void __unregister_pernet_operations(struct pernet_operations *ops) diff --git a/trunk/net/ieee802154/6lowpan.c b/trunk/net/ieee802154/6lowpan.c index 840821b90bcd..368515885368 100644 --- a/trunk/net/ieee802154/6lowpan.c +++ b/trunk/net/ieee802154/6lowpan.c @@ -1044,24 +1044,6 @@ static void lowpan_dev_free(struct net_device *dev) free_netdev(dev); } -static struct wpan_phy *lowpan_get_phy(const struct net_device *dev) -{ - struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; - return ieee802154_mlme_ops(real_dev)->get_phy(real_dev); -} - -static u16 lowpan_get_pan_id(const struct net_device *dev) -{ - struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; - return ieee802154_mlme_ops(real_dev)->get_pan_id(real_dev); -} - -static u16 lowpan_get_short_addr(const struct net_device *dev) -{ - struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; - return ieee802154_mlme_ops(real_dev)->get_short_addr(real_dev); -} - static struct header_ops lowpan_header_ops = { .create = lowpan_header_create, }; @@ -1071,12 +1053,6 @@ static const struct net_device_ops lowpan_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, }; -static struct ieee802154_mlme_ops lowpan_mlme = { - .get_pan_id = lowpan_get_pan_id, - .get_phy = lowpan_get_phy, - .get_short_addr = lowpan_get_short_addr, -}; - static void lowpan_setup(struct net_device *dev) { pr_debug("(%s)\n", __func__); @@ -1094,7 +1070,6 @@ static void lowpan_setup(struct net_device *dev) dev->netdev_ops = &lowpan_netdev_ops; dev->header_ops = &lowpan_header_ops; - dev->ml_priv = &lowpan_mlme; dev->destructor = lowpan_dev_free; } @@ -1168,8 +1143,6 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev, list_add_tail(&entry->list, &lowpan_devices); mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx); - spin_lock_init(&flist_lock); - register_netdevice(dev); return 0; @@ -1179,20 +1152,11 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head) { struct lowpan_dev_info *lowpan_dev = lowpan_dev_info(dev); struct net_device *real_dev = lowpan_dev->real_dev; - struct lowpan_dev_record *entry, *tmp; - struct lowpan_fragment *frame, *tframe; + struct lowpan_dev_record *entry; + struct lowpan_dev_record *tmp; ASSERT_RTNL(); - spin_lock(&flist_lock); - list_for_each_entry_safe(frame, tframe, &lowpan_fragments, list) { - del_timer(&frame->timer); - list_del(&frame->list); - dev_kfree_skb(frame->skb); - kfree(frame); - } - spin_unlock(&flist_lock); - mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx); list_for_each_entry_safe(entry, tmp, &lowpan_devices, list) { if (entry->ldev == dev) { diff --git a/trunk/net/ipv4/inet_diag.c b/trunk/net/ipv4/inet_diag.c index 8f8db724bfaf..8d25a1c557eb 100644 --- a/trunk/net/ipv4/inet_diag.c +++ b/trunk/net/ipv4/inet_diag.c @@ -141,7 +141,7 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, goto rtattr_failure; if (icsk == NULL) { - handler->idiag_get_info(sk, r, NULL); + r->idiag_rqueue = r->idiag_wqueue = 0; goto out; } diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 1272a88c2a63..8bb6adeb62c0 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -3243,7 +3243,7 @@ void __init tcp_init(void) { struct sk_buff *skb = NULL; unsigned long limit; - int max_rshare, max_wshare, cnt; + int max_share, cnt; unsigned int i; unsigned long jiffy = jiffies; @@ -3303,16 +3303,15 @@ void __init tcp_init(void) tcp_init_mem(&init_net); /* Set per-socket limits to no more than 1/128 the pressure threshold */ limit = nr_free_buffer_pages() << (PAGE_SHIFT - 7); - max_wshare = min(4UL*1024*1024, limit); - max_rshare = min(6UL*1024*1024, limit); + max_share = min(4UL*1024*1024, limit); sysctl_tcp_wmem[0] = SK_MEM_QUANTUM; sysctl_tcp_wmem[1] = 16*1024; - sysctl_tcp_wmem[2] = max(64*1024, max_wshare); + sysctl_tcp_wmem[2] = max(64*1024, max_share); sysctl_tcp_rmem[0] = SK_MEM_QUANTUM; sysctl_tcp_rmem[1] = 87380; - sysctl_tcp_rmem[2] = max(87380, max_rshare); + sysctl_tcp_rmem[2] = max(87380, max_share); pr_info("Hash tables configured (established %u bind %u)\n", tcp_hashinfo.ehash_mask + 1, tcp_hashinfo.bhash_size); diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 257b61789eeb..9944c1d9a218 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -85,7 +85,7 @@ int sysctl_tcp_ecn __read_mostly = 2; EXPORT_SYMBOL(sysctl_tcp_ecn); int sysctl_tcp_dsack __read_mostly = 1; int sysctl_tcp_app_win __read_mostly = 31; -int sysctl_tcp_adv_win_scale __read_mostly = 1; +int sysctl_tcp_adv_win_scale __read_mostly = 2; EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); int sysctl_tcp_stdurg __read_mostly; @@ -335,7 +335,6 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) incr = __tcp_grow_window(sk, skb); if (incr) { - incr = max_t(int, incr, 2 * skb->len); tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr, tp->window_clamp); inet_csk(sk)->icsk_ack.quick |= 1; @@ -495,7 +494,7 @@ static inline void tcp_rcv_rtt_measure(struct tcp_sock *tp) goto new_measure; if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq)) return; - tcp_rcv_rtt_update(tp, tcp_time_stamp - tp->rcv_rtt_est.time, 1); + tcp_rcv_rtt_update(tp, jiffies - tp->rcv_rtt_est.time, 1); new_measure: tp->rcv_rtt_est.seq = tp->rcv_nxt + tp->rcv_wnd; @@ -2868,14 +2867,11 @@ static inline void tcp_complete_cwr(struct sock *sk) /* Do not moderate cwnd if it's already undone in cwr or recovery. */ if (tp->undo_marker) { - if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR) { + if (inet_csk(sk)->icsk_ca_state == TCP_CA_CWR) tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh); - tp->snd_cwnd_stamp = tcp_time_stamp; - } else if (tp->snd_ssthresh < TCP_INFINITE_SSTHRESH) { - /* PRR algorithm. */ + else /* PRR */ tp->snd_cwnd = tp->snd_ssthresh; - tp->snd_cwnd_stamp = tcp_time_stamp; - } + tp->snd_cwnd_stamp = tcp_time_stamp; } tcp_ca_event(sk, CA_EVENT_COMPLETE_CWR); } diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 7ac6423117ad..376b2cfbb685 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -1096,7 +1096,6 @@ static void __pskb_trim_head(struct sk_buff *skb, int len) eat = min_t(int, len, skb_headlen(skb)); if (eat) { __skb_pull(skb, eat); - skb->avail_size -= eat; len -= eat; if (!len) return; diff --git a/trunk/net/ipv4/udp_diag.c b/trunk/net/ipv4/udp_diag.c index a7f86a3cd502..8a949f19deb6 100644 --- a/trunk/net/ipv4/udp_diag.c +++ b/trunk/net/ipv4/udp_diag.c @@ -146,17 +146,9 @@ static int udp_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr *nlh, return udp_dump_one(&udp_table, in_skb, nlh, req); } -static void udp_diag_get_info(struct sock *sk, struct inet_diag_msg *r, - void *info) -{ - r->idiag_rqueue = sk_rmem_alloc_get(sk); - r->idiag_wqueue = sk_wmem_alloc_get(sk); -} - static const struct inet_diag_handler udp_diag_handler = { .dump = udp_diag_dump, .dump_one = udp_diag_dump_one, - .idiag_get_info = udp_diag_get_info, .idiag_type = IPPROTO_UDP, }; @@ -175,7 +167,6 @@ static int udplite_diag_dump_one(struct sk_buff *in_skb, const struct nlmsghdr * static const struct inet_diag_handler udplite_diag_handler = { .dump = udplite_diag_dump, .dump_one = udplite_diag_dump_one, - .idiag_get_info = udp_diag_get_info, .idiag_type = IPPROTO_UDPLITE, }; diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index 7d5cb975cc6f..6a3bb6077e19 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -803,7 +803,8 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) ip6_del_rt(rt); rt = NULL; } else if (!(rt->rt6i_flags & RTF_EXPIRES)) { - rt6_set_expires(rt, expires); + rt->dst.expires = expires; + rt->rt6i_flags |= RTF_EXPIRES; } } dst_release(&rt->dst); @@ -1886,9 +1887,11 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) rt = NULL; } else if (addrconf_finite_timeout(rt_expires)) { /* not infinity */ - rt6_set_expires(rt, jiffies + rt_expires); + rt->dst.expires = jiffies + rt_expires; + rt->rt6i_flags |= RTF_EXPIRES; } else { - rt6_clean_expires(rt); + rt->rt6i_flags &= ~RTF_EXPIRES; + rt->dst.expires = 0; } } else if (valid_lft) { clock_t expires = 0; diff --git a/trunk/net/ipv6/ip6_fib.c b/trunk/net/ipv6/ip6_fib.c index 93717435013e..5b27fbcae346 100644 --- a/trunk/net/ipv6/ip6_fib.c +++ b/trunk/net/ipv6/ip6_fib.c @@ -673,10 +673,11 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, &rt->rt6i_gateway)) { if (!(iter->rt6i_flags & RTF_EXPIRES)) return -EEXIST; - if (!(rt->rt6i_flags & RTF_EXPIRES)) - rt6_clean_expires(iter); - else - rt6_set_expires(iter, rt->dst.expires); + iter->dst.expires = rt->dst.expires; + if (!(rt->rt6i_flags & RTF_EXPIRES)) { + iter->rt6i_flags &= ~RTF_EXPIRES; + iter->dst.expires = 0; + } return -EEXIST; } } diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index 176b469322ac..3dcdb81ec3e8 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -1264,7 +1264,8 @@ static void ndisc_router_discovery(struct sk_buff *skb) } if (rt) - rt6_set_expires(rt, jiffies + (HZ * lifetime)); + rt->dst.expires = jiffies + (HZ * lifetime); + if (ra_msg->icmph.icmp6_hop_limit) { in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit; if (rt) diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index bc4888d902b2..3992e26a6039 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -62,7 +62,7 @@ #include #endif -static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, +static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, const struct in6_addr *dest); static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie); static unsigned int ip6_default_advmss(const struct dst_entry *dst); @@ -285,10 +285,6 @@ static void ip6_dst_destroy(struct dst_entry *dst) rt->rt6i_idev = NULL; in6_dev_put(idev); } - - if (!(rt->rt6i_flags & RTF_EXPIRES) && dst->from) - dst_release(dst->from); - if (peer) { rt->rt6i_peer = NULL; inet_putpeer(peer); @@ -333,17 +329,8 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, static __inline__ int rt6_check_expired(const struct rt6_info *rt) { - struct rt6_info *ort = NULL; - - if (rt->rt6i_flags & RTF_EXPIRES) { - if (time_after(jiffies, rt->dst.expires)) - return 1; - } else if (rt->dst.from) { - ort = (struct rt6_info *) rt->dst.from; - return (ort->rt6i_flags & RTF_EXPIRES) && - time_after(jiffies, ort->dst.expires); - } - return 0; + return (rt->rt6i_flags & RTF_EXPIRES) && + time_after(jiffies, rt->dst.expires); } static inline int rt6_need_strict(const struct in6_addr *daddr) @@ -633,11 +620,12 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); if (rt) { - if (!addrconf_finite_timeout(lifetime)) - rt6_clean_expires(rt); - else - rt6_set_expires(rt, jiffies + HZ * lifetime); - + if (!addrconf_finite_timeout(lifetime)) { + rt->rt6i_flags &= ~RTF_EXPIRES; + } else { + rt->dst.expires = jiffies + HZ * lifetime; + rt->rt6i_flags |= RTF_EXPIRES; + } dst_release(&rt->dst); } return 0; @@ -742,7 +730,7 @@ int ip6_ins_rt(struct rt6_info *rt) return __ip6_ins_rt(rt, &info); } -static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, +static struct rt6_info *rt6_alloc_cow(const struct rt6_info *ort, const struct in6_addr *daddr, const struct in6_addr *saddr) { @@ -966,10 +954,10 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori rt->rt6i_idev = ort->rt6i_idev; if (rt->rt6i_idev) in6_dev_hold(rt->rt6i_idev); + rt->dst.expires = 0; rt->rt6i_gateway = ort->rt6i_gateway; - rt->rt6i_flags = ort->rt6i_flags; - rt6_clean_expires(rt); + rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; rt->rt6i_metric = 0; memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key)); @@ -1031,9 +1019,10 @@ static void ip6_link_failure(struct sk_buff *skb) rt = (struct rt6_info *) skb_dst(skb); if (rt) { - if (rt->rt6i_flags & RTF_CACHE) - rt6_update_expires(rt, 0); - else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) + if (rt->rt6i_flags & RTF_CACHE) { + dst_set_expires(&rt->dst, 0); + rt->rt6i_flags |= RTF_EXPIRES; + } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) rt->rt6i_node->fn_sernum = -1; } } @@ -1300,12 +1289,9 @@ int ip6_route_add(struct fib6_config *cfg) } rt->dst.obsolete = -1; - - if (cfg->fc_flags & RTF_EXPIRES) - rt6_set_expires(rt, jiffies + - clock_t_to_jiffies(cfg->fc_expires)); - else - rt6_clean_expires(rt); + rt->dst.expires = (cfg->fc_flags & RTF_EXPIRES) ? + jiffies + clock_t_to_jiffies(cfg->fc_expires) : + 0; if (cfg->fc_protocol == RTPROT_UNSPEC) cfg->fc_protocol = RTPROT_BOOT; @@ -1750,8 +1736,8 @@ static void rt6_do_pmtu_disc(const struct in6_addr *daddr, const struct in6_addr features |= RTAX_FEATURE_ALLFRAG; dst_metric_set(&rt->dst, RTAX_FEATURES, features); } - rt6_update_expires(rt, net->ipv6.sysctl.ip6_rt_mtu_expires); - rt->rt6i_flags |= RTF_MODIFIED; + dst_set_expires(&rt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires); + rt->rt6i_flags |= RTF_MODIFIED|RTF_EXPIRES; goto out; } @@ -1779,8 +1765,9 @@ static void rt6_do_pmtu_disc(const struct in6_addr *daddr, const struct in6_addr * which is 10 mins. After 10 mins the decreased pmtu is expired * and detecting PMTU increase will be automatically happened. */ - rt6_update_expires(nrt, net->ipv6.sysctl.ip6_rt_mtu_expires); - nrt->rt6i_flags |= RTF_DYNAMIC; + dst_set_expires(&nrt->dst, net->ipv6.sysctl.ip6_rt_mtu_expires); + nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES; + ip6_ins_rt(nrt); } out: @@ -1812,7 +1799,7 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad * Misc support functions */ -static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, +static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort, const struct in6_addr *dest) { struct net *net = dev_net(ort->dst.dev); @@ -1832,14 +1819,10 @@ static struct rt6_info *ip6_rt_copy(struct rt6_info *ort, if (rt->rt6i_idev) in6_dev_hold(rt->rt6i_idev); rt->dst.lastuse = jiffies; + rt->dst.expires = 0; rt->rt6i_gateway = ort->rt6i_gateway; - rt->rt6i_flags = ort->rt6i_flags; - if ((ort->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) == - (RTF_DEFAULT | RTF_ADDRCONF)) - rt6_set_from(rt, ort); - else - rt6_clean_expires(rt); + rt->rt6i_flags = ort->rt6i_flags & ~RTF_EXPIRES; rt->rt6i_metric = 0; #ifdef CONFIG_IPV6_SUBTREES diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index 98256cf72f9d..86cfe6005f40 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -1383,10 +1383,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, tcp_mtup_init(newsk); tcp_sync_mss(newsk, dst_mtu(dst)); newtp->advmss = dst_metric_advmss(dst); - if (tcp_sk(sk)->rx_opt.user_mss && - tcp_sk(sk)->rx_opt.user_mss < newtp->advmss) - newtp->advmss = tcp_sk(sk)->rx_opt.user_mss; - tcp_initialize_rcv_mss(newsk); if (tcp_rsk(req)->snt_synack) tcp_valid_rtt_meas(newsk, diff --git a/trunk/net/key/af_key.c b/trunk/net/key/af_key.c index 7e5d927b576f..11dbb2255ccb 100644 --- a/trunk/net/key/af_key.c +++ b/trunk/net/key/af_key.c @@ -3480,7 +3480,7 @@ static int pfkey_send_migrate(const struct xfrm_selector *sel, u8 dir, u8 type, /* Addresses to be used by KM for negotiation, if ext is available */ if (k != NULL && (set_sadb_kmaddress(skb, k) < 0)) - goto err; + return -EINVAL; /* selector src */ set_sadb_address(skb, sasize_sel, SADB_EXT_ADDRESS_SRC, sel); diff --git a/trunk/net/l2tp/l2tp_ip.c b/trunk/net/l2tp/l2tp_ip.c index 6274f0be82b0..55670ec3cd0f 100644 --- a/trunk/net/l2tp/l2tp_ip.c +++ b/trunk/net/l2tp/l2tp_ip.c @@ -232,7 +232,7 @@ static void l2tp_ip_close(struct sock *sk, long timeout) { write_lock_bh(&l2tp_ip_lock); hlist_del_init(&sk->sk_bind_node); - sk_del_node_init(sk); + hlist_del_init(&sk->sk_node); write_unlock_bh(&l2tp_ip_lock); sk_common_release(sk); } @@ -271,8 +271,7 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) chk_addr_ret != RTN_MULTICAST && chk_addr_ret != RTN_BROADCAST) goto out; - if (addr->l2tp_addr.s_addr) - inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr; + inet->inet_rcv_saddr = inet->inet_saddr = addr->l2tp_addr.s_addr; if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) inet->inet_saddr = 0; /* Use device */ sk_dst_reset(sk); @@ -442,9 +441,8 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m daddr = lip->l2tp_addr.s_addr; } else { - rc = -EDESTADDRREQ; if (sk->sk_state != TCP_ESTABLISHED) - goto out; + return -EDESTADDRREQ; daddr = inet->inet_daddr; connected = 1; diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index cef7c29214a8..33fd8d9f714e 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -457,8 +457,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, * fall back to HT20 if we don't use or use * the other extension channel */ - if (!(channel_type == NL80211_CHAN_HT40MINUS || - channel_type == NL80211_CHAN_HT40PLUS) || + if ((channel_type == NL80211_CHAN_HT40MINUS || + channel_type == NL80211_CHAN_HT40PLUS) && channel_type != sdata->u.ibss.channel_type) sta_ht_cap_new.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index db8fae51714c..d9798a307f20 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -1210,7 +1210,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata); -void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata); +void ieee80211_mgd_teardown(struct ieee80211_sub_if_data *sdata); /* IBSS code */ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index c20051b7ffcd..401c01f0731e 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -486,8 +486,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, /* free all potentially still buffered bcast frames */ local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps_bc_buf); skb_queue_purge(&sdata->u.ap.ps_bc_buf); - } else if (sdata->vif.type == NL80211_IFTYPE_STATION) { - ieee80211_mgd_stop(sdata); } if (going_down) @@ -646,6 +644,8 @@ static void ieee80211_teardown_sdata(struct net_device *dev) if (ieee80211_vif_is_mesh(&sdata->vif)) mesh_rmc_free(sdata); + else if (sdata->vif.type == NL80211_IFTYPE_STATION) + ieee80211_mgd_teardown(sdata); flushed = sta_info_flush(local, sdata); WARN_ON(flushed); diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index 20c680bfc3ae..f76da5b3f5c5 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -3497,7 +3497,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, return 0; } -void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata) +void ieee80211_mgd_teardown(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index d64e285400aa..bcfe8c77c839 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -103,7 +103,7 @@ static void ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, struct sk_buff *skb, struct ieee80211_rate *rate, - int rtap_len, bool has_fcs) + int rtap_len) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_radiotap_header *rthdr; @@ -134,7 +134,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, } /* IEEE80211_RADIOTAP_FLAGS */ - if (has_fcs && (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)) + if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) *pos |= IEEE80211_RADIOTAP_F_FCS; if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) *pos |= IEEE80211_RADIOTAP_F_BADFCS; @@ -294,8 +294,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, } /* prepend radiotap information */ - ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom, - true); + ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); skb_reset_mac_header(skb); skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -2572,8 +2571,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, goto out_free_skb; /* prepend radiotap information */ - ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom, - false); + ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); skb_set_mac_header(skb, 0); skb->ip_summed = CHECKSUM_UNNECESSARY; diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index e76facc69e95..782a60198df4 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -1158,8 +1158,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, tx->sta = rcu_dereference(sdata->u.vlan.sta); if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr) return TX_DROP; - } else if (info->flags & IEEE80211_TX_CTL_INJECTED || - tx->sdata->control_port_protocol == tx->skb->protocol) { + } else if (info->flags & IEEE80211_TX_CTL_INJECTED) { tx->sta = sta_info_get_bss(sdata, hdr->addr1); } if (!tx->sta) diff --git a/trunk/net/netfilter/ipvs/ip_vs_core.c b/trunk/net/netfilter/ipvs/ip_vs_core.c index 00bdb1d9d690..2555816e7788 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_core.c +++ b/trunk/net/netfilter/ipvs/ip_vs_core.c @@ -1924,7 +1924,6 @@ static int __net_init __ip_vs_init(struct net *net) control_fail: ip_vs_estimator_net_cleanup(net); estimator_fail: - net->ipvs = NULL; return -ENOMEM; } @@ -1937,7 +1936,6 @@ static void __net_exit __ip_vs_cleanup(struct net *net) ip_vs_control_net_cleanup(net); ip_vs_estimator_net_cleanup(net); IP_VS_DBG(2, "ipvs netns %d released\n", net_ipvs(net)->gen); - net->ipvs = NULL; } static void __net_exit __ip_vs_dev_cleanup(struct net *net) @@ -1995,18 +1993,10 @@ static int __init ip_vs_init(void) goto cleanup_dev; } - ret = ip_vs_register_nl_ioctl(); - if (ret < 0) { - pr_err("can't register netlink/ioctl.\n"); - goto cleanup_hooks; - } - pr_info("ipvs loaded.\n"); return ret; -cleanup_hooks: - nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops)); cleanup_dev: unregister_pernet_device(&ipvs_core_dev_ops); cleanup_sub: @@ -2022,7 +2012,6 @@ static int __init ip_vs_init(void) static void __exit ip_vs_cleanup(void) { - ip_vs_unregister_nl_ioctl(); nf_unregister_hooks(ip_vs_ops, ARRAY_SIZE(ip_vs_ops)); unregister_pernet_device(&ipvs_core_dev_ops); unregister_pernet_subsys(&ipvs_core_ops); /* free ip_vs struct */ diff --git a/trunk/net/netfilter/ipvs/ip_vs_ctl.c b/trunk/net/netfilter/ipvs/ip_vs_ctl.c index f5589987fc80..b3afe189af61 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_ctl.c +++ b/trunk/net/netfilter/ipvs/ip_vs_ctl.c @@ -3680,7 +3680,7 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net) return 0; } -void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) +void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net) { struct netns_ipvs *ipvs = net_ipvs(net); @@ -3692,7 +3692,7 @@ void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) #else int __net_init ip_vs_control_net_init_sysctl(struct net *net) { return 0; } -void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net) { } +void __net_init ip_vs_control_net_cleanup_sysctl(struct net *net) { } #endif @@ -3750,10 +3750,21 @@ void __net_exit ip_vs_control_net_cleanup(struct net *net) free_percpu(ipvs->tot_stats.cpustats); } -int __init ip_vs_register_nl_ioctl(void) +int __init ip_vs_control_init(void) { + int idx; int ret; + EnterFunction(2); + + /* Initialize svc_table, ip_vs_svc_fwm_table, rs_table */ + for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { + INIT_LIST_HEAD(&ip_vs_svc_table[idx]); + INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]); + } + + smp_wmb(); /* Do we really need it now ? */ + ret = nf_register_sockopt(&ip_vs_sockopts); if (ret) { pr_err("cannot register sockopt.\n"); @@ -3765,41 +3776,20 @@ int __init ip_vs_register_nl_ioctl(void) pr_err("cannot register Generic Netlink interface.\n"); goto err_genl; } - return 0; - -err_genl: - nf_unregister_sockopt(&ip_vs_sockopts); -err_sock: - return ret; -} - -void ip_vs_unregister_nl_ioctl(void) -{ - ip_vs_genl_unregister(); - nf_unregister_sockopt(&ip_vs_sockopts); -} - -int __init ip_vs_control_init(void) -{ - int idx; - int ret; - - EnterFunction(2); - - /* Initialize svc_table, ip_vs_svc_fwm_table, rs_table */ - for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { - INIT_LIST_HEAD(&ip_vs_svc_table[idx]); - INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]); - } - - smp_wmb(); /* Do we really need it now ? */ ret = register_netdevice_notifier(&ip_vs_dst_notifier); if (ret < 0) - return ret; + goto err_notf; LeaveFunction(2); return 0; + +err_notf: + ip_vs_genl_unregister(); +err_genl: + nf_unregister_sockopt(&ip_vs_sockopts); +err_sock: + return ret; } @@ -3807,5 +3797,7 @@ void ip_vs_control_cleanup(void) { EnterFunction(2); unregister_netdevice_notifier(&ip_vs_dst_notifier); + ip_vs_genl_unregister(); + nf_unregister_sockopt(&ip_vs_sockopts); LeaveFunction(2); } diff --git a/trunk/net/netfilter/ipvs/ip_vs_ftp.c b/trunk/net/netfilter/ipvs/ip_vs_ftp.c index e39f693dd3e4..538d74ee4f68 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_ftp.c +++ b/trunk/net/netfilter/ipvs/ip_vs_ftp.c @@ -439,8 +439,6 @@ static int __net_init __ip_vs_ftp_init(struct net *net) struct ip_vs_app *app; struct netns_ipvs *ipvs = net_ipvs(net); - if (!ipvs) - return -ENOENT; app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL); if (!app) return -ENOMEM; diff --git a/trunk/net/netfilter/ipvs/ip_vs_lblc.c b/trunk/net/netfilter/ipvs/ip_vs_lblc.c index caa43704e55e..0f16283fd058 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_lblc.c +++ b/trunk/net/netfilter/ipvs/ip_vs_lblc.c @@ -551,9 +551,6 @@ static int __net_init __ip_vs_lblc_init(struct net *net) { struct netns_ipvs *ipvs = net_ipvs(net); - if (!ipvs) - return -ENOENT; - if (!net_eq(net, &init_net)) { ipvs->lblc_ctl_table = kmemdup(vs_vars_table, sizeof(vs_vars_table), diff --git a/trunk/net/netfilter/ipvs/ip_vs_lblcr.c b/trunk/net/netfilter/ipvs/ip_vs_lblcr.c index 548bf37aa29e..eec797f8cce7 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_lblcr.c +++ b/trunk/net/netfilter/ipvs/ip_vs_lblcr.c @@ -745,9 +745,6 @@ static int __net_init __ip_vs_lblcr_init(struct net *net) { struct netns_ipvs *ipvs = net_ipvs(net); - if (!ipvs) - return -ENOENT; - if (!net_eq(net, &init_net)) { ipvs->lblcr_ctl_table = kmemdup(vs_vars_table, sizeof(vs_vars_table), diff --git a/trunk/net/netfilter/ipvs/ip_vs_proto.c b/trunk/net/netfilter/ipvs/ip_vs_proto.c index ed835e67a07e..f843a8833250 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_proto.c +++ b/trunk/net/netfilter/ipvs/ip_vs_proto.c @@ -59,6 +59,9 @@ static int __used __init register_ip_vs_protocol(struct ip_vs_protocol *pp) return 0; } +#if defined(CONFIG_IP_VS_PROTO_TCP) || defined(CONFIG_IP_VS_PROTO_UDP) || \ + defined(CONFIG_IP_VS_PROTO_SCTP) || defined(CONFIG_IP_VS_PROTO_AH) || \ + defined(CONFIG_IP_VS_PROTO_ESP) /* * register an ipvs protocols netns related data */ @@ -78,18 +81,12 @@ register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp) ipvs->proto_data_table[hash] = pd; atomic_set(&pd->appcnt, 0); /* Init app counter */ - if (pp->init_netns != NULL) { - int ret = pp->init_netns(net, pd); - if (ret) { - /* unlink an free proto data */ - ipvs->proto_data_table[hash] = pd->next; - kfree(pd); - return ret; - } - } + if (pp->init_netns != NULL) + pp->init_netns(net, pd); return 0; } +#endif /* * unregister an ipvs protocol @@ -319,35 +316,22 @@ ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp, */ int __net_init ip_vs_protocol_net_init(struct net *net) { - int i, ret; - static struct ip_vs_protocol *protos[] = { #ifdef CONFIG_IP_VS_PROTO_TCP - &ip_vs_protocol_tcp, + register_ip_vs_proto_netns(net, &ip_vs_protocol_tcp); #endif #ifdef CONFIG_IP_VS_PROTO_UDP - &ip_vs_protocol_udp, + register_ip_vs_proto_netns(net, &ip_vs_protocol_udp); #endif #ifdef CONFIG_IP_VS_PROTO_SCTP - &ip_vs_protocol_sctp, + register_ip_vs_proto_netns(net, &ip_vs_protocol_sctp); #endif #ifdef CONFIG_IP_VS_PROTO_AH - &ip_vs_protocol_ah, + register_ip_vs_proto_netns(net, &ip_vs_protocol_ah); #endif #ifdef CONFIG_IP_VS_PROTO_ESP - &ip_vs_protocol_esp, + register_ip_vs_proto_netns(net, &ip_vs_protocol_esp); #endif - }; - - for (i = 0; i < ARRAY_SIZE(protos); i++) { - ret = register_ip_vs_proto_netns(net, protos[i]); - if (ret < 0) - goto cleanup; - } return 0; - -cleanup: - ip_vs_protocol_net_cleanup(net); - return ret; } void __net_exit ip_vs_protocol_net_cleanup(struct net *net) diff --git a/trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c b/trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c index 9f3fb751c491..1fbf7a2816f5 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/trunk/net/netfilter/ipvs/ip_vs_proto_sctp.c @@ -1090,7 +1090,7 @@ static int sctp_app_conn_bind(struct ip_vs_conn *cp) * timeouts is netns related now. * --------------------------------------------- */ -static int __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd) +static void __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd) { struct netns_ipvs *ipvs = net_ipvs(net); @@ -1098,9 +1098,6 @@ static int __ip_vs_sctp_init(struct net *net, struct ip_vs_proto_data *pd) spin_lock_init(&ipvs->sctp_app_lock); pd->timeout_table = ip_vs_create_timeout_table((int *)sctp_timeouts, sizeof(sctp_timeouts)); - if (!pd->timeout_table) - return -ENOMEM; - return 0; } static void __ip_vs_sctp_exit(struct net *net, struct ip_vs_proto_data *pd) diff --git a/trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c b/trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c index cd609cc62721..ef8641f7af83 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c +++ b/trunk/net/netfilter/ipvs/ip_vs_proto_tcp.c @@ -677,7 +677,7 @@ void ip_vs_tcp_conn_listen(struct net *net, struct ip_vs_conn *cp) * timeouts is netns related now. * --------------------------------------------- */ -static int __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd) +static void __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd) { struct netns_ipvs *ipvs = net_ipvs(net); @@ -685,10 +685,7 @@ static int __ip_vs_tcp_init(struct net *net, struct ip_vs_proto_data *pd) spin_lock_init(&ipvs->tcp_app_lock); pd->timeout_table = ip_vs_create_timeout_table((int *)tcp_timeouts, sizeof(tcp_timeouts)); - if (!pd->timeout_table) - return -ENOMEM; pd->tcp_state_table = tcp_states; - return 0; } static void __ip_vs_tcp_exit(struct net *net, struct ip_vs_proto_data *pd) diff --git a/trunk/net/netfilter/ipvs/ip_vs_proto_udp.c b/trunk/net/netfilter/ipvs/ip_vs_proto_udp.c index 2fedb2dcb3d1..f4b7262896bb 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_proto_udp.c +++ b/trunk/net/netfilter/ipvs/ip_vs_proto_udp.c @@ -467,7 +467,7 @@ udp_state_transition(struct ip_vs_conn *cp, int direction, cp->timeout = pd->timeout_table[IP_VS_UDP_S_NORMAL]; } -static int __udp_init(struct net *net, struct ip_vs_proto_data *pd) +static void __udp_init(struct net *net, struct ip_vs_proto_data *pd) { struct netns_ipvs *ipvs = net_ipvs(net); @@ -475,9 +475,6 @@ static int __udp_init(struct net *net, struct ip_vs_proto_data *pd) spin_lock_init(&ipvs->udp_app_lock); pd->timeout_table = ip_vs_create_timeout_table((int *)udp_timeouts, sizeof(udp_timeouts)); - if (!pd->timeout_table) - return -ENOMEM; - return 0; } static void __udp_exit(struct net *net, struct ip_vs_proto_data *pd) diff --git a/trunk/net/netfilter/xt_CT.c b/trunk/net/netfilter/xt_CT.c index 3746d8b9a478..59530e93fa58 100644 --- a/trunk/net/netfilter/xt_CT.c +++ b/trunk/net/netfilter/xt_CT.c @@ -227,7 +227,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) } #ifdef CONFIG_NF_CONNTRACK_TIMEOUT - if (info->timeout[0]) { + if (info->timeout) { typeof(nf_ct_timeout_find_get_hook) timeout_find_get; struct nf_conn_timeout *timeout_ext; diff --git a/trunk/net/phonet/pn_dev.c b/trunk/net/phonet/pn_dev.c index bf5cf69c820a..9b9a85ecc4c7 100644 --- a/trunk/net/phonet/pn_dev.c +++ b/trunk/net/phonet/pn_dev.c @@ -331,6 +331,23 @@ static int __net_init phonet_init_net(struct net *net) static void __net_exit phonet_exit_net(struct net *net) { + struct phonet_net *pnn = phonet_pernet(net); + struct net_device *dev; + unsigned i; + + rtnl_lock(); + for_each_netdev(net, dev) + phonet_device_destroy(dev); + + for (i = 0; i < 64; i++) { + dev = pnn->routes.table[i]; + if (dev) { + rtm_phonet_notify(RTM_DELROUTE, dev, i); + dev_put(dev); + } + } + rtnl_unlock(); + proc_net_remove(net, "phonet"); } @@ -344,7 +361,7 @@ static struct pernet_operations phonet_net_ops = { /* Initialize Phonet devices list */ int __init phonet_device_init(void) { - int err = register_pernet_subsys(&phonet_net_ops); + int err = register_pernet_device(&phonet_net_ops); if (err) return err; @@ -360,7 +377,7 @@ void phonet_device_exit(void) { rtnl_unregister_all(PF_PHONET); unregister_netdevice_notifier(&phonet_device_notifier); - unregister_pernet_subsys(&phonet_net_ops); + unregister_pernet_device(&phonet_net_ops); proc_net_remove(&init_net, "pnresource"); } diff --git a/trunk/net/sched/sch_gred.c b/trunk/net/sched/sch_gred.c index 8179494c269a..0b15236be7b6 100644 --- a/trunk/net/sched/sch_gred.c +++ b/trunk/net/sched/sch_gred.c @@ -565,8 +565,11 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) opt.packets = q->packetsin; opt.bytesin = q->bytesin; - if (gred_wred_mode(table)) - gred_load_wred_set(table, q); + if (gred_wred_mode(table)) { + q->vars.qidlestart = + table->tab[table->def]->vars.qidlestart; + q->vars.qavg = table->tab[table->def]->vars.qavg; + } opt.qave = red_calc_qavg(&q->parms, &q->vars, q->vars.qavg); diff --git a/trunk/net/sched/sch_netem.c b/trunk/net/sched/sch_netem.c index ebd22966f748..5da548fa7ae9 100644 --- a/trunk/net/sched/sch_netem.c +++ b/trunk/net/sched/sch_netem.c @@ -408,8 +408,10 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) if (q->corrupt && q->corrupt >= get_crandom(&q->corrupt_cor)) { if (!(skb = skb_unshare(skb, GFP_ATOMIC)) || (skb->ip_summed == CHECKSUM_PARTIAL && - skb_checksum_help(skb))) - return qdisc_drop(skb, sch); + skb_checksum_help(skb))) { + sch->qstats.drops++; + return NET_XMIT_DROP; + } skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8); } diff --git a/trunk/net/sunrpc/clnt.c b/trunk/net/sunrpc/clnt.c index adf2990acebf..67972462a543 100644 --- a/trunk/net/sunrpc/clnt.c +++ b/trunk/net/sunrpc/clnt.c @@ -176,22 +176,16 @@ rpc_setup_pipedir(struct rpc_clnt *clnt, const char *dir_name) return 0; } -static inline int rpc_clnt_skip_event(struct rpc_clnt *clnt, unsigned long event) -{ - if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) || - ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry)) - return 1; - return 0; -} - -static int __rpc_clnt_handle_event(struct rpc_clnt *clnt, unsigned long event, - struct super_block *sb) +static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event, + struct super_block *sb) { struct dentry *dentry; int err = 0; switch (event) { case RPC_PIPEFS_MOUNT: + if (clnt->cl_program->pipe_dir_name == NULL) + break; dentry = rpc_setup_pipedir_sb(sb, clnt, clnt->cl_program->pipe_dir_name); BUG_ON(dentry == NULL); @@ -214,20 +208,6 @@ static int __rpc_clnt_handle_event(struct rpc_clnt *clnt, unsigned long event, return err; } -static int __rpc_pipefs_event(struct rpc_clnt *clnt, unsigned long event, - struct super_block *sb) -{ - int error = 0; - - for (;; clnt = clnt->cl_parent) { - if (!rpc_clnt_skip_event(clnt, event)) - error = __rpc_clnt_handle_event(clnt, event, sb); - if (error || clnt == clnt->cl_parent) - break; - } - return error; -} - static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event) { struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); @@ -235,12 +215,10 @@ static struct rpc_clnt *rpc_get_client_for_event(struct net *net, int event) spin_lock(&sn->rpc_client_lock); list_for_each_entry(clnt, &sn->all_clients, cl_clients) { - if (clnt->cl_program->pipe_dir_name == NULL) - break; - if (rpc_clnt_skip_event(clnt, event)) - continue; - if (atomic_inc_not_zero(&clnt->cl_count) == 0) + if (((event == RPC_PIPEFS_MOUNT) && clnt->cl_dentry) || + ((event == RPC_PIPEFS_UMOUNT) && !clnt->cl_dentry)) continue; + atomic_inc(&clnt->cl_count); spin_unlock(&sn->rpc_client_lock); return clnt; } @@ -279,14 +257,6 @@ void rpc_clients_notifier_unregister(void) return rpc_pipefs_notifier_unregister(&rpc_clients_block); } -static void rpc_clnt_set_nodename(struct rpc_clnt *clnt, const char *nodename) -{ - clnt->cl_nodelen = strlen(nodename); - if (clnt->cl_nodelen > UNX_MAXNODENAME) - clnt->cl_nodelen = UNX_MAXNODENAME; - memcpy(clnt->cl_nodename, nodename, clnt->cl_nodelen); -} - static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, struct rpc_xprt *xprt) { const struct rpc_program *program = args->program; @@ -367,7 +337,10 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru } /* save the nodename */ - rpc_clnt_set_nodename(clnt, utsname()->nodename); + clnt->cl_nodelen = strlen(init_utsname()->nodename); + if (clnt->cl_nodelen > UNX_MAXNODENAME) + clnt->cl_nodelen = UNX_MAXNODENAME; + memcpy(clnt->cl_nodename, init_utsname()->nodename, clnt->cl_nodelen); rpc_register_client(clnt); return clnt; @@ -526,7 +499,6 @@ rpc_clone_client(struct rpc_clnt *clnt) err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name); if (err != 0) goto out_no_path; - rpc_clnt_set_nodename(new, utsname()->nodename); if (new->cl_auth) atomic_inc(&new->cl_auth->au_count); atomic_inc(&clnt->cl_count); diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index 3b62cf288031..0af37fc46818 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -1126,20 +1126,19 @@ rpc_fill_super(struct super_block *sb, void *data, int silent) return -ENOMEM; dprintk("RPC: sending pipefs MOUNT notification for net %p%s\n", net, NET_NAME(net)); - sn->pipefs_sb = sb; err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list, RPC_PIPEFS_MOUNT, sb); if (err) goto err_depopulate; sb->s_fs_info = get_net(net); + sn->pipefs_sb = sb; return 0; err_depopulate: blocking_notifier_call_chain(&rpc_pipefs_notifier_list, RPC_PIPEFS_UMOUNT, sb); - sn->pipefs_sb = NULL; __rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF); return err; } diff --git a/trunk/net/sunrpc/sunrpc_syms.c b/trunk/net/sunrpc/sunrpc_syms.c index 3d6498af9adc..8adfc88e793a 100644 --- a/trunk/net/sunrpc/sunrpc_syms.c +++ b/trunk/net/sunrpc/sunrpc_syms.c @@ -75,20 +75,19 @@ static struct pernet_operations sunrpc_net_ops = { static int __init init_sunrpc(void) { - int err = rpc_init_mempool(); + int err = register_rpc_pipefs(); if (err) goto out; - err = rpcauth_init_module(); + err = rpc_init_mempool(); if (err) goto out2; + err = rpcauth_init_module(); + if (err) + goto out3; cache_initialize(); err = register_pernet_subsys(&sunrpc_net_ops); - if (err) - goto out3; - - err = register_rpc_pipefs(); if (err) goto out4; #ifdef RPC_DEBUG @@ -99,11 +98,11 @@ init_sunrpc(void) return 0; out4: - unregister_pernet_subsys(&sunrpc_net_ops); -out3: rpcauth_remove_module(); -out2: +out3: rpc_destroy_mempool(); +out2: + unregister_rpc_pipefs(); out: return err; } diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c index 957f25621617..1b7a08df933c 100644 --- a/trunk/net/wireless/util.c +++ b/trunk/net/wireless/util.c @@ -989,7 +989,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, if (rdev->wiphy.software_iftypes & BIT(iftype)) continue; for (j = 0; j < c->n_limits; j++) { - if (!(limits[j].types & BIT(iftype))) + if (!(limits[j].types & iftype)) continue; if (limits[j].max < num[iftype]) goto cont; diff --git a/trunk/scripts/checkpatch.pl b/trunk/scripts/checkpatch.pl index faea0ec612bf..de639eeeed50 100755 --- a/trunk/scripts/checkpatch.pl +++ b/trunk/scripts/checkpatch.pl @@ -1869,6 +1869,12 @@ sub process { "No space is necessary after a cast\n" . $hereprev); } + if ($rawline =~ /^\+[ \t]*\/\*[ \t]*$/ && + $prevrawline =~ /^\+[ \t]*$/) { + CHK("BLOCK_COMMENT_STYLE", + "Don't begin block comments with only a /* line, use /* comment...\n" . $hereprev); + } + # check for spaces at the beginning of a line. # Exceptions: # 1) within comments diff --git a/trunk/scripts/mod/file2alias.c b/trunk/scripts/mod/file2alias.c index 44ddaa542db6..8e730ccc3f2b 100644 --- a/trunk/scripts/mod/file2alias.c +++ b/trunk/scripts/mod/file2alias.c @@ -1100,10 +1100,6 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) return; - /* We're looking for an object */ - if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) - return; - /* All our symbols are of form __mod_XXX_device_table. */ name = strstr(symname, "__mod_"); if (!name) diff --git a/trunk/scripts/xz_wrap.sh b/trunk/scripts/xz_wrap.sh index 7a2d372f4885..17a5798c29da 100644 --- a/trunk/scripts/xz_wrap.sh +++ b/trunk/scripts/xz_wrap.sh @@ -12,8 +12,8 @@ BCJ= LZMA2OPTS= -case $SRCARCH in - x86) BCJ=--x86 ;; +case $ARCH in + x86|x86_64) BCJ=--x86 ;; powerpc) BCJ=--powerpc ;; ia64) BCJ=--ia64; LZMA2OPTS=pb=4 ;; arm) BCJ=--arm ;; diff --git a/trunk/security/commoncap.c b/trunk/security/commoncap.c index 71a166a05975..0cf4b53480a7 100644 --- a/trunk/security/commoncap.c +++ b/trunk/security/commoncap.c @@ -29,7 +29,6 @@ #include #include #include -#include /* * If a non-root user executes a setuid-root binary in @@ -506,11 +505,6 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) } skip: - /* if we have fs caps, clear dangerous personality flags */ - if (!cap_issubset(new->cap_permitted, old->cap_permitted)) - bprm->per_clear |= PER_CLEAR_ON_SETID; - - /* Don't let someone trace a set[ug]id/setpcap binary with the revised * credentials unless they have the appropriate permit */ diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index 45c32f074166..10056f2f6df3 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -3640,38 +3640,8 @@ struct security_operations smack_ops = { }; -static __init void init_smack_known_list(void) +static __init void init_smack_know_list(void) { - /* - * Initialize CIPSO locks - */ - spin_lock_init(&smack_known_huh.smk_cipsolock); - spin_lock_init(&smack_known_hat.smk_cipsolock); - spin_lock_init(&smack_known_star.smk_cipsolock); - spin_lock_init(&smack_known_floor.smk_cipsolock); - spin_lock_init(&smack_known_invalid.smk_cipsolock); - spin_lock_init(&smack_known_web.smk_cipsolock); - /* - * Initialize rule list locks - */ - mutex_init(&smack_known_huh.smk_rules_lock); - mutex_init(&smack_known_hat.smk_rules_lock); - mutex_init(&smack_known_floor.smk_rules_lock); - mutex_init(&smack_known_star.smk_rules_lock); - mutex_init(&smack_known_invalid.smk_rules_lock); - mutex_init(&smack_known_web.smk_rules_lock); - /* - * Initialize rule lists - */ - INIT_LIST_HEAD(&smack_known_huh.smk_rules); - INIT_LIST_HEAD(&smack_known_hat.smk_rules); - INIT_LIST_HEAD(&smack_known_star.smk_rules); - INIT_LIST_HEAD(&smack_known_floor.smk_rules); - INIT_LIST_HEAD(&smack_known_invalid.smk_rules); - INIT_LIST_HEAD(&smack_known_web.smk_rules); - /* - * Create the known labels list - */ list_add(&smack_known_huh.list, &smack_known_list); list_add(&smack_known_hat.list, &smack_known_list); list_add(&smack_known_star.list, &smack_known_list); @@ -3706,8 +3676,16 @@ static __init int smack_init(void) cred = (struct cred *) current->cred; cred->security = tsp; - /* initialize the smack_known_list */ - init_smack_known_list(); + /* initialize the smack_know_list */ + init_smack_know_list(); + /* + * Initialize locks + */ + spin_lock_init(&smack_known_huh.smk_cipsolock); + spin_lock_init(&smack_known_hat.smk_cipsolock); + spin_lock_init(&smack_known_star.smk_cipsolock); + spin_lock_init(&smack_known_floor.smk_cipsolock); + spin_lock_init(&smack_known_invalid.smk_cipsolock); /* * Register with LSM diff --git a/trunk/security/smack/smackfs.c b/trunk/security/smack/smackfs.c index 038811cb7e62..5c32f36ff706 100644 --- a/trunk/security/smack/smackfs.c +++ b/trunk/security/smack/smackfs.c @@ -1614,6 +1614,20 @@ static int __init init_smk_fs(void) smk_cipso_doi(); smk_unlbl_ambient(NULL); + mutex_init(&smack_known_floor.smk_rules_lock); + mutex_init(&smack_known_hat.smk_rules_lock); + mutex_init(&smack_known_huh.smk_rules_lock); + mutex_init(&smack_known_invalid.smk_rules_lock); + mutex_init(&smack_known_star.smk_rules_lock); + mutex_init(&smack_known_web.smk_rules_lock); + + INIT_LIST_HEAD(&smack_known_floor.smk_rules); + INIT_LIST_HEAD(&smack_known_hat.smk_rules); + INIT_LIST_HEAD(&smack_known_huh.smk_rules); + INIT_LIST_HEAD(&smack_known_invalid.smk_rules); + INIT_LIST_HEAD(&smack_known_star.smk_rules); + INIT_LIST_HEAD(&smack_known_web.smk_rules); + return err; } diff --git a/trunk/sound/core/vmaster.c b/trunk/sound/core/vmaster.c index 857586135d18..14a286a7bf2b 100644 --- a/trunk/sound/core/vmaster.c +++ b/trunk/sound/core/vmaster.c @@ -419,7 +419,6 @@ EXPORT_SYMBOL(snd_ctl_make_virtual_master); * snd_ctl_add_vmaster_hook - Add a hook to a vmaster control * @kcontrol: vmaster kctl element * @hook: the hook function - * @private_data: the private_data pointer to be saved * * Adds the given hook to the vmaster control element so that it's called * at each time when the value is changed. diff --git a/trunk/sound/last.c b/trunk/sound/last.c index 7ffc182e0844..bdd0857b8871 100644 --- a/trunk/sound/last.c +++ b/trunk/sound/last.c @@ -38,4 +38,4 @@ static int __init alsa_sound_last_init(void) return 0; } -late_initcall_sync(alsa_sound_last_init); +__initcall(alsa_sound_last_init); diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c index d906c5b74cf0..a36488d94aaa 100644 --- a/trunk/sound/pci/hda/patch_conexant.c +++ b/trunk/sound/pci/hda/patch_conexant.c @@ -3971,14 +3971,9 @@ static void cx_auto_init_output(struct hda_codec *codec) int i; mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids); - for (i = 0; i < cfg->hp_outs; i++) { - unsigned int val = PIN_OUT; - if (snd_hda_query_pin_caps(codec, cfg->hp_pins[i]) & - AC_PINCAP_HP_DRV) - val |= AC_PINCTL_HP_EN; + for (i = 0; i < cfg->hp_outs; i++) snd_hda_codec_write(codec, cfg->hp_pins[i], 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, val); - } + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); mute_outputs(codec, cfg->hp_outs, cfg->hp_pins); mute_outputs(codec, cfg->line_outs, cfg->line_out_pins); mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins); @@ -4396,10 +4391,8 @@ static void apply_pin_fixup(struct hda_codec *codec, enum { CXT_PINCFG_LENOVO_X200, - CXT_PINCFG_LENOVO_TP410, }; -/* ThinkPad X200 & co with cxt5051 */ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = { { 0x16, 0x042140ff }, /* HP (seq# overridden) */ { 0x17, 0x21a11000 }, /* dock-mic */ @@ -4408,33 +4401,15 @@ static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = { {} }; -/* ThinkPad 410/420/510/520, X201 & co with cxt5066 */ -static const struct cxt_pincfg cxt_pincfg_lenovo_tp410[] = { - { 0x19, 0x042110ff }, /* HP (seq# overridden) */ - { 0x1a, 0x21a190f0 }, /* dock-mic */ - { 0x1c, 0x212140ff }, /* dock-HP */ - {} -}; - static const struct cxt_pincfg *cxt_pincfg_tbl[] = { [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200, - [CXT_PINCFG_LENOVO_TP410] = cxt_pincfg_lenovo_tp410, }; -static const struct snd_pci_quirk cxt5051_fixups[] = { +static const struct snd_pci_quirk cxt_fixups[] = { SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200), {} }; -static const struct snd_pci_quirk cxt5066_fixups[] = { - SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410), - SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), - {} -}; - /* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches * can be created (bko#42825) */ @@ -4471,13 +4446,13 @@ static int patch_conexant_auto(struct hda_codec *codec) case 0x14f15051: add_cx5051_fake_mutes(codec); codec->pin_amp_workaround = 1; - apply_pin_fixup(codec, cxt5051_fixups, cxt_pincfg_tbl); break; default: codec->pin_amp_workaround = 1; - apply_pin_fixup(codec, cxt5066_fixups, cxt_pincfg_tbl); } + apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); + /* Show mute-led control only on HP laptops * This is a sort of white-list: on HP laptops, EAPD corresponds * only to the mute-LED without actualy amp function. Meanwhile, diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 818f90bc7d57..2508f8109f11 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -1445,13 +1445,6 @@ enum { ALC_FIXUP_ACT_BUILD, }; -static void alc_apply_pincfgs(struct hda_codec *codec, - const struct alc_pincfg *cfg) -{ - for (; cfg->nid; cfg++) - snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); -} - static void alc_apply_fixup(struct hda_codec *codec, int action) { struct alc_spec *spec = codec->spec; @@ -1485,7 +1478,9 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) snd_printdd(KERN_INFO "hda_codec: %s: " "Apply pincfg for %s\n", codec->chip_name, modelname); - alc_apply_pincfgs(codec, cfg); + for (; cfg->nid; cfg++) + snd_hda_codec_set_pincfg(codec, cfg->nid, + cfg->val); break; case ALC_FIXUP_VERBS: if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs) @@ -4866,7 +4861,6 @@ enum { ALC260_FIXUP_GPIO1_TOGGLE, ALC260_FIXUP_REPLACER, ALC260_FIXUP_HP_B1900, - ALC260_FIXUP_KN1, }; static void alc260_gpio1_automute(struct hda_codec *codec) @@ -4894,36 +4888,6 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, } } -static void alc260_fixup_kn1(struct hda_codec *codec, - const struct alc_fixup *fix, int action) -{ - struct alc_spec *spec = codec->spec; - static const struct alc_pincfg pincfgs[] = { - { 0x0f, 0x02214000 }, /* HP/speaker */ - { 0x12, 0x90a60160 }, /* int mic */ - { 0x13, 0x02a19000 }, /* ext mic */ - { 0x18, 0x01446000 }, /* SPDIF out */ - /* disable bogus I/O pins */ - { 0x10, 0x411111f0 }, - { 0x11, 0x411111f0 }, - { 0x14, 0x411111f0 }, - { 0x15, 0x411111f0 }, - { 0x16, 0x411111f0 }, - { 0x17, 0x411111f0 }, - { 0x19, 0x411111f0 }, - { } - }; - - switch (action) { - case ALC_FIXUP_ACT_PRE_PROBE: - alc_apply_pincfgs(codec, pincfgs); - break; - case ALC_FIXUP_ACT_PROBE: - spec->init_amp = ALC_INIT_NONE; - break; - } -} - static const struct alc_fixup alc260_fixups[] = { [ALC260_FIXUP_HP_DC5750] = { .type = ALC_FIXUP_PINS, @@ -4974,11 +4938,7 @@ static const struct alc_fixup alc260_fixups[] = { .v.func = alc260_fixup_gpio1_toggle, .chained = true, .chain_id = ALC260_FIXUP_COEF, - }, - [ALC260_FIXUP_KN1] = { - .type = ALC_FIXUP_FUNC, - .v.func = alc260_fixup_kn1, - }, + } }; static const struct snd_pci_quirk alc260_fixup_tbl[] = { @@ -4988,7 +4948,6 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), - SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), {} @@ -6109,7 +6068,6 @@ static const struct alc_fixup alc269_fixups[] = { static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), - SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index 4742cac26aa9..33a9946b492c 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -5063,11 +5063,12 @@ static void stac92xx_update_led_status(struct hda_codec *codec, int enabled) if (spec->gpio_led_polarity) muted = !muted; + /*polarity defines *not* muted state level*/ if (!spec->vref_mute_led_nid) { if (muted) - spec->gpio_data |= spec->gpio_led; + spec->gpio_data &= ~spec->gpio_led; /* orange */ else - spec->gpio_data &= ~spec->gpio_led; + spec->gpio_data |= spec->gpio_led; /* white */ stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); } else { diff --git a/trunk/sound/soc/blackfin/bf5xx-ssm2602.c b/trunk/sound/soc/blackfin/bf5xx-ssm2602.c index b39ad356b92b..df3ac73f8778 100644 --- a/trunk/sound/soc/blackfin/bf5xx-ssm2602.c +++ b/trunk/sound/soc/blackfin/bf5xx-ssm2602.c @@ -99,7 +99,6 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { .platform_name = "bfin-i2s-pcm-audio", .codec_name = "ssm2602.0-001b", .ops = &bf5xx_ssm2602_ops, - .dai_fmt = BF5XX_SSM2602_DAIFMT, }, { .name = "ssm2602", @@ -109,7 +108,6 @@ static struct snd_soc_dai_link bf5xx_ssm2602_dai[] = { .platform_name = "bfin-i2s-pcm-audio", .codec_name = "ssm2602.0-001b", .ops = &bf5xx_ssm2602_ops, - .dai_fmt = BF5XX_SSM2602_DAIFMT, }, }; diff --git a/trunk/sound/soc/codecs/Kconfig b/trunk/sound/soc/codecs/Kconfig index 59d8efaa17e9..6508e8b790bb 100644 --- a/trunk/sound/soc/codecs/Kconfig +++ b/trunk/sound/soc/codecs/Kconfig @@ -57,7 +57,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_TPA6130A2 if I2C select SND_SOC_TLV320DAC33 if I2C select SND_SOC_TWL4030 if TWL4030_CORE - select SND_SOC_TWL6040 if TWL6040_CORE + select SND_SOC_TWL6040 if TWL4030_CORE select SND_SOC_UDA134X select SND_SOC_UDA1380 if I2C select SND_SOC_WL1273 if MFD_WL1273_CORE @@ -276,6 +276,7 @@ config SND_SOC_TWL4030 tristate config SND_SOC_TWL6040 + select TWL6040_CORE tristate config SND_SOC_UDA134X diff --git a/trunk/sound/soc/codecs/cs42l73.c b/trunk/sound/soc/codecs/cs42l73.c index 07c44b71f096..78979b3e0e95 100644 --- a/trunk/sound/soc/codecs/cs42l73.c +++ b/trunk/sound/soc/codecs/cs42l73.c @@ -929,8 +929,6 @@ static int cs42l73_set_mclk(struct snd_soc_dai *dai, unsigned int freq) /* MCLKX -> MCLK */ mclkx_coeff = cs42l73_get_mclkx_coeff(freq); - if (mclkx_coeff < 0) - return mclkx_coeff; mclk = cs42l73_mclkx_coeffs[mclkx_coeff].mclkx / cs42l73_mclkx_coeffs[mclkx_coeff].ratio; diff --git a/trunk/sound/soc/codecs/tlv320aic23.c b/trunk/sound/soc/codecs/tlv320aic23.c index df1e07ffac32..16d55f91a653 100644 --- a/trunk/sound/soc/codecs/tlv320aic23.c +++ b/trunk/sound/soc/codecs/tlv320aic23.c @@ -472,7 +472,7 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai, static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0x17f; + u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0xff7f; switch (level) { case SND_SOC_BIAS_ON: @@ -491,7 +491,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_OFF: /* everything off, dac mute, inactive */ snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); - snd_soc_write(codec, TLV320AIC23_PWR, 0x1ff); + snd_soc_write(codec, TLV320AIC23_PWR, 0xffff); break; } codec->dapm.bias_level = level; diff --git a/trunk/sound/soc/codecs/twl6040.c b/trunk/sound/soc/codecs/twl6040.c index dc7509b9d53a..2d8c6b825e57 100644 --- a/trunk/sound/soc/codecs/twl6040.c +++ b/trunk/sound/soc/codecs/twl6040.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -1527,7 +1528,7 @@ static int twl6040_resume(struct snd_soc_codec *codec) static int twl6040_probe(struct snd_soc_codec *codec) { struct twl6040_data *priv; - struct twl6040_codec_data *pdata = dev_get_platdata(codec->dev); + struct twl4030_codec_data *pdata = dev_get_platdata(codec->dev); struct platform_device *pdev = container_of(codec->dev, struct platform_device, dev); int ret = 0; diff --git a/trunk/sound/soc/codecs/wm8350.c b/trunk/sound/soc/codecs/wm8350.c index aa12c6b6beeb..8c4c9591ec05 100644 --- a/trunk/sound/soc/codecs/wm8350.c +++ b/trunk/sound/soc/codecs/wm8350.c @@ -60,7 +60,7 @@ struct wm8350_jack_data { }; struct wm8350_data { - struct wm8350 *wm8350; + struct snd_soc_codec codec; struct wm8350_output out1; struct wm8350_output out2; struct wm8350_jack_data hpl; @@ -1309,7 +1309,7 @@ static void wm8350_hp_work(struct wm8350_data *priv, struct wm8350_jack_data *jack, u16 mask) { - struct wm8350 *wm8350 = priv->wm8350; + struct wm8350 *wm8350 = priv->codec.control_data; u16 reg; int report; @@ -1342,7 +1342,7 @@ static void wm8350_hpr_work(struct work_struct *work) static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) { struct wm8350_data *priv = data; - struct wm8350 *wm8350 = priv->wm8350; + struct wm8350 *wm8350 = priv->codec.control_data; struct wm8350_jack_data *jack = NULL; switch (irq - wm8350->irq_base) { @@ -1427,7 +1427,7 @@ EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); static irqreturn_t wm8350_mic_handler(int irq, void *data) { struct wm8350_data *priv = data; - struct wm8350 *wm8350 = priv->wm8350; + struct wm8350 *wm8350 = priv->codec.control_data; u16 reg; int report = 0; @@ -1536,8 +1536,6 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) return -ENOMEM; snd_soc_codec_set_drvdata(codec, priv); - priv->wm8350 = wm8350; - for (i = 0; i < ARRAY_SIZE(supply_names); i++) priv->supplies[i].supply = supply_names[i]; @@ -1546,6 +1544,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) if (ret != 0) return ret; + wm8350->codec.codec = codec; codec->control_data = wm8350; /* Put the codec into reset if it wasn't already */ diff --git a/trunk/sound/soc/codecs/wm8994.c b/trunk/sound/soc/codecs/wm8994.c index 6c1fe3afd4b5..7c49642af052 100644 --- a/trunk/sound/soc/codecs/wm8994.c +++ b/trunk/sound/soc/codecs/wm8994.c @@ -1000,170 +1000,61 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec) } } -static int aif1clk_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int late_enable_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; - struct wm8994 *control = codec->control_data; - int mask = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA; - int dac; - int adc; - int val; - - switch (control->type) { - case WM8994: - case WM8958: - mask |= WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA; - break; - default: - break; - } + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); switch (event) { case SND_SOC_DAPM_PRE_PMU: - val = snd_soc_read(codec, WM8994_AIF1_CONTROL_1); - if ((val & WM8994_AIF1ADCL_SRC) && - (val & WM8994_AIF1ADCR_SRC)) - adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA; - else if (!(val & WM8994_AIF1ADCL_SRC) && - !(val & WM8994_AIF1ADCR_SRC)) - adc = WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA; - else - adc = WM8994_AIF1ADC1R_ENA | WM8994_AIF1ADC2R_ENA | - WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC2L_ENA; - - val = snd_soc_read(codec, WM8994_AIF1_CONTROL_2); - if ((val & WM8994_AIF1DACL_SRC) && - (val & WM8994_AIF1DACR_SRC)) - dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA; - else if (!(val & WM8994_AIF1DACL_SRC) && - !(val & WM8994_AIF1DACR_SRC)) - dac = WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA; - else - dac = WM8994_AIF1DAC1R_ENA | WM8994_AIF1DAC2R_ENA | - WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC2L_ENA; - - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, - mask, adc); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, - mask, dac); - snd_soc_update_bits(codec, WM8994_CLOCKING_1, - WM8994_AIF1DSPCLK_ENA | - WM8994_SYSDSPCLK_ENA, - WM8994_AIF1DSPCLK_ENA | - WM8994_SYSDSPCLK_ENA); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, mask, - WM8994_AIF1ADC1R_ENA | - WM8994_AIF1ADC1L_ENA | - WM8994_AIF1ADC2R_ENA | - WM8994_AIF1ADC2L_ENA); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, mask, - WM8994_AIF1DAC1R_ENA | - WM8994_AIF1DAC1L_ENA | - WM8994_AIF1DAC2R_ENA | - WM8994_AIF1DAC2L_ENA); - break; - - case SND_SOC_DAPM_PRE_PMD: - case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, - mask, 0); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, - mask, 0); - - val = snd_soc_read(codec, WM8994_CLOCKING_1); - if (val & WM8994_AIF2DSPCLK_ENA) - val = WM8994_SYSDSPCLK_ENA; - else - val = 0; - snd_soc_update_bits(codec, WM8994_CLOCKING_1, - WM8994_SYSDSPCLK_ENA | - WM8994_AIF1DSPCLK_ENA, val); + if (wm8994->aif1clk_enable) { + snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, + WM8994_AIF1CLK_ENA_MASK, + WM8994_AIF1CLK_ENA); + wm8994->aif1clk_enable = 0; + } + if (wm8994->aif2clk_enable) { + snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, + WM8994_AIF2CLK_ENA_MASK, + WM8994_AIF2CLK_ENA); + wm8994->aif2clk_enable = 0; + } break; } + /* We may also have postponed startup of DSP, handle that. */ + wm8958_aif_ev(w, kcontrol, event); + return 0; } -static int aif2clk_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int late_disable_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; - int dac; - int adc; - int val; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); switch (event) { - case SND_SOC_DAPM_PRE_PMU: - val = snd_soc_read(codec, WM8994_AIF2_CONTROL_1); - if ((val & WM8994_AIF2ADCL_SRC) && - (val & WM8994_AIF2ADCR_SRC)) - adc = WM8994_AIF2ADCR_ENA; - else if (!(val & WM8994_AIF2ADCL_SRC) && - !(val & WM8994_AIF2ADCR_SRC)) - adc = WM8994_AIF2ADCL_ENA; - else - adc = WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA; - - - val = snd_soc_read(codec, WM8994_AIF2_CONTROL_2); - if ((val & WM8994_AIF2DACL_SRC) && - (val & WM8994_AIF2DACR_SRC)) - dac = WM8994_AIF2DACR_ENA; - else if (!(val & WM8994_AIF2DACL_SRC) && - !(val & WM8994_AIF2DACR_SRC)) - dac = WM8994_AIF2DACL_ENA; - else - dac = WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA; - - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, - WM8994_AIF2ADCL_ENA | - WM8994_AIF2ADCR_ENA, adc); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, - WM8994_AIF2DACL_ENA | - WM8994_AIF2DACR_ENA, dac); - snd_soc_update_bits(codec, WM8994_CLOCKING_1, - WM8994_AIF2DSPCLK_ENA | - WM8994_SYSDSPCLK_ENA, - WM8994_AIF2DSPCLK_ENA | - WM8994_SYSDSPCLK_ENA); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_4, - WM8994_AIF2ADCL_ENA | - WM8994_AIF2ADCR_ENA, - WM8994_AIF2ADCL_ENA | - WM8994_AIF2ADCR_ENA); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, - WM8994_AIF2DACL_ENA | - WM8994_AIF2DACR_ENA, - WM8994_AIF2DACL_ENA | - WM8994_AIF2DACR_ENA); - break; - - case SND_SOC_DAPM_PRE_PMD: case SND_SOC_DAPM_POST_PMD: - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, - WM8994_AIF2DACL_ENA | - WM8994_AIF2DACR_ENA, 0); - snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_5, - WM8994_AIF2ADCL_ENA | - WM8994_AIF2ADCR_ENA, 0); - - val = snd_soc_read(codec, WM8994_CLOCKING_1); - if (val & WM8994_AIF1DSPCLK_ENA) - val = WM8994_SYSDSPCLK_ENA; - else - val = 0; - snd_soc_update_bits(codec, WM8994_CLOCKING_1, - WM8994_SYSDSPCLK_ENA | - WM8994_AIF2DSPCLK_ENA, val); + if (wm8994->aif1clk_disable) { + snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, + WM8994_AIF1CLK_ENA_MASK, 0); + wm8994->aif1clk_disable = 0; + } + if (wm8994->aif2clk_disable) { + snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, + WM8994_AIF2CLK_ENA_MASK, 0); + wm8994->aif2clk_disable = 0; + } break; } return 0; } -static int aif1clk_late_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int aif1clk_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); @@ -1180,8 +1071,8 @@ static int aif1clk_late_ev(struct snd_soc_dapm_widget *w, return 0; } -static int aif2clk_late_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static int aif2clk_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); @@ -1198,63 +1089,6 @@ static int aif2clk_late_ev(struct snd_soc_dapm_widget *w, return 0; } -static int late_enable_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - if (wm8994->aif1clk_enable) { - aif1clk_ev(w, kcontrol, event); - snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, - WM8994_AIF1CLK_ENA_MASK, - WM8994_AIF1CLK_ENA); - wm8994->aif1clk_enable = 0; - } - if (wm8994->aif2clk_enable) { - aif2clk_ev(w, kcontrol, event); - snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, - WM8994_AIF2CLK_ENA_MASK, - WM8994_AIF2CLK_ENA); - wm8994->aif2clk_enable = 0; - } - break; - } - - /* We may also have postponed startup of DSP, handle that. */ - wm8958_aif_ev(w, kcontrol, event); - - return 0; -} - -static int late_disable_ev(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - - switch (event) { - case SND_SOC_DAPM_POST_PMD: - if (wm8994->aif1clk_disable) { - snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1, - WM8994_AIF1CLK_ENA_MASK, 0); - aif1clk_ev(w, kcontrol, event); - wm8994->aif1clk_disable = 0; - } - if (wm8994->aif2clk_disable) { - snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1, - WM8994_AIF2CLK_ENA_MASK, 0); - aif2clk_ev(w, kcontrol, event); - wm8994->aif2clk_disable = 0; - } - break; - } - - return 0; -} - static int adc_mux_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -1551,9 +1385,9 @@ static const struct snd_kcontrol_new aif2dacr_src_mux = SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); static const struct snd_soc_dapm_widget wm8994_lateclk_revd_widgets[] = { -SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_late_ev, +SND_SOC_DAPM_SUPPLY("AIF1CLK", SND_SOC_NOPM, 0, 0, aif1clk_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), -SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_late_ev, +SND_SOC_DAPM_SUPPLY("AIF2CLK", SND_SOC_NOPM, 0, 0, aif2clk_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_E("Late DAC1L Enable PGA", SND_SOC_NOPM, 0, 0, NULL, 0, @@ -1582,10 +1416,8 @@ SND_SOC_DAPM_POST("Late Disable PGA", late_disable_ev) }; static const struct snd_soc_dapm_widget wm8994_lateclk_widgets[] = { -SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, aif1clk_ev, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), -SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, aif2clk_ev, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0), SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0, left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)), @@ -1638,30 +1470,30 @@ SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event, SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), -SND_SOC_DAPM_SUPPLY("DSP1CLK", SND_SOC_NOPM, 3, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("DSP2CLK", SND_SOC_NOPM, 2, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("DSPINTCLK", SND_SOC_NOPM, 1, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0), SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", NULL, - 0, SND_SOC_NOPM, 9, 0), + 0, WM8994_POWER_MANAGEMENT_4, 9, 0), SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", NULL, - 0, SND_SOC_NOPM, 8, 0), + 0, WM8994_POWER_MANAGEMENT_4, 8, 0), SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0, - SND_SOC_NOPM, 9, 0, wm8958_aif_ev, + WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0, - SND_SOC_NOPM, 8, 0, wm8958_aif_ev, + WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", NULL, - 0, SND_SOC_NOPM, 11, 0), + 0, WM8994_POWER_MANAGEMENT_4, 11, 0), SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", NULL, - 0, SND_SOC_NOPM, 10, 0), + 0, WM8994_POWER_MANAGEMENT_4, 10, 0), SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0, - SND_SOC_NOPM, 11, 0, wm8958_aif_ev, + WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_IN_E("AIF1DAC2R", NULL, 0, - SND_SOC_NOPM, 10, 0, wm8958_aif_ev, + WM8994_POWER_MANAGEMENT_5, 10, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0, @@ -1688,14 +1520,14 @@ SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0, dac1r_mix, ARRAY_SIZE(dac1r_mix)), SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0, - SND_SOC_NOPM, 13, 0), + WM8994_POWER_MANAGEMENT_4, 13, 0), SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0, - SND_SOC_NOPM, 12, 0), + WM8994_POWER_MANAGEMENT_4, 12, 0), SND_SOC_DAPM_AIF_IN_E("AIF2DACL", NULL, 0, - SND_SOC_NOPM, 13, 0, wm8958_aif_ev, + WM8994_POWER_MANAGEMENT_5, 13, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0, - SND_SOC_NOPM, 12, 0, wm8958_aif_ev, + WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_AIF_IN("AIF1DACDAT", NULL, 0, SND_SOC_NOPM, 0, 0), diff --git a/trunk/sound/soc/codecs/wm_hubs.c b/trunk/sound/soc/codecs/wm_hubs.c index 6c028c470601..f13f2886339c 100644 --- a/trunk/sound/soc/codecs/wm_hubs.c +++ b/trunk/sound/soc/codecs/wm_hubs.c @@ -1035,7 +1035,7 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); - int mask, val; + int val; switch (level) { case SND_SOC_BIAS_STANDBY: @@ -1047,13 +1047,6 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_ON: /* Turn off any unneded single ended outputs */ val = 0; - mask = 0; - - if (hubs->lineout1_se) - mask |= WM8993_LINEOUT1N_ENA | WM8993_LINEOUT1P_ENA; - - if (hubs->lineout2_se) - mask |= WM8993_LINEOUT2N_ENA | WM8993_LINEOUT2P_ENA; if (hubs->lineout1_se && hubs->lineout1n_ena) val |= WM8993_LINEOUT1N_ENA; @@ -1068,7 +1061,11 @@ void wm_hubs_set_bias_level(struct snd_soc_codec *codec, val |= WM8993_LINEOUT2P_ENA; snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_3, - mask, val); + WM8993_LINEOUT1N_ENA | + WM8993_LINEOUT1P_ENA | + WM8993_LINEOUT2N_ENA | + WM8993_LINEOUT2P_ENA, + val); /* Remove the input clamps */ snd_soc_update_bits(codec, WM8993_INPUTS_CLAMP_REG, diff --git a/trunk/sound/soc/omap/Kconfig b/trunk/sound/soc/omap/Kconfig index deafbfaacdbf..e00dd0b1139c 100644 --- a/trunk/sound/soc/omap/Kconfig +++ b/trunk/sound/soc/omap/Kconfig @@ -97,7 +97,7 @@ config SND_OMAP_SOC_SDP3430 config SND_OMAP_SOC_OMAP_ABE_TWL6040 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" - depends on TWL6040_CORE && SND_OMAP_SOC && ARCH_OMAP4 + depends on TWL4030_CORE && SND_OMAP_SOC && ARCH_OMAP4 select SND_OMAP_SOC_DMIC select SND_OMAP_SOC_MCPDM select SND_SOC_TWL6040 diff --git a/trunk/sound/soc/omap/omap-pcm.c b/trunk/sound/soc/omap/omap-pcm.c index 5a649da9122a..a59bd352d342 100644 --- a/trunk/sound/soc/omap/omap-pcm.c +++ b/trunk/sound/soc/omap/omap-pcm.c @@ -401,10 +401,6 @@ static int omap_pcm_new(struct snd_soc_pcm_runtime *rtd) } out: - /* free preallocated buffers in case of error */ - if (ret) - omap_pcm_free_dma_buffers(pcm); - return ret; } diff --git a/trunk/sound/soc/samsung/s3c2412-i2s.c b/trunk/sound/soc/samsung/s3c2412-i2s.c index 79fbeea99d46..72185078ddf8 100644 --- a/trunk/sound/soc/samsung/s3c2412-i2s.c +++ b/trunk/sound/soc/samsung/s3c2412-i2s.c @@ -166,7 +166,7 @@ static struct snd_soc_dai_driver s3c2412_i2s_dai = { static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev) { - return s3c_i2sv2_register_dai(&pdev->dev, -1, &s3c2412_i2s_dai); + return snd_soc_register_dai(&pdev->dev, &s3c2412_i2s_dai); } static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev) diff --git a/trunk/sound/soc/sh/fsi.c b/trunk/sound/soc/sh/fsi.c index 74ed2dffbffd..378cc5b056d7 100644 --- a/trunk/sound/soc/sh/fsi.c +++ b/trunk/sound/soc/sh/fsi.c @@ -1001,10 +1001,11 @@ static void fsi_dma_do_tasklet(unsigned long data) sg_dma_address(&sg) = buf; sg_dma_len(&sg) = len; - desc = dmaengine_prep_slave_sg(chan, &sg, 1, dir, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + desc = chan->device->device_prep_slave_sg(chan, &sg, 1, dir, + DMA_PREP_INTERRUPT | + DMA_CTRL_ACK); if (!desc) { - dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n"); + dev_err(dai->dev, "device_prep_slave_sg() fail\n"); return; } diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index c88d9741b9e7..accdcb7d4d9d 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -3113,7 +3113,6 @@ int snd_soc_register_card(struct snd_soc_card *card) GFP_KERNEL); if (card->rtd == NULL) return -ENOMEM; - card->num_rtd = 0; card->rtd_aux = &card->rtd[card->num_links]; for (i = 0; i < card->num_links; i++) @@ -3625,10 +3624,10 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, int i, ret; num_routes = of_property_count_strings(np, propname); - if (num_routes < 0 || num_routes & 1) { + if (num_routes & 1) { dev_err(card->dev, - "Property '%s' does not exist or its length is not even\n", - propname); + "Property '%s's length is not even\n", + propname); return -EINVAL; } num_routes /= 2; diff --git a/trunk/sound/soc/soc-dapm.c b/trunk/sound/soc/soc-dapm.c index 1bb6d4a63cd8..5cbd2d7623b8 100644 --- a/trunk/sound/soc/soc-dapm.c +++ b/trunk/sound/soc/soc-dapm.c @@ -67,7 +67,6 @@ static int dapm_up_seq[] = { [snd_soc_dapm_out_drv] = 10, [snd_soc_dapm_hp] = 10, [snd_soc_dapm_spk] = 10, - [snd_soc_dapm_line] = 10, [snd_soc_dapm_post] = 11, }; @@ -76,7 +75,6 @@ static int dapm_down_seq[] = { [snd_soc_dapm_adc] = 1, [snd_soc_dapm_hp] = 2, [snd_soc_dapm_spk] = 2, - [snd_soc_dapm_line] = 2, [snd_soc_dapm_out_drv] = 2, [snd_soc_dapm_pga] = 4, [snd_soc_dapm_mixer_named_ctl] = 5, diff --git a/trunk/tools/perf/.gitignore b/trunk/tools/perf/.gitignore index 26b823b61aa1..416684be0ad3 100644 --- a/trunk/tools/perf/.gitignore +++ b/trunk/tools/perf/.gitignore @@ -19,5 +19,3 @@ TAGS cscope* config.mak config.mak.autogen -*-bison.* -*-flex.* diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 9bf3fc759344..820371f10d1b 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -234,23 +234,24 @@ endif export PERL_PATH -FLEX = flex -BISON= bison +FLEX = $(CROSS_COMPILE)flex +BISON= $(CROSS_COMPILE)bison -$(OUTPUT)util/parse-events-flex.c: util/parse-events.l +event-parser: + $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c -$(OUTPUT)util/parse-events-bison.c: util/parse-events.y - $(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c +$(OUTPUT)util/parse-events-flex.c: event-parser +$(OUTPUT)util/parse-events-bison.c: event-parser -$(OUTPUT)util/pmu-flex.c: util/pmu.l +pmu-parser: + $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c -$(OUTPUT)util/pmu-bison.c: util/pmu.y - $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c +$(OUTPUT)util/pmu-flex.c: pmu-parser +$(OUTPUT)util/pmu-bison.c: pmu-parser -$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c -$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c +$(OUTPUT)util/parse-events.o: event-parser pmu-parser LIB_FILE=$(OUTPUT)libperf.a @@ -526,7 +527,7 @@ else endif ifdef NO_GTK2 - BASIC_CFLAGS += -DNO_GTK2_SUPPORT + BASIC_CFLAGS += -DNO_GTK2 else FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0) ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2)),y) @@ -851,6 +852,8 @@ help: @echo ' html - make html documentation' @echo ' info - make GNU info documentation (access with info )' @echo ' pdf - make pdf documentation' + @echo ' event-parser - make event parser code' + @echo ' pmu-parser - make pmu format parser code' @echo ' TAGS - use etags to make tag information for source browsing' @echo ' tags - use ctags to make tag information for source browsing' @echo ' cscope - use cscope to make interactive browsing database' diff --git a/trunk/tools/perf/builtin-report.c b/trunk/tools/perf/builtin-report.c index cdae9b2db1cc..2e317438980b 100644 --- a/trunk/tools/perf/builtin-report.c +++ b/trunk/tools/perf/builtin-report.c @@ -374,23 +374,16 @@ static int __cmd_report(struct perf_report *rep) (kernel_map->dso->hit && (kernel_kmap->ref_reloc_sym == NULL || kernel_kmap->ref_reloc_sym->addr == 0))) { - const char *desc = - "As no suitable kallsyms nor vmlinux was found, kernel samples\n" - "can't be resolved."; - - if (kernel_map) { - const struct dso *kdso = kernel_map->dso; - if (!RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION])) { - desc = "If some relocation was applied (e.g. " - "kexec) symbols may be misresolved."; - } - } + const struct dso *kdso = kernel_map->dso; ui__warning( "Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n" "Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n" "Samples in kernel modules can't be resolved as well.\n\n", - desc); + RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION]) ? +"As no suitable kallsyms nor vmlinux was found, kernel samples\n" +"can't be resolved." : +"If some relocation was applied (e.g. kexec) symbols may be misresolved."); } if (dump_trace) { diff --git a/trunk/tools/perf/builtin-test.c b/trunk/tools/perf/builtin-test.c index 223ffdcc0fd8..1c5b9801ac61 100644 --- a/trunk/tools/perf/builtin-test.c +++ b/trunk/tools/perf/builtin-test.c @@ -851,28 +851,6 @@ static int test__checkevent_symbolic_name_modifier(struct perf_evlist *evlist) return test__checkevent_symbolic_name(evlist); } -static int test__checkevent_exclude_host_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = list_entry(evlist->entries.next, - struct perf_evsel, node); - - TEST_ASSERT_VAL("wrong exclude guest", !evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", evsel->attr.exclude_host); - - return test__checkevent_symbolic_name(evlist); -} - -static int test__checkevent_exclude_guest_modifier(struct perf_evlist *evlist) -{ - struct perf_evsel *evsel = list_entry(evlist->entries.next, - struct perf_evsel, node); - - TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest); - TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host); - - return test__checkevent_symbolic_name(evlist); -} - static int test__checkevent_symbolic_alias_modifier(struct perf_evlist *evlist) { struct perf_evsel *evsel = list_entry(evlist->entries.next, @@ -1113,14 +1091,6 @@ static struct test__event_st { .name = "r1,syscalls:sys_enter_open:k,1:1:hp", .check = test__checkevent_list, }, - { - .name = "instructions:G", - .check = test__checkevent_exclude_host_modifier, - }, - { - .name = "instructions:H", - .check = test__checkevent_exclude_guest_modifier, - }, }; #define TEST__EVENTS_CNT (sizeof(test__events) / sizeof(struct test__event_st)) diff --git a/trunk/tools/perf/perf-archive.sh b/trunk/tools/perf/perf-archive.sh index 95b6f8b6177a..677e59d62a8d 100644 --- a/trunk/tools/perf/perf-archive.sh +++ b/trunk/tools/perf/perf-archive.sh @@ -29,14 +29,13 @@ if [ ! -s $BUILDIDS ] ; then fi MANIFEST=$(mktemp /tmp/perf-archive-manifest.XXXXXX) -PERF_BUILDID_LINKDIR=$(readlink -f $PERF_BUILDID_DIR)/ cut -d ' ' -f 1 $BUILDIDS | \ while read build_id ; do linkname=$PERF_BUILDID_DIR.build-id/${build_id:0:2}/${build_id:2} filename=$(readlink -f $linkname) echo ${linkname#$PERF_BUILDID_DIR} >> $MANIFEST - echo ${filename#$PERF_BUILDID_LINKDIR} >> $MANIFEST + echo ${filename#$PERF_BUILDID_DIR} >> $MANIFEST done tar cfj $PERF_DATA.tar.bz2 -C $PERF_BUILDID_DIR -T $MANIFEST diff --git a/trunk/tools/perf/util/parse-events.l b/trunk/tools/perf/util/parse-events.l index 1fcf1bbc5458..05d766e3ecb5 100644 --- a/trunk/tools/perf/util/parse-events.l +++ b/trunk/tools/perf/util/parse-events.l @@ -54,7 +54,7 @@ num_dec [0-9]+ num_hex 0x[a-fA-F0-9]+ num_raw_hex [a-fA-F0-9]+ name [a-zA-Z_*?][a-zA-Z0-9_*?]* -modifier_event [ukhpGH]{1,8} +modifier_event [ukhp]{1,5} modifier_bp [rwx] %% diff --git a/trunk/tools/perf/util/session.c b/trunk/tools/perf/util/session.c index 1efd3bee6336..00923cda4d9c 100644 --- a/trunk/tools/perf/util/session.c +++ b/trunk/tools/perf/util/session.c @@ -876,11 +876,11 @@ static int perf_session_deliver_event(struct perf_session *session, dump_sample(session, event, sample); if (evsel == NULL) { ++session->hists.stats.nr_unknown_id; - return 0; + return -1; } if (machine == NULL) { ++session->hists.stats.nr_unprocessable_samples; - return 0; + return -1; } return tool->sample(tool, event, sample, evsel, machine); case PERF_RECORD_MMAP: diff --git a/trunk/tools/perf/util/symbol.c b/trunk/tools/perf/util/symbol.c index ab9867b2b433..c0a028c3ebaf 100644 --- a/trunk/tools/perf/util/symbol.c +++ b/trunk/tools/perf/util/symbol.c @@ -977,9 +977,8 @@ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, * And always look at the original dso, not at debuginfo packages, that * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS). */ -static int -dso__synthesize_plt_symbols(struct dso *dso, char *name, struct map *map, - symbol_filter_t filter) +static int dso__synthesize_plt_symbols(struct dso *dso, struct map *map, + symbol_filter_t filter) { uint32_t nr_rel_entries, idx; GElf_Sym sym; @@ -994,7 +993,10 @@ dso__synthesize_plt_symbols(struct dso *dso, char *name, struct map *map, char sympltname[1024]; Elf *elf; int nr = 0, symidx, fd, err = 0; + char name[PATH_MAX]; + snprintf(name, sizeof(name), "%s%s", + symbol_conf.symfs, dso->long_name); fd = open(name, O_RDONLY); if (fd < 0) goto out; @@ -1701,9 +1703,8 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) continue; if (ret > 0) { - int nr_plt; - - nr_plt = dso__synthesize_plt_symbols(dso, name, map, filter); + int nr_plt = dso__synthesize_plt_symbols(dso, map, + filter); if (nr_plt > 0) ret += nr_plt; break; diff --git a/trunk/tools/testing/ktest/ktest.pl b/trunk/tools/testing/ktest/ktest.pl index 4915408f6a98..95d6a6f7c33a 100755 --- a/trunk/tools/testing/ktest/ktest.pl +++ b/trunk/tools/testing/ktest/ktest.pl @@ -183,9 +183,6 @@ # do not force reboots on config problems my $no_reboot = 1; -# reboot on success -my $reboot_success = 0; - my %option_map = ( "MACHINE" => \$machine, "SSH_USER" => \$ssh_user, @@ -2195,7 +2192,7 @@ sub run_bisect { } # Are we looking for where it worked, not failed? - if ($reverse_bisect && $ret >= 0) { + if ($reverse_bisect) { $ret = !$ret; } @@ -3472,7 +3469,6 @@ sub set_test_option { # Do not reboot on failing test options $no_reboot = 1; - $reboot_success = 0; $iteration = $i; @@ -3558,11 +3554,9 @@ sub set_test_option { die "failed to checkout $checkout"; } - $no_reboot = 0; - # A test may opt to not reboot the box if ($reboot_on_success) { - $reboot_success = 1; + $no_reboot = 0; } if ($test_type eq "bisect") { @@ -3606,7 +3600,7 @@ sub set_test_option { if ($opt{"POWEROFF_ON_SUCCESS"}) { halt; -} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot && $reboot_success) { +} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) { reboot_to_good; } elsif (defined($switch_to_good)) { # still need to get to the good kernel diff --git a/trunk/virt/kvm/iommu.c b/trunk/virt/kvm/iommu.c index e9fff9830bf0..a457d2138f49 100644 --- a/trunk/virt/kvm/iommu.c +++ b/trunk/virt/kvm/iommu.c @@ -240,13 +240,9 @@ int kvm_iommu_map_guest(struct kvm *kvm) return -ENODEV; } - mutex_lock(&kvm->slots_lock); - kvm->arch.iommu_domain = iommu_domain_alloc(&pci_bus_type); - if (!kvm->arch.iommu_domain) { - r = -ENOMEM; - goto out_unlock; - } + if (!kvm->arch.iommu_domain) + return -ENOMEM; if (!allow_unsafe_assigned_interrupts && !iommu_domain_has_cap(kvm->arch.iommu_domain, @@ -257,16 +253,17 @@ int kvm_iommu_map_guest(struct kvm *kvm) " module option.\n", __func__); iommu_domain_free(kvm->arch.iommu_domain); kvm->arch.iommu_domain = NULL; - r = -EPERM; - goto out_unlock; + return -EPERM; } r = kvm_iommu_map_memslots(kvm); if (r) - kvm_iommu_unmap_memslots(kvm); + goto out_unmap; -out_unlock: - mutex_unlock(&kvm->slots_lock); + return 0; + +out_unmap: + kvm_iommu_unmap_memslots(kvm); return r; } @@ -313,11 +310,6 @@ static void kvm_iommu_put_pages(struct kvm *kvm, } } -void kvm_iommu_unmap_pages(struct kvm *kvm, struct kvm_memory_slot *slot) -{ - kvm_iommu_put_pages(kvm, slot->base_gfn, slot->npages); -} - static int kvm_iommu_unmap_memslots(struct kvm *kvm) { int idx; @@ -328,7 +320,7 @@ static int kvm_iommu_unmap_memslots(struct kvm *kvm) slots = kvm_memslots(kvm); kvm_for_each_memslot(memslot, slots) - kvm_iommu_unmap_pages(kvm, memslot); + kvm_iommu_put_pages(kvm, memslot->base_gfn, memslot->npages); srcu_read_unlock(&kvm->srcu, idx); @@ -343,11 +335,7 @@ int kvm_iommu_unmap_guest(struct kvm *kvm) if (!domain) return 0; - mutex_lock(&kvm->slots_lock); kvm_iommu_unmap_memslots(kvm); - kvm->arch.iommu_domain = NULL; - mutex_unlock(&kvm->slots_lock); - iommu_domain_free(domain); return 0; } diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index 9739b533ca2e..42b73930a6de 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -808,13 +808,12 @@ int __kvm_set_memory_region(struct kvm *kvm, if (r) goto out_free; - /* map/unmap the pages in iommu page table */ + /* map the pages in iommu page table */ if (npages) { r = kvm_iommu_map_pages(kvm, &new); if (r) goto out_free; - } else - kvm_iommu_unmap_pages(kvm, &old); + } r = -ENOMEM; slots = kmemdup(kvm->memslots, sizeof(struct kvm_memslots),