From 08998ab2cfc05f23ab4db4b786eca8f820ebdbef Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Mon, 21 Nov 2011 17:31:02 -0600 Subject: [PATCH] --- yaml --- r: 275921 b: refs/heads/master c: b59db43ad4434519feb338eacb01d77eb50825c5 h: refs/heads/master i: 275919: 93c2ffb2706ec6268104d35dec84205fd1a8784a v: v3 --- [refs] | 2 +- trunk/Documentation/DocBook/uio-howto.tmpl | 7 +- trunk/Documentation/i2c/ten-bit-addresses | 36 +- trunk/Documentation/serial/serial-rs485.txt | 14 +- trunk/MAINTAINERS | 10 +- trunk/arch/microblaze/include/asm/namei.h | 22 + trunk/arch/x86/um/asm/processor.h | 2 +- trunk/drivers/base/node.c | 14 +- trunk/drivers/gpu/drm/drm_crtc.c | 4 - trunk/drivers/gpu/drm/i915/i915_debugfs.c | 57 +-- trunk/drivers/gpu/drm/i915/i915_drv.c | 6 +- trunk/drivers/gpu/drm/i915/i915_drv.h | 19 +- trunk/drivers/gpu/drm/i915/i915_gem.c | 12 +- trunk/drivers/gpu/drm/i915/i915_irq.c | 1 - trunk/drivers/gpu/drm/i915/i915_reg.h | 21 +- trunk/drivers/gpu/drm/i915/i915_suspend.c | 2 - trunk/drivers/gpu/drm/i915/intel_display.c | 33 +- trunk/drivers/gpu/drm/i915/intel_dp.c | 411 ++++++++---------- trunk/drivers/gpu/drm/i915/intel_panel.c | 3 +- trunk/drivers/gpu/drm/radeon/evergreen_cs.c | 92 ++-- trunk/drivers/gpu/drm/radeon/r300.c | 94 ++-- trunk/drivers/gpu/drm/radeon/r600_cs.c | 26 +- trunk/drivers/gpu/drm/radeon/radeon.h | 3 +- .../drivers/gpu/drm/radeon/radeon_atombios.c | 202 +++++---- trunk/drivers/gpu/drm/radeon/radeon_cs.c | 11 +- trunk/drivers/gpu/drm/radeon/radeon_drv.c | 3 +- trunk/drivers/gpu/drm/ttm/ttm_bo.c | 8 +- trunk/drivers/gpu/vga/vgaarb.c | 18 +- trunk/drivers/i2c/algos/i2c-algo-bit.c | 4 +- trunk/drivers/i2c/i2c-core.c | 4 +- trunk/drivers/i2c/i2c-dev.c | 2 +- trunk/drivers/input/mouse/elantech.c | 26 +- trunk/drivers/input/serio/ams_delta_serio.c | 1 - trunk/drivers/input/serio/i8042-x86ia64io.h | 14 - trunk/drivers/misc/Kconfig | 15 +- trunk/drivers/misc/ad525x_dpot.h | 2 +- trunk/drivers/misc/pch_phub.c | 81 +--- trunk/drivers/misc/spear13xx_pcie_gadget.c | 2 +- trunk/drivers/of/irq.c | 14 +- trunk/drivers/regulator/tps65910-regulator.c | 14 +- trunk/drivers/staging/et131x/Kconfig | 3 +- trunk/drivers/staging/et131x/et131x.c | 12 +- trunk/drivers/staging/iio/industrialio-core.c | 10 +- trunk/drivers/staging/slicoss/Kconfig | 2 +- trunk/drivers/tty/hvc/hvc_dcc.c | 2 - trunk/drivers/tty/serial/Kconfig | 14 +- trunk/drivers/tty/serial/atmel_serial.c | 16 +- trunk/drivers/tty/serial/crisv10.c | 10 +- trunk/drivers/tty/serial/mfd.c | 4 +- trunk/drivers/tty/serial/pch_uart.c | 19 +- trunk/drivers/tty/tty_ldisc.c | 30 +- trunk/drivers/usb/class/cdc-acm.c | 8 +- trunk/drivers/usb/core/hub.c | 6 - trunk/drivers/usb/core/quirks.c | 27 -- trunk/drivers/usb/dwc3/gadget.c | 1 - trunk/drivers/usb/gadget/Kconfig | 9 +- trunk/drivers/usb/gadget/ci13xxx_msm.c | 2 - trunk/drivers/usb/gadget/ci13xxx_udc.c | 21 +- trunk/drivers/usb/gadget/f_mass_storage.c | 6 +- trunk/drivers/usb/gadget/f_midi.c | 138 +++--- trunk/drivers/usb/gadget/file_storage.c | 4 +- trunk/drivers/usb/gadget/fsl_udc_core.c | 3 +- trunk/drivers/usb/gadget/inode.c | 5 +- trunk/drivers/usb/gadget/pch_udc.c | 10 +- trunk/drivers/usb/gadget/r8a66597-udc.c | 30 +- trunk/drivers/usb/gadget/udc-core.c | 10 +- trunk/drivers/usb/host/ehci-sched.c | 15 +- trunk/drivers/usb/host/ehci-xls.c | 2 +- trunk/drivers/usb/host/ohci-at91.c | 6 - trunk/drivers/usb/host/ohci-hcd.c | 15 +- trunk/drivers/usb/host/ohci-pci.c | 26 ++ trunk/drivers/usb/host/ohci.h | 1 + trunk/drivers/usb/host/pci-quirks.c | 57 +-- trunk/drivers/usb/host/xhci-mem.c | 5 + trunk/drivers/usb/host/xhci-ring.c | 13 +- trunk/drivers/usb/host/xhci.c | 34 +- trunk/drivers/usb/musb/Kconfig | 3 +- trunk/drivers/usb/musb/am35x.c | 1 - trunk/drivers/usb/musb/da8xx.c | 1 - trunk/drivers/usb/musb/musb_core.c | 3 +- trunk/drivers/usb/musb/musb_gadget.c | 4 + trunk/drivers/usb/renesas_usbhs/common.c | 2 +- trunk/drivers/usb/renesas_usbhs/fifo.c | 4 +- trunk/drivers/usb/renesas_usbhs/mod.h | 8 +- trunk/drivers/usb/renesas_usbhs/mod_gadget.c | 4 +- trunk/drivers/usb/renesas_usbhs/mod_host.c | 63 +-- trunk/drivers/usb/serial/ark3116.c | 10 +- trunk/drivers/usb/serial/ftdi_sio.c | 14 +- trunk/drivers/usb/serial/option.c | 28 -- trunk/drivers/usb/serial/pl2303.c | 1 + trunk/drivers/usb/serial/pl2303.h | 4 + trunk/drivers/usb/storage/ene_ub6250.c | 3 +- trunk/drivers/usb/storage/protocol.c | 7 +- trunk/drivers/watchdog/Kconfig | 7 + trunk/drivers/watchdog/Makefile | 1 + trunk/drivers/watchdog/adx_wdt.c | 355 +++++++++++++++ trunk/drivers/watchdog/s3c2410_wdt.c | 4 +- trunk/drivers/watchdog/wm831x_wdt.c | 2 +- trunk/fs/btrfs/backref.c | 2 +- trunk/fs/btrfs/ctree.c | 17 +- trunk/fs/btrfs/ctree.h | 5 +- trunk/fs/btrfs/disk-io.c | 147 +------ trunk/fs/btrfs/extent-tree.c | 119 ++--- trunk/fs/btrfs/extent_io.c | 9 +- trunk/fs/btrfs/extent_io.h | 2 +- trunk/fs/btrfs/free-space-cache.c | 63 +-- trunk/fs/btrfs/inode.c | 6 +- trunk/fs/btrfs/ioctl.c | 15 +- trunk/fs/btrfs/scrub.c | 2 +- trunk/fs/btrfs/transaction.c | 8 - trunk/fs/btrfs/volumes.h | 6 - trunk/fs/ceph/dir.c | 2 +- trunk/fs/ceph/inode.c | 9 +- trunk/fs/ceph/super.c | 6 +- trunk/fs/dcache.c | 11 +- trunk/fs/ecryptfs/crypto.c | 22 +- trunk/fs/ecryptfs/ecryptfs_kernel.h | 5 +- trunk/fs/ecryptfs/inode.c | 52 ++- trunk/fs/ext4/balloc.c | 2 +- trunk/fs/ext4/inode.c | 1 - trunk/fs/ext4/super.c | 6 +- trunk/fs/minix/bitmap.c | 55 ++- trunk/fs/minix/inode.c | 25 +- trunk/fs/minix/minix.h | 11 +- trunk/fs/namespace.c | 6 +- trunk/fs/nfs/dir.c | 2 +- trunk/fs/nfs/file.c | 91 ++-- trunk/fs/nfs/inode.c | 2 +- trunk/fs/nfs/internal.h | 2 - trunk/fs/nfs/nfs3proc.c | 1 - trunk/fs/nfs/nfs4proc.c | 4 +- trunk/fs/nfs/pnfs.c | 26 +- trunk/fs/nfs/proc.c | 1 - trunk/fs/nfs/read.c | 14 +- trunk/include/drm/drm_mode.h | 2 - trunk/include/drm/radeon_drm.h | 4 - trunk/include/linux/ceph/osd_client.h | 8 +- trunk/include/linux/device.h | 2 +- trunk/include/linux/i2c.h | 3 + trunk/include/linux/init_task.h | 1 + trunk/include/linux/mfd/tps65910.h | 3 +- trunk/include/linux/nfs_fs.h | 3 - trunk/include/linux/nfs_xdr.h | 1 - trunk/include/linux/sched.h | 1 + trunk/include/linux/serial.h | 14 +- trunk/kernel/fork.c | 5 + trunk/mm/page-writeback.c | 23 +- trunk/net/ceph/osd_client.c | 2 +- trunk/net/sunrpc/xprtsock.c | 4 +- trunk/tools/testing/ktest/ktest.pl | 16 - 150 files changed, 1544 insertions(+), 1722 deletions(-) create mode 100644 trunk/arch/microblaze/include/asm/namei.h create mode 100644 trunk/drivers/watchdog/adx_wdt.c diff --git a/[refs] b/[refs] index a0e72638f89f..6ce9a2433dfd 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f10cdea68b70bd85706baed0decab59618f9c353 +refs/heads/master: b59db43ad4434519feb338eacb01d77eb50825c5 diff --git a/trunk/Documentation/DocBook/uio-howto.tmpl b/trunk/Documentation/DocBook/uio-howto.tmpl index ac3d0018140c..54883de5d5f9 100644 --- a/trunk/Documentation/DocBook/uio-howto.tmpl +++ b/trunk/Documentation/DocBook/uio-howto.tmpl @@ -520,11 +520,6 @@ Here's a description of the fields of struct uio_mem: - -const char *name: Optional. Set this to help identify -the memory region, it will show up in the corresponding sysfs node. - - int memtype: Required if the mapping is used. Set this to UIO_MEM_PHYS if you you have physical memory on your @@ -558,7 +553,7 @@ instead to remember such an address. -Please do not touch the map element of +Please do not touch the kobj element of struct uio_mem! It is used by the UIO framework to set up sysfs files for this mapping. Simply leave it alone. diff --git a/trunk/Documentation/i2c/ten-bit-addresses b/trunk/Documentation/i2c/ten-bit-addresses index cdfe13901b99..e9890709c508 100644 --- a/trunk/Documentation/i2c/ten-bit-addresses +++ b/trunk/Documentation/i2c/ten-bit-addresses @@ -1,24 +1,22 @@ The I2C protocol knows about two kinds of device addresses: normal 7 bit addresses, and an extended set of 10 bit addresses. The sets of addresses do not intersect: the 7 bit address 0x10 is not the same as the 10 bit -address 0x10 (though a single device could respond to both of them). +address 0x10 (though a single device could respond to both of them). You +select a 10 bit address by adding an extra byte after the address +byte: + S Addr7 Rd/Wr .... +becomes + S 11110 Addr10 Rd/Wr +S is the start bit, Rd/Wr the read/write bit, and if you count the number +of bits, you will see the there are 8 after the S bit for 7 bit addresses, +and 16 after the S bit for 10 bit addresses. -I2C messages to and from 10-bit address devices have a different format. -See the I2C specification for the details. +WARNING! The current 10 bit address support is EXPERIMENTAL. There are +several places in the code that will cause SEVERE PROBLEMS with 10 bit +addresses, even though there is some basic handling and hooks. Also, +almost no supported adapter handles the 10 bit addresses correctly. -The current 10 bit address support is minimal. It should work, however -you can expect some problems along the way: -* Not all bus drivers support 10-bit addresses. Some don't because the - hardware doesn't support them (SMBus doesn't require 10-bit address - support for example), some don't because nobody bothered adding the - code (or it's there but not working properly.) Software implementation - (i2c-algo-bit) is known to work. -* Some optional features do not support 10-bit addresses. This is the - case of automatic detection and instantiation of devices by their, - drivers, for example. -* Many user-space packages (for example i2c-tools) lack support for - 10-bit addresses. - -Note that 10-bit address devices are still pretty rare, so the limitations -listed above could stay for a long time, maybe even forever if nobody -needs them to be fixed. +As soon as a real 10 bit address device is spotted 'in the wild', we +can and will add proper support. Right now, 10 bit address devices +are defined by the I2C protocol, but we have never seen a single device +which supports them. diff --git a/trunk/Documentation/serial/serial-rs485.txt b/trunk/Documentation/serial/serial-rs485.txt index 41c8378c0b2f..079cb3df62cf 100644 --- a/trunk/Documentation/serial/serial-rs485.txt +++ b/trunk/Documentation/serial/serial-rs485.txt @@ -97,23 +97,15 @@ struct serial_rs485 rs485conf; - /* Enable RS485 mode: */ + /* Set RS485 mode: */ rs485conf.flags |= SER_RS485_ENABLED; - /* Set logical level for RTS pin equal to 1 when sending: */ - rs485conf.flags |= SER_RS485_RTS_ON_SEND; - /* or, set logical level for RTS pin equal to 0 when sending: */ - rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND); - - /* Set logical level for RTS pin equal to 1 after sending: */ - rs485conf.flags |= SER_RS485_RTS_AFTER_SEND; - /* or, set logical level for RTS pin equal to 0 after sending: */ - rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND); - /* Set rts delay before send, if needed: */ + rs485conf.flags |= SER_RS485_RTS_BEFORE_SEND; rs485conf.delay_rts_before_send = ...; /* Set rts delay after send, if needed: */ + rs485conf.flags |= SER_RS485_RTS_AFTER_SEND; rs485conf.delay_rts_after_send = ...; /* Set this flag if you want to receive data even whilst sending data */ diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 3523ab000f1f..29f9948b2cc0 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1789,14 +1789,6 @@ F: include/net/cfg80211.h F: net/wireless/* X: net/wireless/wext* -CHAR and MISC DRIVERS -M: Arnd Bergmann -M: Greg Kroah-Hartman -T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git -S: Maintained -F: drivers/char/* -F: drivers/misc/* - CHECKPATCH M: Andy Whitcroft S: Supported @@ -3728,7 +3720,7 @@ F: fs/jbd2/ F: include/linux/jbd2.h JSM Neo PCI based serial card -M: Lucas Tavares +M: Breno Leitao L: linux-serial@vger.kernel.org S: Maintained F: drivers/tty/serial/jsm/ diff --git a/trunk/arch/microblaze/include/asm/namei.h b/trunk/arch/microblaze/include/asm/namei.h new file mode 100644 index 000000000000..61d60b8a07d5 --- /dev/null +++ b/trunk/arch/microblaze/include/asm/namei.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2006 Atmark Techno, Inc. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ + +#ifndef _ASM_MICROBLAZE_NAMEI_H +#define _ASM_MICROBLAZE_NAMEI_H + +#ifdef __KERNEL__ + +/* This dummy routine maybe changed to something useful + * for /usr/gnemul/ emulation stuff. + * Look at asm-sparc/namei.h for details. + */ +#define __emul_prefix() NULL + +#endif /* __KERNEL__ */ + +#endif /* _ASM_MICROBLAZE_NAMEI_H */ diff --git a/trunk/arch/x86/um/asm/processor.h b/trunk/arch/x86/um/asm/processor.h index 2c32df6fe231..118c143a9cb4 100644 --- a/trunk/arch/x86/um/asm/processor.h +++ b/trunk/arch/x86/um/asm/processor.h @@ -11,7 +11,7 @@ #endif #define KSTK_EIP(tsk) KSTK_REG(tsk, HOST_IP) -#define KSTK_ESP(tsk) KSTK_REG(tsk, HOST_SP) +#define KSTK_ESP(tsk) KSTK_REG(tsk, HOST_IP) #define KSTK_EBP(tsk) KSTK_REG(tsk, HOST_BP) #define ARCH_IS_STACKGROW(address) \ diff --git a/trunk/drivers/base/node.c b/trunk/drivers/base/node.c index 5693ecee9a40..793f796c4da3 100644 --- a/trunk/drivers/base/node.c +++ b/trunk/drivers/base/node.c @@ -127,13 +127,12 @@ static ssize_t node_read_meminfo(struct sys_device * dev, nid, K(node_page_state(nid, NR_WRITEBACK)), nid, K(node_page_state(nid, NR_FILE_PAGES)), nid, K(node_page_state(nid, NR_FILE_MAPPED)), -#ifdef CONFIG_TRANSPARENT_HUGEPAGE nid, K(node_page_state(nid, NR_ANON_PAGES) +#ifdef CONFIG_TRANSPARENT_HUGEPAGE + node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) * - HPAGE_PMD_NR), -#else - nid, K(node_page_state(nid, NR_ANON_PAGES)), + HPAGE_PMD_NR #endif + ), nid, K(node_page_state(nid, NR_SHMEM)), nid, node_page_state(nid, NR_KERNEL_STACK) * THREAD_SIZE / 1024, @@ -144,14 +143,13 @@ static ssize_t node_read_meminfo(struct sys_device * dev, nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) + node_page_state(nid, NR_SLAB_UNRECLAIMABLE)), nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)), -#ifdef CONFIG_TRANSPARENT_HUGEPAGE nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE)) +#ifdef CONFIG_TRANSPARENT_HUGEPAGE , nid, K(node_page_state(nid, NR_ANON_TRANSPARENT_HUGEPAGES) * - HPAGE_PMD_NR)); -#else - nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))); + HPAGE_PMD_NR) #endif + ); n += hugetlb_report_node_meminfo(nid, buf + n); return n; } diff --git a/trunk/drivers/gpu/drm/drm_crtc.c b/trunk/drivers/gpu/drm/drm_crtc.c index 8323fc389840..405c63b9d539 100644 --- a/trunk/drivers/gpu/drm/drm_crtc.c +++ b/trunk/drivers/gpu/drm/drm_crtc.c @@ -1873,10 +1873,6 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, } if (num_clips && clips_ptr) { - if (num_clips < 0 || num_clips > DRM_MODE_FB_DIRTY_MAX_CLIPS) { - ret = -EINVAL; - goto out_err1; - } clips = kzalloc(num_clips * sizeof(*clips), GFP_KERNEL); if (!clips) { ret = -ENOMEM; diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index d09a6e02dc95..4f40f1ce1d8e 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -636,16 +636,11 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct intel_ring_buffer *ring; - int ret; ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; if (ring->size == 0) return 0; - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - seq_printf(m, "Ring %s:\n", ring->name); seq_printf(m, " Head : %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR); seq_printf(m, " Tail : %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR); @@ -659,8 +654,6 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) seq_printf(m, " Control : %08x\n", I915_READ_CTL(ring)); seq_printf(m, " Start : %08x\n", I915_READ_START(ring)); - mutex_unlock(&dev->struct_mutex); - return 0; } @@ -849,16 +842,7 @@ static int i915_rstdby_delays(struct seq_file *m, void *unused) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - u16 crstanddelay; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - crstanddelay = I915_READ16(CRSTANDVID); - - mutex_unlock(&dev->struct_mutex); + u16 crstanddelay = I915_READ16(CRSTANDVID); seq_printf(m, "w/ctx: %d, w/o ctx: %d\n", (crstanddelay >> 8) & 0x3f, (crstanddelay & 0x3f)); @@ -956,11 +940,7 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused) struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; u32 delayfreq; - int ret, i; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; + int i; for (i = 0; i < 16; i++) { delayfreq = I915_READ(PXVFREQ_BASE + i * 4); @@ -968,8 +948,6 @@ static int i915_delayfreq_table(struct seq_file *m, void *unused) (delayfreq & PXVFREQ_PX_MASK) >> PXVFREQ_PX_SHIFT); } - mutex_unlock(&dev->struct_mutex); - return 0; } @@ -984,19 +962,13 @@ static int i915_inttoext_table(struct seq_file *m, void *unused) struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; u32 inttoext; - int ret, i; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; + int i; for (i = 1; i <= 32; i++) { inttoext = I915_READ(INTTOEXT_BASE_ILK + i * 4); seq_printf(m, "INTTOEXT%02d: 0x%08x\n", i, inttoext); } - mutex_unlock(&dev->struct_mutex); - return 0; } @@ -1005,19 +977,9 @@ static int i915_drpc_info(struct seq_file *m, void *unused) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - u32 rgvmodectl, rstdbyctl; - u16 crstandvid; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - rgvmodectl = I915_READ(MEMMODECTL); - rstdbyctl = I915_READ(RSTDBYCTL); - crstandvid = I915_READ16(CRSTANDVID); - - mutex_unlock(&dev->struct_mutex); + u32 rgvmodectl = I915_READ(MEMMODECTL); + u32 rstdbyctl = I915_READ(RSTDBYCTL); + u16 crstandvid = I915_READ16(CRSTANDVID); seq_printf(m, "HD boost: %s\n", (rgvmodectl & MEMMODE_BOOST_EN) ? "yes" : "no"); @@ -1205,16 +1167,9 @@ static int i915_gfxec(struct seq_file *m, void *unused) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; seq_printf(m, "GFXEC: %ld\n", (unsigned long)I915_READ(0x112f4)); - mutex_unlock(&dev->struct_mutex); - return 0; } diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index 15bfa9145d2b..e9c2cfe45daa 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -68,7 +68,7 @@ module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); MODULE_PARM_DESC(i915_enable_rc6, "Enable power-saving render C-state 6 (default: true)"); -int i915_enable_fbc __read_mostly = -1; +unsigned int i915_enable_fbc __read_mostly = -1; module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600); MODULE_PARM_DESC(i915_enable_fbc, "Enable frame buffer compression for power savings " @@ -80,7 +80,7 @@ MODULE_PARM_DESC(lvds_downclock, "Use panel (LVDS/eDP) downclocking for power savings " "(default: false)"); -int i915_panel_use_ssc __read_mostly = -1; +unsigned int i915_panel_use_ssc __read_mostly = -1; module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600); MODULE_PARM_DESC(lvds_use_ssc, "Use Spread Spectrum Clock with panels [LVDS/eDP] " @@ -107,7 +107,7 @@ static struct drm_driver driver; extern int intel_agp_enabled; #define INTEL_VGA_DEVICE(id, info) { \ - .class = PCI_BASE_CLASS_DISPLAY << 16, \ + .class = PCI_CLASS_DISPLAY_VGA << 8, \ .class_mask = 0xff0000, \ .vendor = 0x8086, \ .device = id, \ diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 4a9c1b979804..06a37f4fd74b 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -126,9 +126,6 @@ struct drm_i915_master_private { struct _drm_i915_sarea *sarea_priv; }; #define I915_FENCE_REG_NONE -1 -#define I915_MAX_NUM_FENCES 16 -/* 16 fences + sign bit for FENCE_REG_NONE */ -#define I915_MAX_NUM_FENCE_BITS 5 struct drm_i915_fence_reg { struct list_head lru_list; @@ -171,7 +168,7 @@ struct drm_i915_error_state { u32 instdone1; u32 seqno; u64 bbaddr; - u64 fence[I915_MAX_NUM_FENCES]; + u64 fence[16]; struct timeval time; struct drm_i915_error_object { int page_count; @@ -185,7 +182,7 @@ struct drm_i915_error_state { u32 gtt_offset; u32 read_domains; u32 write_domain; - s32 fence_reg:I915_MAX_NUM_FENCE_BITS; + s32 fence_reg:5; s32 pinned:2; u32 tiling:2; u32 dirty:1; @@ -378,7 +375,7 @@ typedef struct drm_i915_private { struct notifier_block lid_notifier; int crt_ddc_pin; - struct drm_i915_fence_reg fence_regs[I915_MAX_NUM_FENCES]; /* assume 965 */ + struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ int num_fence_regs; /* 8 on pre-965, 16 otherwise */ @@ -509,7 +506,7 @@ typedef struct drm_i915_private { u8 saveAR[21]; u8 saveDACMASK; u8 saveCR[37]; - uint64_t saveFENCE[I915_MAX_NUM_FENCES]; + uint64_t saveFENCE[16]; u32 saveCURACNTR; u32 saveCURAPOS; u32 saveCURABASE; @@ -780,8 +777,10 @@ struct drm_i915_gem_object { * Fence register bits (if any) for this object. Will be set * as needed when mapped into the GTT. * Protected by dev->struct_mutex. + * + * Size: 4 bits for 16 fences + sign (for FENCE_REG_NONE) */ - signed int fence_reg:I915_MAX_NUM_FENCE_BITS; + signed int fence_reg:5; /** * Advice: are the backing pages purgeable? @@ -1000,10 +999,10 @@ extern int i915_panel_ignore_lid __read_mostly; extern unsigned int i915_powersave __read_mostly; extern unsigned int i915_semaphores __read_mostly; extern unsigned int i915_lvds_downclock __read_mostly; -extern int i915_panel_use_ssc __read_mostly; +extern unsigned int i915_panel_use_ssc __read_mostly; extern int i915_vbt_sdvo_panel_type __read_mostly; extern unsigned int i915_enable_rc6 __read_mostly; -extern int i915_enable_fbc __read_mostly; +extern unsigned int i915_enable_fbc __read_mostly; extern bool i915_enable_hangcheck __read_mostly; extern int i915_suspend(struct drm_device *dev, pm_message_t state); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 8359dc777041..d18b07adcffa 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -1745,7 +1745,7 @@ static void i915_gem_reset_fences(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int i; - for (i = 0; i < dev_priv->num_fence_regs; i++) { + for (i = 0; i < 16; i++) { struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; struct drm_i915_gem_object *obj = reg->obj; @@ -3512,11 +3512,9 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, * so emit a request to do so. */ request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request) { + if (request) ret = i915_add_request(obj->ring, NULL, request); - if (ret) - kfree(request); - } else + else ret = -ENOMEM; } @@ -3615,7 +3613,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, obj->base.write_domain = I915_GEM_DOMAIN_CPU; obj->base.read_domains = I915_GEM_DOMAIN_CPU; - if (IS_GEN6(dev) || IS_GEN7(dev)) { + if (IS_GEN6(dev)) { /* On Gen6, we can have the GPU use the LLC (the CPU * cache) for about a 10% performance improvement * compared to uncached. Graphics requests other than @@ -3879,7 +3877,7 @@ i915_gem_load(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->mm.gtt_list); for (i = 0; i < I915_NUM_RINGS; i++) init_ring_lists(&dev_priv->ring[i]); - for (i = 0; i < I915_MAX_NUM_FENCES; i++) + for (i = 0; i < 16; i++) INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); INIT_DELAYED_WORK(&dev_priv->mm.retire_work, i915_gem_retire_work_handler); diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index b40004b55977..9ee2729fe5c6 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -824,7 +824,6 @@ static void i915_gem_record_fences(struct drm_device *dev, /* Fences */ switch (INTEL_INFO(dev)->gen) { - case 7: case 6: for (i = 0; i < 16; i++) error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index b080cc824001..5a09416e611f 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -1553,21 +1553,12 @@ */ #define PP_READY (1 << 30) #define PP_SEQUENCE_NONE (0 << 28) -#define PP_SEQUENCE_POWER_UP (1 << 28) -#define PP_SEQUENCE_POWER_DOWN (2 << 28) -#define PP_SEQUENCE_MASK (3 << 28) -#define PP_SEQUENCE_SHIFT 28 +#define PP_SEQUENCE_ON (1 << 28) +#define PP_SEQUENCE_OFF (2 << 28) +#define PP_SEQUENCE_MASK 0x30000000 #define PP_CYCLE_DELAY_ACTIVE (1 << 27) +#define PP_SEQUENCE_STATE_ON_IDLE (1 << 3) #define PP_SEQUENCE_STATE_MASK 0x0000000f -#define PP_SEQUENCE_STATE_OFF_IDLE (0x0 << 0) -#define PP_SEQUENCE_STATE_OFF_S0_1 (0x1 << 0) -#define PP_SEQUENCE_STATE_OFF_S0_2 (0x2 << 0) -#define PP_SEQUENCE_STATE_OFF_S0_3 (0x3 << 0) -#define PP_SEQUENCE_STATE_ON_IDLE (0x8 << 0) -#define PP_SEQUENCE_STATE_ON_S1_0 (0x9 << 0) -#define PP_SEQUENCE_STATE_ON_S1_2 (0xa << 0) -#define PP_SEQUENCE_STATE_ON_S1_3 (0xb << 0) -#define PP_SEQUENCE_STATE_RESET (0xf << 0) #define PP_CONTROL 0x61204 #define POWER_TARGET_ON (1 << 0) #define PP_ON_DELAYS 0x61208 @@ -3453,10 +3444,6 @@ #define GT_FIFO_FREE_ENTRIES 0x120008 #define GT_FIFO_NUM_RESERVED_ENTRIES 20 -#define GEN6_UCGCTL2 0x9404 -# define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) -# define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11) - #define GEN6_RPNSWREQ 0xA008 #define GEN6_TURBO_DISABLE (1<<31) #define GEN6_FREQUENCY(x) ((x)<<25) diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c index 7886e4fb60e3..f8f602d76650 100644 --- a/trunk/drivers/gpu/drm/i915/i915_suspend.c +++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c @@ -370,7 +370,6 @@ static void i915_save_modeset_reg(struct drm_device *dev) /* Fences */ switch (INTEL_INFO(dev)->gen) { - case 7: case 6: for (i = 0; i < 16; i++) dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); @@ -405,7 +404,6 @@ static void i915_restore_modeset_reg(struct drm_device *dev) /* Fences */ switch (INTEL_INFO(dev)->gen) { - case 7: case 6: for (i = 0; i < 16; i++) I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index e77a863a3833..981b1f1c04d8 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -2933,8 +2933,7 @@ static void ironlake_pch_enable(struct drm_crtc *crtc) /* For PCH DP, enable TRANS_DP_CTL */ if (HAS_PCH_CPT(dev) && - (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || - intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { + intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { u32 bpc = (I915_READ(PIPECONF(pipe)) & PIPE_BPC_MASK) >> 5; reg = TRANS_DP_CTL(pipe); temp = I915_READ(reg); @@ -4712,7 +4711,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, lvds_bpc = 6; if (lvds_bpc < display_bpc) { - DRM_DEBUG_KMS("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc); + DRM_DEBUG_DRIVER("clamping display bpc (was %d) to LVDS (%d)\n", display_bpc, lvds_bpc); display_bpc = lvds_bpc; } continue; @@ -4723,7 +4722,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, unsigned int edp_bpc = dev_priv->edp.bpp / 3; if (edp_bpc < display_bpc) { - DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); + DRM_DEBUG_DRIVER("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); display_bpc = edp_bpc; } continue; @@ -4738,7 +4737,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, /* Don't use an invalid EDID bpc value */ if (connector->display_info.bpc && connector->display_info.bpc < display_bpc) { - DRM_DEBUG_KMS("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc); + DRM_DEBUG_DRIVER("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc); display_bpc = connector->display_info.bpc; } } @@ -4749,10 +4748,10 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, */ if (intel_encoder->type == INTEL_OUTPUT_HDMI) { if (display_bpc > 8 && display_bpc < 12) { - DRM_DEBUG_KMS("forcing bpc to 12 for HDMI\n"); + DRM_DEBUG_DRIVER("forcing bpc to 12 for HDMI\n"); display_bpc = 12; } else { - DRM_DEBUG_KMS("forcing bpc to 8 for HDMI\n"); + DRM_DEBUG_DRIVER("forcing bpc to 8 for HDMI\n"); display_bpc = 8; } } @@ -4790,8 +4789,8 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, display_bpc = min(display_bpc, bpc); - DRM_DEBUG_KMS("setting pipe bpc to %d (max display bpc %d)\n", - bpc, display_bpc); + DRM_DEBUG_DRIVER("setting pipe bpc to %d (max display bpc %d)\n", + bpc, display_bpc); *pipe_bpp = display_bpc * 3; @@ -5672,7 +5671,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, pipeconf &= ~PIPECONF_DITHER_TYPE_MASK; if ((is_lvds && dev_priv->lvds_dither) || dither) { pipeconf |= PIPECONF_DITHER_EN; - pipeconf |= PIPECONF_DITHER_TYPE_SP; + pipeconf |= PIPECONF_DITHER_TYPE_ST1; } if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { intel_dp_set_m_n(crtc, mode, adjusted_mode); @@ -8149,20 +8148,6 @@ static void gen6_init_clock_gating(struct drm_device *dev) I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); - /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock - * gating disable must be set. Failure to set it results in - * flickering pixels due to Z write ordering failures after - * some amount of runtime in the Mesa "fire" demo, and Unigine - * Sanctuary and Tropics, and apparently anything else with - * alpha test or pixel discard. - * - * According to the spec, bit 11 (RCCUNIT) must also be set, - * but we didn't debug actual testcases to find it out. - */ - I915_WRITE(GEN6_UCGCTL2, - GEN6_RCPBUNIT_CLOCK_GATE_DISABLE | - GEN6_RCCUNIT_CLOCK_GATE_DISABLE); - /* * According to the spec the following bits should be * set in order to enable memory self-refresh and fbc: diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 4d0358fad937..09b318b0227f 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -59,6 +59,7 @@ struct intel_dp { struct i2c_algo_dp_aux_data algo; bool is_pch_edp; uint8_t train_set[4]; + uint8_t link_status[DP_LINK_STATUS_SIZE]; int panel_power_up_delay; int panel_power_down_delay; int panel_power_cycle_delay; @@ -67,6 +68,7 @@ struct intel_dp { struct drm_display_mode *panel_fixed_mode; /* for eDP */ struct delayed_work panel_vdd_work; bool want_panel_vdd; + unsigned long panel_off_jiffies; }; /** @@ -155,12 +157,16 @@ intel_edp_link_config(struct intel_encoder *intel_encoder, static int intel_dp_max_lane_count(struct intel_dp *intel_dp) { - int max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; - switch (max_lane_count) { - case 1: case 2: case 4: - break; - default: - max_lane_count = 4; + int max_lane_count = 4; + + if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) { + max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; + switch (max_lane_count) { + case 1: case 2: case 4: + break; + default: + max_lane_count = 4; + } } return max_lane_count; } @@ -762,11 +768,12 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, continue; intel_dp = enc_to_intel_dp(encoder); - if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || - intel_dp->base.type == INTEL_OUTPUT_EDP) - { + if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) { lane_count = intel_dp->lane_count; break; + } else if (is_edp(intel_dp)) { + lane_count = dev_priv->edp.lanes; + break; } } @@ -803,7 +810,6 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct drm_crtc *crtc = intel_dp->base.base.crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -816,31 +822,18 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, ironlake_edp_pll_off(encoder); } - /* - * There are three kinds of DP registers: - * - * IBX PCH - * CPU - * CPT PCH - * - * IBX PCH and CPU are the same for almost everything, - * except that the CPU DP PLL is configured in this - * register - * - * CPT PCH is quite different, having many bits moved - * to the TRANS_DP_CTL register instead. That - * configuration happens (oddly) in ironlake_pch_enable - */ - - /* Preserve the BIOS-computed detected bit. This is - * supposed to be read-only. - */ - intel_dp->DP = I915_READ(intel_dp->output_reg) & DP_DETECTED; - intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; + intel_dp->DP = DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; + intel_dp->DP |= intel_dp->color_range; - /* Handle DP bits in common between all three register formats */ + if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) + intel_dp->DP |= DP_SYNC_HS_HIGH; + if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) + intel_dp->DP |= DP_SYNC_VS_HIGH; - intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; + if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) + intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; + else + intel_dp->DP |= DP_LINK_TRAIN_OFF; switch (intel_dp->lane_count) { case 1: @@ -859,106 +852,59 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; intel_write_eld(encoder, adjusted_mode); } + memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); intel_dp->link_configuration[0] = intel_dp->link_bw; intel_dp->link_configuration[1] = intel_dp->lane_count; intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B; + /* * Check for DPCD version > 1.1 and enhanced framing support */ if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) { intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; + intel_dp->DP |= DP_ENHANCED_FRAMING; } - /* Split out the IBX/CPU vs CPT settings */ - - if (!HAS_PCH_CPT(dev) || is_cpu_edp(intel_dp)) { - intel_dp->DP |= intel_dp->color_range; - - if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) - intel_dp->DP |= DP_SYNC_HS_HIGH; - if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) - intel_dp->DP |= DP_SYNC_VS_HIGH; - intel_dp->DP |= DP_LINK_TRAIN_OFF; - - if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN) - intel_dp->DP |= DP_ENHANCED_FRAMING; - - if (intel_crtc->pipe == 1) - intel_dp->DP |= DP_PIPEB_SELECT; - - if (is_cpu_edp(intel_dp)) { - /* don't miss out required setting for eDP */ - intel_dp->DP |= DP_PLL_ENABLE; - if (adjusted_mode->clock < 200000) - intel_dp->DP |= DP_PLL_FREQ_160MHZ; - else - intel_dp->DP |= DP_PLL_FREQ_270MHZ; - } - } else { - intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; - } -} + /* CPT DP's pipe select is decided in TRANS_DP_CTL */ + if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) + intel_dp->DP |= DP_PIPEB_SELECT; -#define IDLE_ON_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK) -#define IDLE_ON_VALUE (PP_ON | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_ON_IDLE) - -#define IDLE_OFF_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | 0 | PP_SEQUENCE_STATE_MASK) -#define IDLE_OFF_VALUE (0 | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE) - -#define IDLE_CYCLE_MASK (PP_ON | 0 | PP_SEQUENCE_MASK | PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK) -#define IDLE_CYCLE_VALUE (0 | 0 | PP_SEQUENCE_NONE | 0 | PP_SEQUENCE_STATE_OFF_IDLE) - -static void ironlake_wait_panel_status(struct intel_dp *intel_dp, - u32 mask, - u32 value) -{ - struct drm_device *dev = intel_dp->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n", - mask, value, - I915_READ(PCH_PP_STATUS), - I915_READ(PCH_PP_CONTROL)); - - if (_wait_for((I915_READ(PCH_PP_STATUS) & mask) == value, 5000, 10)) { - DRM_ERROR("Panel status timeout: status %08x control %08x\n", - I915_READ(PCH_PP_STATUS), - I915_READ(PCH_PP_CONTROL)); + if (is_cpu_edp(intel_dp)) { + /* don't miss out required setting for eDP */ + intel_dp->DP |= DP_PLL_ENABLE; + if (adjusted_mode->clock < 200000) + intel_dp->DP |= DP_PLL_FREQ_160MHZ; + else + intel_dp->DP |= DP_PLL_FREQ_270MHZ; } } -static void ironlake_wait_panel_on(struct intel_dp *intel_dp) -{ - DRM_DEBUG_KMS("Wait for panel power on\n"); - ironlake_wait_panel_status(intel_dp, IDLE_ON_MASK, IDLE_ON_VALUE); -} - static void ironlake_wait_panel_off(struct intel_dp *intel_dp) { - DRM_DEBUG_KMS("Wait for panel power off time\n"); - ironlake_wait_panel_status(intel_dp, IDLE_OFF_MASK, IDLE_OFF_VALUE); -} + unsigned long off_time; + unsigned long delay; -static void ironlake_wait_panel_power_cycle(struct intel_dp *intel_dp) -{ - DRM_DEBUG_KMS("Wait for panel power cycle\n"); - ironlake_wait_panel_status(intel_dp, IDLE_CYCLE_MASK, IDLE_CYCLE_VALUE); -} - - -/* Read the current pp_control value, unlocking the register if it - * is locked - */ + DRM_DEBUG_KMS("Wait for panel power off time\n"); -static u32 ironlake_get_pp_control(struct drm_i915_private *dev_priv) -{ - u32 control = I915_READ(PCH_PP_CONTROL); + if (ironlake_edp_have_panel_power(intel_dp) || + ironlake_edp_have_panel_vdd(intel_dp)) + { + DRM_DEBUG_KMS("Panel still on, no delay needed\n"); + return; + } - control &= ~PANEL_UNLOCK_MASK; - control |= PANEL_UNLOCK_REGS; - return control; + off_time = intel_dp->panel_off_jiffies + msecs_to_jiffies(intel_dp->panel_power_down_delay); + if (time_after(jiffies, off_time)) { + DRM_DEBUG_KMS("Time already passed"); + return; + } + delay = jiffies_to_msecs(off_time - jiffies); + if (delay > intel_dp->panel_power_down_delay) + delay = intel_dp->panel_power_down_delay; + DRM_DEBUG_KMS("Waiting an additional %ld ms\n", delay); + msleep(delay); } static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) @@ -975,16 +921,15 @@ static void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) "eDP VDD already requested on\n"); intel_dp->want_panel_vdd = true; - if (ironlake_edp_have_panel_vdd(intel_dp)) { DRM_DEBUG_KMS("eDP VDD already on\n"); return; } - if (!ironlake_edp_have_panel_power(intel_dp)) - ironlake_wait_panel_power_cycle(intel_dp); - - pp = ironlake_get_pp_control(dev_priv); + ironlake_wait_panel_off(intel_dp); + pp = I915_READ(PCH_PP_CONTROL); + pp &= ~PANEL_UNLOCK_MASK; + pp |= PANEL_UNLOCK_REGS; pp |= EDP_FORCE_VDD; I915_WRITE(PCH_PP_CONTROL, pp); POSTING_READ(PCH_PP_CONTROL); @@ -1007,7 +952,9 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp) u32 pp; if (!intel_dp->want_panel_vdd && ironlake_edp_have_panel_vdd(intel_dp)) { - pp = ironlake_get_pp_control(dev_priv); + pp = I915_READ(PCH_PP_CONTROL); + pp &= ~PANEL_UNLOCK_MASK; + pp |= PANEL_UNLOCK_REGS; pp &= ~EDP_FORCE_VDD; I915_WRITE(PCH_PP_CONTROL, pp); POSTING_READ(PCH_PP_CONTROL); @@ -1015,8 +962,7 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp) /* Make sure sequencer is idle before allowing subsequent activity */ DRM_DEBUG_KMS("PCH_PP_STATUS: 0x%08x PCH_PP_CONTROL: 0x%08x\n", I915_READ(PCH_PP_STATUS), I915_READ(PCH_PP_CONTROL)); - - msleep(intel_dp->panel_power_down_delay); + intel_dp->panel_off_jiffies = jiffies; } } @@ -1026,9 +972,9 @@ static void ironlake_panel_vdd_work(struct work_struct *__work) struct intel_dp, panel_vdd_work); struct drm_device *dev = intel_dp->base.base.dev; - mutex_lock(&dev->mode_config.mutex); + mutex_lock(&dev->struct_mutex); ironlake_panel_vdd_off_sync(intel_dp); - mutex_unlock(&dev->mode_config.mutex); + mutex_unlock(&dev->struct_mutex); } static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) @@ -1038,7 +984,7 @@ static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) DRM_DEBUG_KMS("Turn eDP VDD off %d\n", intel_dp->want_panel_vdd); WARN(!intel_dp->want_panel_vdd, "eDP VDD not forced on"); - + intel_dp->want_panel_vdd = false; if (sync) { @@ -1054,25 +1000,23 @@ static void ironlake_edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) } } +/* Returns true if the panel was already on when called */ static void ironlake_edp_panel_on(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - u32 pp; + u32 pp, idle_on_mask = PP_ON | PP_SEQUENCE_STATE_ON_IDLE; if (!is_edp(intel_dp)) return; - - DRM_DEBUG_KMS("Turn eDP power on\n"); - - if (ironlake_edp_have_panel_power(intel_dp)) { - DRM_DEBUG_KMS("eDP power already on\n"); + if (ironlake_edp_have_panel_power(intel_dp)) return; - } - ironlake_wait_panel_power_cycle(intel_dp); + ironlake_wait_panel_off(intel_dp); + pp = I915_READ(PCH_PP_CONTROL); + pp &= ~PANEL_UNLOCK_MASK; + pp |= PANEL_UNLOCK_REGS; - pp = ironlake_get_pp_control(dev_priv); if (IS_GEN5(dev)) { /* ILK workaround: disable reset around power sequence */ pp &= ~PANEL_POWER_RESET; @@ -1081,13 +1025,13 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp) } pp |= POWER_TARGET_ON; - if (!IS_GEN5(dev)) - pp |= PANEL_POWER_RESET; - I915_WRITE(PCH_PP_CONTROL, pp); POSTING_READ(PCH_PP_CONTROL); - ironlake_wait_panel_on(intel_dp); + if (wait_for((I915_READ(PCH_PP_STATUS) & idle_on_mask) == idle_on_mask, + 5000)) + DRM_ERROR("panel on wait timed out: 0x%08x\n", + I915_READ(PCH_PP_STATUS)); if (IS_GEN5(dev)) { pp |= PANEL_POWER_RESET; /* restore panel reset bit */ @@ -1096,25 +1040,46 @@ static void ironlake_edp_panel_on(struct intel_dp *intel_dp) } } -static void ironlake_edp_panel_off(struct intel_dp *intel_dp) +static void ironlake_edp_panel_off(struct drm_encoder *encoder) { - struct drm_device *dev = intel_dp->base.base.dev; + struct intel_dp *intel_dp = enc_to_intel_dp(encoder); + struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; - u32 pp; + u32 pp, idle_off_mask = PP_ON | PP_SEQUENCE_MASK | + PP_CYCLE_DELAY_ACTIVE | PP_SEQUENCE_STATE_MASK; if (!is_edp(intel_dp)) return; + pp = I915_READ(PCH_PP_CONTROL); + pp &= ~PANEL_UNLOCK_MASK; + pp |= PANEL_UNLOCK_REGS; - DRM_DEBUG_KMS("Turn eDP power off\n"); + if (IS_GEN5(dev)) { + /* ILK workaround: disable reset around power sequence */ + pp &= ~PANEL_POWER_RESET; + I915_WRITE(PCH_PP_CONTROL, pp); + POSTING_READ(PCH_PP_CONTROL); + } - WARN(intel_dp->want_panel_vdd, "Cannot turn power off while VDD is on\n"); + intel_dp->panel_off_jiffies = jiffies; - pp = ironlake_get_pp_control(dev_priv); - pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); - I915_WRITE(PCH_PP_CONTROL, pp); - POSTING_READ(PCH_PP_CONTROL); + if (IS_GEN5(dev)) { + pp &= ~POWER_TARGET_ON; + I915_WRITE(PCH_PP_CONTROL, pp); + POSTING_READ(PCH_PP_CONTROL); + pp &= ~POWER_TARGET_ON; + I915_WRITE(PCH_PP_CONTROL, pp); + POSTING_READ(PCH_PP_CONTROL); + msleep(intel_dp->panel_power_cycle_delay); - ironlake_wait_panel_off(intel_dp); + if (wait_for((I915_READ(PCH_PP_STATUS) & idle_off_mask) == 0, 5000)) + DRM_ERROR("panel off wait timed out: 0x%08x\n", + I915_READ(PCH_PP_STATUS)); + + pp |= PANEL_POWER_RESET; /* restore panel reset bit */ + I915_WRITE(PCH_PP_CONTROL, pp); + POSTING_READ(PCH_PP_CONTROL); + } } static void ironlake_edp_backlight_on(struct intel_dp *intel_dp) @@ -1134,7 +1099,9 @@ static void ironlake_edp_backlight_on(struct intel_dp *intel_dp) * allowing it to appear. */ msleep(intel_dp->backlight_on_delay); - pp = ironlake_get_pp_control(dev_priv); + pp = I915_READ(PCH_PP_CONTROL); + pp &= ~PANEL_UNLOCK_MASK; + pp |= PANEL_UNLOCK_REGS; pp |= EDP_BLC_ENABLE; I915_WRITE(PCH_PP_CONTROL, pp); POSTING_READ(PCH_PP_CONTROL); @@ -1150,7 +1117,9 @@ static void ironlake_edp_backlight_off(struct intel_dp *intel_dp) return; DRM_DEBUG_KMS("\n"); - pp = ironlake_get_pp_control(dev_priv); + pp = I915_READ(PCH_PP_CONTROL); + pp &= ~PANEL_UNLOCK_MASK; + pp |= PANEL_UNLOCK_REGS; pp &= ~EDP_BLC_ENABLE; I915_WRITE(PCH_PP_CONTROL, pp); POSTING_READ(PCH_PP_CONTROL); @@ -1218,18 +1187,17 @@ static void intel_dp_prepare(struct drm_encoder *encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); - ironlake_edp_backlight_off(intel_dp); - ironlake_edp_panel_off(intel_dp); - /* Wake up the sink first */ ironlake_edp_panel_vdd_on(intel_dp); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); - intel_dp_link_down(intel_dp); ironlake_edp_panel_vdd_off(intel_dp, false); /* Make sure the panel is off before trying to * change the mode */ + ironlake_edp_backlight_off(intel_dp); + intel_dp_link_down(intel_dp); + ironlake_edp_panel_off(encoder); } static void intel_dp_commit(struct drm_encoder *encoder) @@ -1243,6 +1211,7 @@ static void intel_dp_commit(struct drm_encoder *encoder) intel_dp_start_link_train(intel_dp); ironlake_edp_panel_on(intel_dp); ironlake_edp_panel_vdd_off(intel_dp, true); + intel_dp_complete_link_train(intel_dp); ironlake_edp_backlight_on(intel_dp); @@ -1261,20 +1230,16 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) uint32_t dp_reg = I915_READ(intel_dp->output_reg); if (mode != DRM_MODE_DPMS_ON) { - ironlake_edp_backlight_off(intel_dp); - ironlake_edp_panel_off(intel_dp); - ironlake_edp_panel_vdd_on(intel_dp); + if (is_edp(intel_dp)) + ironlake_edp_backlight_off(intel_dp); intel_dp_sink_dpms(intel_dp, mode); intel_dp_link_down(intel_dp); - ironlake_edp_panel_vdd_off(intel_dp, false); - - if (is_cpu_edp(intel_dp)) + ironlake_edp_panel_off(encoder); + if (is_edp(intel_dp) && !is_pch_edp(intel_dp)) ironlake_edp_pll_off(encoder); + ironlake_edp_panel_vdd_off(intel_dp, false); } else { - if (is_cpu_edp(intel_dp)) - ironlake_edp_pll_on(encoder); - ironlake_edp_panel_vdd_on(intel_dp); intel_dp_sink_dpms(intel_dp, mode); if (!(dp_reg & DP_PORT_EN)) { @@ -1282,6 +1247,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) ironlake_edp_panel_on(intel_dp); ironlake_edp_panel_vdd_off(intel_dp, true); intel_dp_complete_link_train(intel_dp); + ironlake_edp_backlight_on(intel_dp); } else ironlake_edp_panel_vdd_off(intel_dp, false); ironlake_edp_backlight_on(intel_dp); @@ -1319,11 +1285,11 @@ intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address, * link status information */ static bool -intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) +intel_dp_get_link_status(struct intel_dp *intel_dp) { return intel_dp_aux_native_read_retry(intel_dp, DP_LANE0_1_STATUS, - link_status, + intel_dp->link_status, DP_LINK_STATUS_SIZE); } @@ -1335,25 +1301,27 @@ intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], } static uint8_t -intel_get_adjust_request_voltage(uint8_t adjust_request[2], +intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane) { + int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); int s = ((lane & 1) ? DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); - uint8_t l = adjust_request[lane>>1]; + uint8_t l = intel_dp_link_status(link_status, i); return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; } static uint8_t -intel_get_adjust_request_pre_emphasis(uint8_t adjust_request[2], +intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane) { + int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); int s = ((lane & 1) ? DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); - uint8_t l = adjust_request[lane>>1]; + uint8_t l = intel_dp_link_status(link_status, i); return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; } @@ -1376,7 +1344,6 @@ static char *link_train_names[] = { * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB */ #define I830_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_800 -#define I830_DP_VOLTAGE_MAX_CPT DP_TRAIN_VOLTAGE_SWING_1200 static uint8_t intel_dp_pre_emphasis_max(uint8_t voltage_swing) @@ -1395,18 +1362,15 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing) } static void -intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) +intel_get_adjust_train(struct intel_dp *intel_dp) { - struct drm_device *dev = intel_dp->base.base.dev; uint8_t v = 0; uint8_t p = 0; int lane; - uint8_t *adjust_request = link_status + (DP_ADJUST_REQUEST_LANE0_1 - DP_LANE0_1_STATUS); - int voltage_max; for (lane = 0; lane < intel_dp->lane_count; lane++) { - uint8_t this_v = intel_get_adjust_request_voltage(adjust_request, lane); - uint8_t this_p = intel_get_adjust_request_pre_emphasis(adjust_request, lane); + uint8_t this_v = intel_get_adjust_request_voltage(intel_dp->link_status, lane); + uint8_t this_p = intel_get_adjust_request_pre_emphasis(intel_dp->link_status, lane); if (this_v > v) v = this_v; @@ -1414,12 +1378,8 @@ intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_ST p = this_p; } - if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) - voltage_max = I830_DP_VOLTAGE_MAX_CPT; - else - voltage_max = I830_DP_VOLTAGE_MAX; - if (v >= voltage_max) - v = voltage_max | DP_TRAIN_MAX_SWING_REACHED; + if (v >= I830_DP_VOLTAGE_MAX) + v = I830_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED; if (p >= intel_dp_pre_emphasis_max(v)) p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; @@ -1429,7 +1389,7 @@ intel_get_adjust_train(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_ST } static uint32_t -intel_dp_signal_levels(uint8_t train_set) +intel_dp_signal_levels(uint8_t train_set, int lane_count) { uint32_t signal_levels = 0; @@ -1498,8 +1458,9 @@ static uint8_t intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane) { + int i = DP_LANE0_1_STATUS + (lane >> 1); int s = (lane & 1) * 4; - uint8_t l = link_status[lane>>1]; + uint8_t l = intel_dp_link_status(link_status, i); return (l >> s) & 0xf; } @@ -1524,18 +1485,18 @@ intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count DP_LANE_CHANNEL_EQ_DONE|\ DP_LANE_SYMBOL_LOCKED) static bool -intel_channel_eq_ok(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_STATUS_SIZE]) +intel_channel_eq_ok(struct intel_dp *intel_dp) { uint8_t lane_align; uint8_t lane_status; int lane; - lane_align = intel_dp_link_status(link_status, + lane_align = intel_dp_link_status(intel_dp->link_status, DP_LANE_ALIGN_STATUS_UPDATED); if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) return false; for (lane = 0; lane < intel_dp->lane_count; lane++) { - lane_status = intel_get_lane_status(link_status, lane); + lane_status = intel_get_lane_status(intel_dp->link_status, lane); if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) return false; } @@ -1560,9 +1521,8 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, ret = intel_dp_aux_native_write(intel_dp, DP_TRAINING_LANE0_SET, - intel_dp->train_set, - intel_dp->lane_count); - if (ret != intel_dp->lane_count) + intel_dp->train_set, 4); + if (ret != 4) return false; return true; @@ -1578,7 +1538,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) int i; uint8_t voltage; bool clock_recovery = false; - int voltage_tries, loop_tries; + int tries; u32 reg; uint32_t DP = intel_dp->DP; @@ -1605,20 +1565,16 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) DP &= ~DP_LINK_TRAIN_MASK; memset(intel_dp->train_set, 0, 4); voltage = 0xff; - voltage_tries = 0; - loop_tries = 0; + tries = 0; clock_recovery = false; for (;;) { /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ - uint8_t link_status[DP_LINK_STATUS_SIZE]; uint32_t signal_levels; - - if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { + if (IS_GEN6(dev) && is_edp(intel_dp)) { signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; } else { - signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); - DRM_DEBUG_KMS("training pattern 1 signal levels %08x\n", signal_levels); + signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; } @@ -1634,13 +1590,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) /* Set training pattern 1 */ udelay(100); - if (!intel_dp_get_link_status(intel_dp, link_status)) { - DRM_ERROR("failed to get link status\n"); + if (!intel_dp_get_link_status(intel_dp)) break; - } - if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { - DRM_DEBUG_KMS("clock recovery OK\n"); + if (intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { clock_recovery = true; break; } @@ -1649,30 +1602,20 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) for (i = 0; i < intel_dp->lane_count; i++) if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) break; - if (i == intel_dp->lane_count) { - ++loop_tries; - if (loop_tries == 5) { - DRM_DEBUG_KMS("too many full retries, give up\n"); - break; - } - memset(intel_dp->train_set, 0, 4); - voltage_tries = 0; - continue; - } + if (i == intel_dp->lane_count) + break; /* Check to see if we've tried the same voltage 5 times */ if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { - ++voltage_tries; - if (voltage_tries == 5) { - DRM_DEBUG_KMS("too many voltage retries, give up\n"); + ++tries; + if (tries == 5) break; - } } else - voltage_tries = 0; + tries = 0; voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; /* Compute new intel_dp->train_set as requested by target */ - intel_get_adjust_train(intel_dp, link_status); + intel_get_adjust_train(intel_dp); } intel_dp->DP = DP; @@ -1695,7 +1638,6 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) for (;;) { /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */ uint32_t signal_levels; - uint8_t link_status[DP_LINK_STATUS_SIZE]; if (cr_tries > 5) { DRM_ERROR("failed to train DP, aborting\n"); @@ -1703,11 +1645,11 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) break; } - if (IS_GEN6(dev) && is_cpu_edp(intel_dp)) { + if (IS_GEN6(dev) && is_edp(intel_dp)) { signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]); DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; } else { - signal_levels = intel_dp_signal_levels(intel_dp->train_set[0]); + signal_levels = intel_dp_signal_levels(intel_dp->train_set[0], intel_dp->lane_count); DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; } @@ -1723,17 +1665,17 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) break; udelay(400); - if (!intel_dp_get_link_status(intel_dp, link_status)) + if (!intel_dp_get_link_status(intel_dp)) break; /* Make sure clock is still ok */ - if (!intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { + if (!intel_clock_recovery_ok(intel_dp->link_status, intel_dp->lane_count)) { intel_dp_start_link_train(intel_dp); cr_tries++; continue; } - if (intel_channel_eq_ok(intel_dp, link_status)) { + if (intel_channel_eq_ok(intel_dp)) { channel_eq = true; break; } @@ -1748,7 +1690,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) } /* Compute new intel_dp->train_set as requested by target */ - intel_get_adjust_train(intel_dp, link_status); + intel_get_adjust_train(intel_dp); ++tries; } @@ -1793,12 +1735,8 @@ intel_dp_link_down(struct intel_dp *intel_dp) msleep(17); - if (is_edp(intel_dp)) { - if (HAS_PCH_CPT(dev) && !is_cpu_edp(intel_dp)) - DP |= DP_LINK_TRAIN_OFF_CPT; - else - DP |= DP_LINK_TRAIN_OFF; - } + if (is_edp(intel_dp)) + DP |= DP_LINK_TRAIN_OFF; if (!HAS_PCH_CPT(dev) && I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { @@ -1884,7 +1822,6 @@ static void intel_dp_check_link_status(struct intel_dp *intel_dp) { u8 sink_irq_vector; - u8 link_status[DP_LINK_STATUS_SIZE]; if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) return; @@ -1893,7 +1830,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) return; /* Try to read receiver status if the link appears to be up */ - if (!intel_dp_get_link_status(intel_dp, link_status)) { + if (!intel_dp_get_link_status(intel_dp)) { intel_dp_link_down(intel_dp); return; } @@ -1918,7 +1855,7 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) DRM_DEBUG_DRIVER("CP or sink specific irq unhandled\n"); } - if (!intel_channel_eq_ok(intel_dp, link_status)) { + if (!intel_channel_eq_ok(intel_dp)) { DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", drm_get_encoder_name(&intel_dp->base.base)); intel_dp_start_link_train(intel_dp); @@ -2242,8 +2179,7 @@ intel_trans_dp_port_sel(struct drm_crtc *crtc) continue; intel_dp = enc_to_intel_dp(encoder); - if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT || - intel_dp->base.type == INTEL_OUTPUT_EDP) + if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) return intel_dp->output_reg; } @@ -2385,7 +2321,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) cur.t8 = (pp_on & PANEL_LIGHT_ON_DELAY_MASK) >> PANEL_LIGHT_ON_DELAY_SHIFT; - + cur.t9 = (pp_off & PANEL_LIGHT_OFF_DELAY_MASK) >> PANEL_LIGHT_OFF_DELAY_SHIFT; @@ -2418,10 +2354,11 @@ intel_dp_init(struct drm_device *dev, int output_reg) DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); + intel_dp->panel_off_jiffies = jiffies - intel_dp->panel_power_down_delay; + ironlake_edp_panel_vdd_on(intel_dp); ret = intel_dp_get_dpcd(intel_dp); ironlake_edp_panel_vdd_off(intel_dp, false); - if (ret) { if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) dev_priv->no_aux_handshake = diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c index 21f60b7d69a3..499d4c0dbeeb 100644 --- a/trunk/drivers/gpu/drm/i915/intel_panel.c +++ b/trunk/drivers/gpu/drm/i915/intel_panel.c @@ -326,8 +326,7 @@ static int intel_panel_update_status(struct backlight_device *bd) static int intel_panel_get_brightness(struct backlight_device *bd) { struct drm_device *dev = bl_get_data(bd); - struct drm_i915_private *dev_priv = dev->dev_private; - return dev_priv->backlight_level; + return intel_panel_get_backlight(dev); } static const struct backlight_ops intel_panel_bl_ops = { diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c index 38e1bda73d33..7fdfa8ea7570 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c @@ -480,23 +480,21 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) } break; case DB_Z_INFO: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } track->db_z_info = radeon_get_ib_value(p, idx); - if (!p->keep_tiling_flags) { - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - ib[idx] &= ~Z_ARRAY_MODE(0xf); - track->db_z_info &= ~Z_ARRAY_MODE(0xf); - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { - ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); - track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); - } else { - ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); - track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); - } + ib[idx] &= ~Z_ARRAY_MODE(0xf); + track->db_z_info &= ~Z_ARRAY_MODE(0xf); + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { + ib[idx] |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + track->db_z_info |= Z_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + } else { + ib[idx] |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); + track->db_z_info |= Z_ARRAY_MODE(ARRAY_1D_TILED_THIN1); } break; case DB_STENCIL_INFO: @@ -609,44 +607,40 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case CB_COLOR5_INFO: case CB_COLOR6_INFO: case CB_COLOR7_INFO: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } tmp = (reg - CB_COLOR0_INFO) / 0x3c; track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); - if (!p->keep_tiling_flags) { - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { - ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); - track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); - } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { - ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); - track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); - } + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { + ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { + ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); + track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); } break; case CB_COLOR8_INFO: case CB_COLOR9_INFO: case CB_COLOR10_INFO: case CB_COLOR11_INFO: + r = evergreen_cs_packet_next_reloc(p, &reloc); + if (r) { + dev_warn(p->dev, "bad SET_CONTEXT_REG " + "0x%04X\n", reg); + return -EINVAL; + } tmp = ((reg - CB_COLOR8_INFO) / 0x1c) + 8; track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); - if (!p->keep_tiling_flags) { - r = evergreen_cs_packet_next_reloc(p, &reloc); - if (r) { - dev_warn(p->dev, "bad SET_CONTEXT_REG " - "0x%04X\n", reg); - return -EINVAL; - } - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { - ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); - track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); - } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { - ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); - track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); - } + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { + ib[idx] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + } else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { + ib[idx] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); + track->cb_color_info[tmp] |= CB_ARRAY_MODE(ARRAY_1D_TILED_THIN1); } break; case CB_COLOR0_PITCH: @@ -1317,12 +1311,10 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, return -EINVAL; } ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - if (!p->keep_tiling_flags) { - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); - else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); - } + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_2D_TILED_THIN1); + else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + ib[idx+1+(i*8)+1] |= TEX_ARRAY_MODE(ARRAY_1D_TILED_THIN1); texture = reloc->robj; /* tex mip base */ r = evergreen_cs_packet_next_reloc(p, &reloc); diff --git a/trunk/drivers/gpu/drm/radeon/r300.c b/trunk/drivers/gpu/drm/radeon/r300.c index c93bc64707e1..400b26df652a 100644 --- a/trunk/drivers/gpu/drm/radeon/r300.c +++ b/trunk/drivers/gpu/drm/radeon/r300.c @@ -701,21 +701,16 @@ static int r300_packet0_check(struct radeon_cs_parser *p, return r; } - if (p->keep_tiling_flags) { - ib[idx] = (idx_value & 31) | /* keep the 1st 5 bits */ - ((idx_value & ~31) + (u32)reloc->lobj.gpu_offset); - } else { - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= R300_TXO_MACRO_TILE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= R300_TXO_MICRO_TILE; - else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) - tile_flags |= R300_TXO_MICRO_TILE_SQUARE; - - tmp = idx_value + ((u32)reloc->lobj.gpu_offset); - tmp |= tile_flags; - ib[idx] = tmp; - } + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= R300_TXO_MACRO_TILE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + tile_flags |= R300_TXO_MICRO_TILE; + else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) + tile_flags |= R300_TXO_MICRO_TILE_SQUARE; + + tmp = idx_value + ((u32)reloc->lobj.gpu_offset); + tmp |= tile_flags; + ib[idx] = tmp; track->textures[i].robj = reloc->robj; track->tex_dirty = true; break; @@ -765,26 +760,24 @@ static int r300_packet0_check(struct radeon_cs_parser *p, /* RB3D_COLORPITCH1 */ /* RB3D_COLORPITCH2 */ /* RB3D_COLORPITCH3 */ - if (!p->keep_tiling_flags) { - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } + r = r100_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("No reloc for ib[%d]=0x%04X\n", + idx, reg); + r100_cs_dump_packet(p, pkt); + return r; + } - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= R300_COLOR_TILE_ENABLE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= R300_COLOR_MICROTILE_ENABLE; - else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) - tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= R300_COLOR_TILE_ENABLE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + tile_flags |= R300_COLOR_MICROTILE_ENABLE; + else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) + tile_flags |= R300_COLOR_MICROTILE_SQUARE_ENABLE; - tmp = idx_value & ~(0x7 << 16); - tmp |= tile_flags; - ib[idx] = tmp; - } + tmp = idx_value & ~(0x7 << 16); + tmp |= tile_flags; + ib[idx] = tmp; i = (reg - 0x4E38) >> 2; track->cb[i].pitch = idx_value & 0x3FFE; switch (((idx_value >> 21) & 0xF)) { @@ -850,26 +843,25 @@ static int r300_packet0_check(struct radeon_cs_parser *p, break; case 0x4F24: /* ZB_DEPTHPITCH */ - if (!p->keep_tiling_flags) { - r = r100_cs_packet_next_reloc(p, &reloc); - if (r) { - DRM_ERROR("No reloc for ib[%d]=0x%04X\n", - idx, reg); - r100_cs_dump_packet(p, pkt); - return r; - } + r = r100_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("No reloc for ib[%d]=0x%04X\n", + idx, reg); + r100_cs_dump_packet(p, pkt); + return r; + } - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= R300_DEPTHMACROTILE_ENABLE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= R300_DEPTHMICROTILE_TILED; - else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) - tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= R300_DEPTHMACROTILE_ENABLE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + tile_flags |= R300_DEPTHMICROTILE_TILED; + else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO_SQUARE) + tile_flags |= R300_DEPTHMICROTILE_TILED_SQUARE; + + tmp = idx_value & ~(0x7 << 16); + tmp |= tile_flags; + ib[idx] = tmp; - tmp = idx_value & ~(0x7 << 16); - tmp |= tile_flags; - ib[idx] = tmp; - } track->zb.pitch = idx_value & 0x3FFC; track->zb_dirty = true; break; diff --git a/trunk/drivers/gpu/drm/radeon/r600_cs.c b/trunk/drivers/gpu/drm/radeon/r600_cs.c index cb1acffd2430..0a2e023c1557 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_cs.c +++ b/trunk/drivers/gpu/drm/radeon/r600_cs.c @@ -941,8 +941,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) track->db_depth_control = radeon_get_ib_value(p, idx); break; case R_028010_DB_DEPTH_INFO: - if (!p->keep_tiling_flags && - r600_cs_packet_next_is_pkt3_nop(p)) { + if (r600_cs_packet_next_is_pkt3_nop(p)) { r = r600_cs_packet_next_reloc(p, &reloc); if (r) { dev_warn(p->dev, "bad SET_CONTEXT_REG " @@ -993,8 +992,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) case R_0280B4_CB_COLOR5_INFO: case R_0280B8_CB_COLOR6_INFO: case R_0280BC_CB_COLOR7_INFO: - if (!p->keep_tiling_flags && - r600_cs_packet_next_is_pkt3_nop(p)) { + if (r600_cs_packet_next_is_pkt3_nop(p)) { r = r600_cs_packet_next_reloc(p, &reloc); if (r) { dev_err(p->dev, "bad SET_CONTEXT_REG 0x%04X\n", reg); @@ -1293,12 +1291,10 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, mip_offset <<= 8; word0 = radeon_get_ib_value(p, idx + 0); - if (!p->keep_tiling_flags) { - if (tiling_flags & RADEON_TILING_MACRO) - word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); - else if (tiling_flags & RADEON_TILING_MICRO) - word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); - } + if (tiling_flags & RADEON_TILING_MACRO) + word0 |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); + else if (tiling_flags & RADEON_TILING_MICRO) + word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); word1 = radeon_get_ib_value(p, idx + 1); w0 = G_038000_TEX_WIDTH(word0) + 1; h0 = G_038004_TEX_HEIGHT(word1) + 1; @@ -1625,12 +1621,10 @@ static int r600_packet3_check(struct radeon_cs_parser *p, return -EINVAL; } base_offset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); - if (!p->keep_tiling_flags) { - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); - else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); - } + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_2D_TILED_THIN1); + else if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + ib[idx+1+(i*7)+0] |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); texture = reloc->robj; /* tex mip base */ r = r600_cs_packet_next_reloc(p, &reloc); diff --git a/trunk/drivers/gpu/drm/radeon/radeon.h b/trunk/drivers/gpu/drm/radeon/radeon.h index 8227e76b5c70..fc5a1d642cb5 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon.h +++ b/trunk/drivers/gpu/drm/radeon/radeon.h @@ -611,8 +611,7 @@ struct radeon_cs_parser { struct radeon_ib *ib; void *track; unsigned family; - int parser_error; - bool keep_tiling_flags; + int parser_error; }; extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c index d24baf30efcb..fecd705a1a5f 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_atombios.c @@ -62,87 +62,6 @@ union atom_supported_devices { struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; }; -static void radeon_lookup_i2c_gpio_quirks(struct radeon_device *rdev, - ATOM_GPIO_I2C_ASSIGMENT *gpio, - u8 index) -{ - /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */ - if ((rdev->family == CHIP_R420) || - (rdev->family == CHIP_R423) || - (rdev->family == CHIP_RV410)) { - if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) || - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) || - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) { - gpio->ucClkMaskShift = 0x19; - gpio->ucDataMaskShift = 0x18; - } - } - - /* some evergreen boards have bad data for this entry */ - if (ASIC_IS_DCE4(rdev)) { - if ((index == 7) && - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && - (gpio->sucI2cId.ucAccess == 0)) { - gpio->sucI2cId.ucAccess = 0x97; - gpio->ucDataMaskShift = 8; - gpio->ucDataEnShift = 8; - gpio->ucDataY_Shift = 8; - gpio->ucDataA_Shift = 8; - } - } - - /* some DCE3 boards have bad data for this entry */ - if (ASIC_IS_DCE3(rdev)) { - if ((index == 4) && - (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && - (gpio->sucI2cId.ucAccess == 0x94)) - gpio->sucI2cId.ucAccess = 0x14; - } -} - -static struct radeon_i2c_bus_rec radeon_get_bus_rec_for_i2c_gpio(ATOM_GPIO_I2C_ASSIGMENT *gpio) -{ - struct radeon_i2c_bus_rec i2c; - - memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); - - i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; - i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; - i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; - i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; - i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; - i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; - i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; - i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; - i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); - i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); - i2c.en_clk_mask = (1 << gpio->ucClkEnShift); - i2c.en_data_mask = (1 << gpio->ucDataEnShift); - i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); - i2c.y_data_mask = (1 << gpio->ucDataY_Shift); - i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); - i2c.a_data_mask = (1 << gpio->ucDataA_Shift); - - if (gpio->sucI2cId.sbfAccess.bfHW_Capable) - i2c.hw_capable = true; - else - i2c.hw_capable = false; - - if (gpio->sucI2cId.ucAccess == 0xa0) - i2c.mm_i2c = true; - else - i2c.mm_i2c = false; - - i2c.i2c_id = gpio->sucI2cId.ucAccess; - - if (i2c.mask_clk_reg) - i2c.valid = true; - else - i2c.valid = false; - - return i2c; -} - static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rdev, uint8_t id) { @@ -166,10 +85,71 @@ static struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_device *rd for (i = 0; i < num_indices; i++) { gpio = &i2c_info->asGPIO_Info[i]; - radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); + /* r4xx mask is technically not used by the hw, so patch in the legacy mask bits */ + if ((rdev->family == CHIP_R420) || + (rdev->family == CHIP_R423) || + (rdev->family == CHIP_RV410)) { + if ((le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0018) || + (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x0019) || + (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x001a)) { + gpio->ucClkMaskShift = 0x19; + gpio->ucDataMaskShift = 0x18; + } + } + + /* some evergreen boards have bad data for this entry */ + if (ASIC_IS_DCE4(rdev)) { + if ((i == 7) && + (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && + (gpio->sucI2cId.ucAccess == 0)) { + gpio->sucI2cId.ucAccess = 0x97; + gpio->ucDataMaskShift = 8; + gpio->ucDataEnShift = 8; + gpio->ucDataY_Shift = 8; + gpio->ucDataA_Shift = 8; + } + } + + /* some DCE3 boards have bad data for this entry */ + if (ASIC_IS_DCE3(rdev)) { + if ((i == 4) && + (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && + (gpio->sucI2cId.ucAccess == 0x94)) + gpio->sucI2cId.ucAccess = 0x14; + } if (gpio->sucI2cId.ucAccess == id) { - i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); + i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; + i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; + i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; + i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; + i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; + i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; + i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; + i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; + i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); + i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); + i2c.en_clk_mask = (1 << gpio->ucClkEnShift); + i2c.en_data_mask = (1 << gpio->ucDataEnShift); + i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); + i2c.y_data_mask = (1 << gpio->ucDataY_Shift); + i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); + i2c.a_data_mask = (1 << gpio->ucDataA_Shift); + + if (gpio->sucI2cId.sbfAccess.bfHW_Capable) + i2c.hw_capable = true; + else + i2c.hw_capable = false; + + if (gpio->sucI2cId.ucAccess == 0xa0) + i2c.mm_i2c = true; + else + i2c.mm_i2c = false; + + i2c.i2c_id = gpio->sucI2cId.ucAccess; + + if (i2c.mask_clk_reg) + i2c.valid = true; break; } } @@ -189,6 +169,8 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) int i, num_indices; char stmp[32]; + memset(&i2c, 0, sizeof(struct radeon_i2c_bus_rec)); + if (atom_parse_data_header(ctx, index, &size, NULL, NULL, &data_offset)) { i2c_info = (struct _ATOM_GPIO_I2C_INFO *)(ctx->bios + data_offset); @@ -197,12 +179,60 @@ void radeon_atombios_i2c_init(struct radeon_device *rdev) for (i = 0; i < num_indices; i++) { gpio = &i2c_info->asGPIO_Info[i]; + i2c.valid = false; + + /* some evergreen boards have bad data for this entry */ + if (ASIC_IS_DCE4(rdev)) { + if ((i == 7) && + (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1936) && + (gpio->sucI2cId.ucAccess == 0)) { + gpio->sucI2cId.ucAccess = 0x97; + gpio->ucDataMaskShift = 8; + gpio->ucDataEnShift = 8; + gpio->ucDataY_Shift = 8; + gpio->ucDataA_Shift = 8; + } + } - radeon_lookup_i2c_gpio_quirks(rdev, gpio, i); + /* some DCE3 boards have bad data for this entry */ + if (ASIC_IS_DCE3(rdev)) { + if ((i == 4) && + (le16_to_cpu(gpio->usClkMaskRegisterIndex) == 0x1fda) && + (gpio->sucI2cId.ucAccess == 0x94)) + gpio->sucI2cId.ucAccess = 0x14; + } + + i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4; + i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4; + i2c.en_clk_reg = le16_to_cpu(gpio->usClkEnRegisterIndex) * 4; + i2c.en_data_reg = le16_to_cpu(gpio->usDataEnRegisterIndex) * 4; + i2c.y_clk_reg = le16_to_cpu(gpio->usClkY_RegisterIndex) * 4; + i2c.y_data_reg = le16_to_cpu(gpio->usDataY_RegisterIndex) * 4; + i2c.a_clk_reg = le16_to_cpu(gpio->usClkA_RegisterIndex) * 4; + i2c.a_data_reg = le16_to_cpu(gpio->usDataA_RegisterIndex) * 4; + i2c.mask_clk_mask = (1 << gpio->ucClkMaskShift); + i2c.mask_data_mask = (1 << gpio->ucDataMaskShift); + i2c.en_clk_mask = (1 << gpio->ucClkEnShift); + i2c.en_data_mask = (1 << gpio->ucDataEnShift); + i2c.y_clk_mask = (1 << gpio->ucClkY_Shift); + i2c.y_data_mask = (1 << gpio->ucDataY_Shift); + i2c.a_clk_mask = (1 << gpio->ucClkA_Shift); + i2c.a_data_mask = (1 << gpio->ucDataA_Shift); + + if (gpio->sucI2cId.sbfAccess.bfHW_Capable) + i2c.hw_capable = true; + else + i2c.hw_capable = false; + + if (gpio->sucI2cId.ucAccess == 0xa0) + i2c.mm_i2c = true; + else + i2c.mm_i2c = false; - i2c = radeon_get_bus_rec_for_i2c_gpio(gpio); + i2c.i2c_id = gpio->sucI2cId.ucAccess; - if (i2c.valid) { + if (i2c.mask_clk_reg) { + i2c.valid = true; sprintf(stmp, "0x%x", i2c.i2c_id); rdev->i2c_bus[i] = radeon_i2c_create(rdev->ddev, &i2c, stmp); } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cs.c b/trunk/drivers/gpu/drm/radeon/radeon_cs.c index 29afd71e0840..ccaa243c1442 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cs.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cs.c @@ -93,7 +93,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) { struct drm_radeon_cs *cs = data; uint64_t *chunk_array_ptr; - unsigned size, i, flags = 0; + unsigned size, i; if (!cs->num_chunks) { return 0; @@ -140,10 +140,6 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) if (p->chunks[i].length_dw == 0) return -EINVAL; } - if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS && - !p->chunks[i].length_dw) { - return -EINVAL; - } p->chunks[i].length_dw = user_chunk.length_dw; p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; @@ -159,9 +155,6 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) p->chunks[i].user_ptr, size)) { return -EFAULT; } - if (p->chunks[i].chunk_id == RADEON_CHUNK_ID_FLAGS) { - flags = p->chunks[i].kdata[0]; - } } else { p->chunks[i].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); p->chunks[i].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); @@ -181,8 +174,6 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) p->chunks[p->chunk_ib_idx].length_dw); return -EINVAL; } - - p->keep_tiling_flags = (flags & RADEON_CS_KEEP_TILING_FLAGS) != 0; return 0; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index 71499fc3daf5..a0b35e909489 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -53,10 +53,9 @@ * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query * 2.10.0 - fusion 2D tiling * 2.11.0 - backend map, initial compute support for the CS checker - * 2.12.0 - RADEON_CS_KEEP_TILING_FLAGS */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 12 +#define KMS_DRIVER_MINOR 11 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo.c b/trunk/drivers/gpu/drm/ttm/ttm_bo.c index 0bb0f5f713e6..617b64678fc6 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo.c @@ -574,16 +574,10 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, return ret; spin_lock(&glob->lru_lock); - - if (unlikely(list_empty(&bo->ddestroy))) { - spin_unlock(&glob->lru_lock); - return 0; - } - ret = ttm_bo_reserve_locked(bo, interruptible, no_wait_reserve, false, 0); - if (unlikely(ret != 0)) { + if (unlikely(ret != 0) || list_empty(&bo->ddestroy)) { spin_unlock(&glob->lru_lock); return ret; } diff --git a/trunk/drivers/gpu/vga/vgaarb.c b/trunk/drivers/gpu/vga/vgaarb.c index 111d956d8e7d..bdde899af72e 100644 --- a/trunk/drivers/gpu/vga/vgaarb.c +++ b/trunk/drivers/gpu/vga/vgaarb.c @@ -991,20 +991,14 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf, uc = &priv->cards[i]; } - if (!uc) { - ret_val = -EINVAL; - goto done; - } + if (!uc) + return -EINVAL; - if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0) { - ret_val = -EINVAL; - goto done; - } + if (io_state & VGA_RSRC_LEGACY_IO && uc->io_cnt == 0) + return -EINVAL; - if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0) { - ret_val = -EINVAL; - goto done; - } + if (io_state & VGA_RSRC_LEGACY_MEM && uc->mem_cnt == 0) + return -EINVAL; vga_put(pdev, io_state); diff --git a/trunk/drivers/i2c/algos/i2c-algo-bit.c b/trunk/drivers/i2c/algos/i2c-algo-bit.c index 525c7345fa0b..85584a547c25 100644 --- a/trunk/drivers/i2c/algos/i2c-algo-bit.c +++ b/trunk/drivers/i2c/algos/i2c-algo-bit.c @@ -488,7 +488,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) if (flags & I2C_M_TEN) { /* a ten bit address */ - addr = 0xf0 | ((msg->addr >> 7) & 0x06); + addr = 0xf0 | ((msg->addr >> 7) & 0x03); bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); /* try extended address code...*/ ret = try_address(i2c_adap, addr, retries); @@ -498,7 +498,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) return -ENXIO; } /* the remaining 8 bit address */ - ret = i2c_outb(i2c_adap, msg->addr & 0xff); + ret = i2c_outb(i2c_adap, msg->addr & 0x7f); if ((ret != 1) && !nak_ok) { /* the chip did not ack / xmission error occurred */ dev_err(&i2c_adap->dev, "died at 2nd address code\n"); diff --git a/trunk/drivers/i2c/i2c-core.c b/trunk/drivers/i2c/i2c-core.c index 1e5606185b4f..131079a3e292 100644 --- a/trunk/drivers/i2c/i2c-core.c +++ b/trunk/drivers/i2c/i2c-core.c @@ -539,10 +539,8 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) client->dev.type = &i2c_client_type; client->dev.of_node = info->of_node; - /* For 10-bit clients, add an arbitrary offset to avoid collisions */ dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), - client->addr | ((client->flags & I2C_CLIENT_TEN) - ? 0xa000 : 0)); + client->addr); status = device_register(&client->dev); if (status) goto out_err; diff --git a/trunk/drivers/i2c/i2c-dev.c b/trunk/drivers/i2c/i2c-dev.c index 57a45ce84b2d..c90ce50b619f 100644 --- a/trunk/drivers/i2c/i2c-dev.c +++ b/trunk/drivers/i2c/i2c-dev.c @@ -579,7 +579,7 @@ static int i2cdev_detach_adapter(struct device *dev, void *dummy) return 0; } -static int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, +int i2cdev_notifier_call(struct notifier_block *nb, unsigned long action, void *data) { struct device *dev = data; diff --git a/trunk/drivers/input/mouse/elantech.c b/trunk/drivers/input/mouse/elantech.c index e2a9867c19d5..09b93b11a274 100644 --- a/trunk/drivers/input/mouse/elantech.c +++ b/trunk/drivers/input/mouse/elantech.c @@ -1210,28 +1210,18 @@ static int elantech_reconnect(struct psmouse *psmouse) */ static int elantech_set_properties(struct elantech_data *etd) { - /* This represents the version of IC body. */ int ver = (etd->fw_version & 0x0f0000) >> 16; - /* Early version of Elan touchpads doesn't obey the rule. */ if (etd->fw_version < 0x020030 || etd->fw_version == 0x020600) etd->hw_version = 1; - else { - switch (ver) { - case 2: - case 4: - etd->hw_version = 2; - break; - case 5: - etd->hw_version = 3; - break; - case 6: - etd->hw_version = 4; - break; - default: - return -1; - } - } + else if (etd->fw_version < 0x150600) + etd->hw_version = 2; + else if (ver == 5) + etd->hw_version = 3; + else if (ver == 6) + etd->hw_version = 4; + else + return -1; /* * Turn on packet checking by default. diff --git a/trunk/drivers/input/serio/ams_delta_serio.c b/trunk/drivers/input/serio/ams_delta_serio.c index d4d08bd9205b..4b2a42f9f0bb 100644 --- a/trunk/drivers/input/serio/ams_delta_serio.c +++ b/trunk/drivers/input/serio/ams_delta_serio.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/trunk/drivers/input/serio/i8042-x86ia64io.h b/trunk/drivers/input/serio/i8042-x86ia64io.h index b4cfc6c8be89..bb9f5d31f0d0 100644 --- a/trunk/drivers/input/serio/i8042-x86ia64io.h +++ b/trunk/drivers/input/serio/i8042-x86ia64io.h @@ -431,13 +431,6 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), }, }, - { - /* Newer HP Pavilion dv4 models */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), - }, - }, { } }; @@ -567,13 +560,6 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V13"), }, }, - { - /* Newer HP Pavilion dv4 models */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv4 Notebook PC"), - }, - }, { } }; diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index 5664696f2d3a..d593878d66d0 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -472,7 +472,7 @@ config BMP085 module will be called bmp085. config PCH_PHUB - tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB" + tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB" depends on PCI help This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of @@ -480,13 +480,12 @@ config PCH_PHUB processor. The Topcliff has MAC address and Option ROM data in SROM. This driver can access MAC address and Option ROM data in SROM. - This driver also can be used for LAPIS Semiconductor's IOH, - ML7213/ML7223/ML7831. - ML7213 which is for IVI(In-Vehicle Infotainment) use. - ML7223 IOH is for MP(Media Phone) use. - ML7831 IOH is for general purpose use. - ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series. - ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH. + This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ + Output Hub), ML7213 and ML7223. + ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is + for MP(Media Phone) use. + ML7213/ML7223 is companion chip for Intel Atom E6xx series. + ML7213/ML7223 is completely compatible for Intel EG20T PCH. To compile this driver as a module, choose M here: the module will be called pch_phub. diff --git a/trunk/drivers/misc/ad525x_dpot.h b/trunk/drivers/misc/ad525x_dpot.h index 82b2cb77ae19..a662f5987b68 100644 --- a/trunk/drivers/misc/ad525x_dpot.h +++ b/trunk/drivers/misc/ad525x_dpot.h @@ -100,7 +100,7 @@ enum dpot_devid { AD5293_ID = DPOT_CONF(F_RDACS_RW | F_SPI_16BIT, BRDAC0, 10, 27), AD7376_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, BRDAC0, 7, 28), - AD8400_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, + AD8400_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_8BIT, BRDAC0, 8, 29), AD8402_ID = DPOT_CONF(F_RDACS_WONLY | F_AD_APPDATA | F_SPI_16BIT, BRDAC0 | BRDAC1, 8, 30), diff --git a/trunk/drivers/misc/pch_phub.c b/trunk/drivers/misc/pch_phub.c index 10fc4785dba7..dee33addcaeb 100644 --- a/trunk/drivers/misc/pch_phub.c +++ b/trunk/drivers/misc/pch_phub.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. + * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,10 +41,10 @@ #define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset (Intel EG20T PCH)*/ #define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address - offset(LAPIS Semicon ML7213) + offset(OKI SEMICONDUCTOR ML7213) */ #define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address - offset(LAPIS Semicon ML7223) + offset(OKI SEMICONDUCTOR ML7223) */ /* MAX number of INT_REDUCE_CONTROL registers */ @@ -73,9 +73,6 @@ #define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */ #define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */ -/* Macros for ML7831 */ -#define PCI_DEVICE_ID_ROHM_ML7831_PHUB 0x8801 - /* SROM ACCESS Macro */ #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1)) @@ -118,7 +115,6 @@ * @pch_mac_start_address: MAC address area start address * @pch_opt_rom_start_address: Option ROM start address * @ioh_type: Save IOH type - * @pdev: pointer to pci device struct */ struct pch_phub_reg { u32 phub_id_reg; @@ -140,7 +136,6 @@ struct pch_phub_reg { u32 pch_mac_start_address; u32 pch_opt_rom_start_address; int ioh_type; - struct pci_dev *pdev; }; /* SROM SPEC for MAC address assignment offset */ @@ -476,7 +471,7 @@ static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data) int retval; int i; - if ((chip->ioh_type == 1) || (chip->ioh_type == 5)) /* EG20T or ML7831*/ + if (chip->ioh_type == 1) /* EG20T */ retval = pch_phub_gbe_serial_rom_conf(chip); else /* ML7223 */ retval = pch_phub_gbe_serial_rom_conf_mp(chip); @@ -503,7 +498,6 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, unsigned int orom_size; int ret; int err; - ssize_t rom_size; struct pch_phub_reg *chip = dev_get_drvdata(container_of(kobj, struct device, kobj)); @@ -515,10 +509,6 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, } /* Get Rom signature */ - chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); - if (!chip->pch_phub_extrom_base_address) - goto exrom_map_err; - pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address, (unsigned char *)&rom_signature); rom_signature &= 0xff; @@ -549,13 +539,10 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj, goto return_err; } return_ok: - pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); mutex_unlock(&pch_phub_mutex); return addr_offset; return_err: - pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); -exrom_map_err: mutex_unlock(&pch_phub_mutex); return_err_nomutex: return err; @@ -568,7 +555,6 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, int err; unsigned int addr_offset; int ret; - ssize_t rom_size; struct pch_phub_reg *chip = dev_get_drvdata(container_of(kobj, struct device, kobj)); @@ -585,12 +571,6 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, goto return_ok; } - chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); - if (!chip->pch_phub_extrom_base_address) { - err = -ENOMEM; - goto exrom_map_err; - } - for (addr_offset = 0; addr_offset < count; addr_offset++) { if (PCH_PHUB_OROM_SIZE < off + addr_offset) goto return_ok; @@ -605,14 +585,10 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj, } return_ok: - pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); mutex_unlock(&pch_phub_mutex); return addr_offset; return_err: - pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); - -exrom_map_err: mutex_unlock(&pch_phub_mutex); return err; } @@ -622,14 +598,8 @@ static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr, { u8 mac[8]; struct pch_phub_reg *chip = dev_get_drvdata(dev); - ssize_t rom_size; - - chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); - if (!chip->pch_phub_extrom_base_address) - return -ENOMEM; pch_phub_read_gbe_mac_addr(chip, mac); - pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); return sprintf(buf, "%pM\n", mac); } @@ -638,7 +608,6 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { u8 mac[6]; - ssize_t rom_size; struct pch_phub_reg *chip = dev_get_drvdata(dev); if (count != 18) @@ -648,12 +617,7 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr, (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3], (u32 *)&mac[4], (u32 *)&mac[5]); - chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size); - if (!chip->pch_phub_extrom_base_address) - return -ENOMEM; - pch_phub_write_gbe_mac_addr(chip, mac); - pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address); return count; } @@ -676,6 +640,7 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, int retval; int ret; + ssize_t rom_size; struct pch_phub_reg *chip; chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL); @@ -712,7 +677,19 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, "in pch_phub_base_address variable is %p\n", __func__, chip->pch_phub_base_address); - chip->pdev = pdev; /* Save pci device struct */ + if (id->driver_data != 3) { + chip->pch_phub_extrom_base_address =\ + pci_map_rom(pdev, &rom_size); + if (chip->pch_phub_extrom_base_address == 0) { + dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__); + ret = -ENOMEM; + goto err_pci_map; + } + dev_dbg(&pdev->dev, "%s : " + "pci_map_rom SUCCESS and value in " + "pch_phub_extrom_base_address variable is %p\n", + __func__, chip->pch_phub_extrom_base_address); + } if (id->driver_data == 1) { /* EG20T PCH */ const char *board_name; @@ -786,22 +763,6 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, chip->pch_opt_rom_start_address =\ PCH_PHUB_ROM_START_ADDR_ML7223; chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223; - } else if (id->driver_data == 5) { /* ML7831 */ - retval = sysfs_create_file(&pdev->dev.kobj, - &dev_attr_pch_mac.attr); - if (retval) - goto err_sysfs_create; - - retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr); - if (retval) - goto exit_bin_attr; - - /* set the prefech value */ - iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14); - /* set the interrupt delay value */ - iowrite32(0x25, chip->pch_phub_base_address + 0x44); - chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T; - chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T; } chip->ioh_type = id->driver_data; @@ -812,6 +773,8 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev, sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); err_sysfs_create: + pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address); +err_pci_map: pci_iounmap(pdev, chip->pch_phub_base_address); err_pci_iomap: pci_release_regions(pdev); @@ -829,6 +792,7 @@ static void __devexit pch_phub_remove(struct pci_dev *pdev) sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr); + pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address); pci_iounmap(pdev, chip->pch_phub_base_address); pci_release_regions(pdev); pci_disable_device(pdev); @@ -883,7 +847,6 @@ static struct pci_device_id pch_phub_pcidev_id[] = { { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3, }, { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4, }, - { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7831_PHUB), 5, }, { } }; MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id); @@ -910,5 +873,5 @@ static void __exit pch_phub_pci_exit(void) module_init(pch_phub_pci_init); module_exit(pch_phub_pci_exit); -MODULE_DESCRIPTION("Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7223) PHUB"); +MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/misc/spear13xx_pcie_gadget.c b/trunk/drivers/misc/spear13xx_pcie_gadget.c index 43d073bc1d9c..cfbddbef11de 100644 --- a/trunk/drivers/misc/spear13xx_pcie_gadget.c +++ b/trunk/drivers/misc/spear13xx_pcie_gadget.c @@ -903,6 +903,6 @@ static void __exit spear_pcie_gadget_exit(void) } module_exit(spear_pcie_gadget_exit); -MODULE_ALIAS("platform:pcie-gadget-spear"); +MODULE_ALIAS("pcie-gadget-spear"); MODULE_AUTHOR("Pratyush Anand"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/of/irq.c b/trunk/drivers/of/irq.c index 791270b8bd1c..6d3dd3988d0f 100644 --- a/trunk/drivers/of/irq.c +++ b/trunk/drivers/of/irq.c @@ -60,27 +60,27 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map); */ struct device_node *of_irq_find_parent(struct device_node *child) { - struct device_node *p; + struct device_node *p, *c = child; const __be32 *parp; - if (!of_node_get(child)) + if (!of_node_get(c)) return NULL; do { - parp = of_get_property(child, "interrupt-parent", NULL); + parp = of_get_property(c, "interrupt-parent", NULL); if (parp == NULL) - p = of_get_parent(child); + p = of_get_parent(c); else { if (of_irq_workarounds & OF_IMAP_NO_PHANDLE) p = of_node_get(of_irq_dflt_pic); else p = of_find_node_by_phandle(be32_to_cpup(parp)); } - of_node_put(child); - child = p; + of_node_put(c); + c = p; } while (p && of_get_property(p, "#interrupt-cells", NULL) == NULL); - return p; + return (p == child) ? NULL : p; } /** diff --git a/trunk/drivers/regulator/tps65910-regulator.c b/trunk/drivers/regulator/tps65910-regulator.c index b552aae55b41..66d2d60b436a 100644 --- a/trunk/drivers/regulator/tps65910-regulator.c +++ b/trunk/drivers/regulator/tps65910-regulator.c @@ -664,10 +664,10 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, switch (id) { case TPS65910_REG_VDD1: - dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; + dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; if (dcdc_mult == 1) dcdc_mult--; - vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3; + vsel = (selector % VDD1_2_NUM_VOLTS) + 3; tps65910_modify_bits(pmic, TPS65910_VDD1, (dcdc_mult << VDD1_VGAIN_SEL_SHIFT), @@ -675,10 +675,10 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel); break; case TPS65910_REG_VDD2: - dcdc_mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; + dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1; if (dcdc_mult == 1) dcdc_mult--; - vsel = (selector % VDD1_2_NUM_VOLT_FINE) + 3; + vsel = (selector % VDD1_2_NUM_VOLTS) + 3; tps65910_modify_bits(pmic, TPS65910_VDD2, (dcdc_mult << VDD2_VGAIN_SEL_SHIFT), @@ -756,9 +756,9 @@ static int tps65910_list_voltage_dcdc(struct regulator_dev *dev, switch (id) { case TPS65910_REG_VDD1: case TPS65910_REG_VDD2: - mult = (selector / VDD1_2_NUM_VOLT_FINE) + 1; + mult = (selector / VDD1_2_NUM_VOLTS) + 1; volt = VDD1_2_MIN_VOLT + - (selector % VDD1_2_NUM_VOLT_FINE) * VDD1_2_OFFSET; + (selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET; break; case TPS65911_REG_VDDCTRL: volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET); @@ -947,8 +947,6 @@ static __devinit int tps65910_probe(struct platform_device *pdev) if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { pmic->desc[i].ops = &tps65910_ops_dcdc; - pmic->desc[i].n_voltages = VDD1_2_NUM_VOLT_FINE * - VDD1_2_NUM_VOLT_COARSE; } else if (i == TPS65910_REG_VDD3) { if (tps65910_chip_id(tps65910) == TPS65910) pmic->desc[i].ops = &tps65910_ops_vdd3; diff --git a/trunk/drivers/staging/et131x/Kconfig b/trunk/drivers/staging/et131x/Kconfig index 8190f2aaf53b..9e1864c6dfd0 100644 --- a/trunk/drivers/staging/et131x/Kconfig +++ b/trunk/drivers/staging/et131x/Kconfig @@ -1,7 +1,6 @@ config ET131X tristate "Agere ET-1310 Gigabit Ethernet support" - depends on PCI && NET && NETDEVICES - select PHYLIB + depends on PCI default n ---help--- This driver supports Agere ET-1310 ethernet adapters. diff --git a/trunk/drivers/staging/et131x/et131x.c b/trunk/drivers/staging/et131x/et131x.c index 0c1c6ca8c379..f5f44a02456f 100644 --- a/trunk/drivers/staging/et131x/et131x.c +++ b/trunk/drivers/staging/et131x/et131x.c @@ -4469,12 +4469,6 @@ static int et131x_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(et131x_pm_ops, et131x_suspend, et131x_resume); -#define ET131X_PM_OPS (&et131x_pm_ops) -#else -#define ET131X_PM_OPS NULL -#endif - /* ISR functions */ /** @@ -5476,6 +5470,12 @@ static int __devinit et131x_pci_setup(struct pci_dev *pdev, return result; } +static SIMPLE_DEV_PM_OPS(et131x_pm_ops, et131x_suspend, et131x_resume); +#define ET131X_PM_OPS (&et131x_pm_ops) +#else +#define ET131X_PM_OPS NULL +#endif + static DEFINE_PCI_DEVICE_TABLE(et131x_pci_table) = { { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_GIG), 0UL}, { PCI_VDEVICE(ATT, ET131X_PCI_DEVICE_ID_FAST), 0UL}, diff --git a/trunk/drivers/staging/iio/industrialio-core.c b/trunk/drivers/staging/iio/industrialio-core.c index 26564094e33b..326e967d54ef 100644 --- a/trunk/drivers/staging/iio/industrialio-core.c +++ b/trunk/drivers/staging/iio/industrialio-core.c @@ -242,8 +242,6 @@ static const struct file_operations iio_event_chrdev_fileops = { static int iio_event_getfd(struct iio_dev *indio_dev) { - int fd; - if (indio_dev->event_interface == NULL) return -ENODEV; @@ -254,15 +252,9 @@ static int iio_event_getfd(struct iio_dev *indio_dev) return -EBUSY; } mutex_unlock(&indio_dev->event_interface->event_list_lock); - fd = anon_inode_getfd("iio:event", + return anon_inode_getfd("iio:event", &iio_event_chrdev_fileops, indio_dev->event_interface, O_RDONLY); - if (fd < 0) { - mutex_lock(&indio_dev->event_interface->event_list_lock); - clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags); - mutex_unlock(&indio_dev->event_interface->event_list_lock); - } - return fd; } static int __init iio_init(void) diff --git a/trunk/drivers/staging/slicoss/Kconfig b/trunk/drivers/staging/slicoss/Kconfig index 5c2a15b42dfe..5cde96b2e6e1 100644 --- a/trunk/drivers/staging/slicoss/Kconfig +++ b/trunk/drivers/staging/slicoss/Kconfig @@ -1,6 +1,6 @@ config SLICOSS tristate "Alacritech Gigabit IS-NIC support" - depends on PCI && X86 && NET + depends on PCI && X86 default n help This driver supports Alacritech's IS-NIC gigabit ethernet cards. diff --git a/trunk/drivers/tty/hvc/hvc_dcc.c b/trunk/drivers/tty/hvc/hvc_dcc.c index 44fbebab5075..435f6facbc23 100644 --- a/trunk/drivers/tty/hvc/hvc_dcc.c +++ b/trunk/drivers/tty/hvc/hvc_dcc.c @@ -46,7 +46,6 @@ static inline char __dcc_getchar(void) asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg" : "=r" (__c)); - isb(); return __c; } @@ -56,7 +55,6 @@ static inline void __dcc_putchar(char c) asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char" : /* no output register */ : "r" (c)); - isb(); } static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count) diff --git a/trunk/drivers/tty/serial/Kconfig b/trunk/drivers/tty/serial/Kconfig index 925a1e547a83..5f479dada6f2 100644 --- a/trunk/drivers/tty/serial/Kconfig +++ b/trunk/drivers/tty/serial/Kconfig @@ -1560,7 +1560,7 @@ config SERIAL_IFX6X60 Support for the IFX6x60 modem devices on Intel MID platforms. config SERIAL_PCH_UART - tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) UART" + tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) UART" depends on PCI select SERIAL_CORE help @@ -1568,12 +1568,12 @@ config SERIAL_PCH_UART which is an IOH(Input/Output Hub) for x86 embedded processor. Enabling PCH_DMA, this PCH UART works as DMA mode. - This driver also can be used for LAPIS Semiconductor IOH(Input/ - Output Hub), ML7213, ML7223 and ML7831. - ML7213 IOH is for IVI(In-Vehicle Infotainment) use, ML7223 IOH is - for MP(Media Phone) use and ML7831 IOH is for general purpose use. - ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series. - ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH. + This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ + Output Hub), ML7213 and ML7223. + ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is + for MP(Media Phone) use. + ML7213/ML7223 is companion chip for Intel Atom E6xx series. + ML7213/ML7223 is completely compatible for Intel EG20T PCH. config SERIAL_MSM_SMD bool "Enable tty device interface for some SMD ports" diff --git a/trunk/drivers/tty/serial/atmel_serial.c b/trunk/drivers/tty/serial/atmel_serial.c index 4c823f341d98..4a0f86fa1e90 100644 --- a/trunk/drivers/tty/serial/atmel_serial.c +++ b/trunk/drivers/tty/serial/atmel_serial.c @@ -228,7 +228,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf) if (rs485conf->flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); atmel_port->tx_done_mask = ATMEL_US_TXEMPTY; - if ((rs485conf->delay_rts_after_send) > 0) + if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND) UART_PUT_TTGR(port, rs485conf->delay_rts_after_send); mode |= ATMEL_US_USMODE_RS485; } else { @@ -304,7 +304,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl) if (atmel_port->rs485.flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); - if ((atmel_port->rs485.delay_rts_after_send) > 0) + if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND) UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_after_send); mode |= ATMEL_US_USMODE_RS485; @@ -1228,7 +1228,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios, if (atmel_port->rs485.flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); - if ((atmel_port->rs485.delay_rts_after_send) > 0) + if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND) UART_PUT_TTGR(port, atmel_port->rs485.delay_rts_after_send); mode |= ATMEL_US_USMODE_RS485; @@ -1447,6 +1447,16 @@ static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port, rs485conf->delay_rts_after_send = rs485_delay[1]; rs485conf->flags = 0; + if (rs485conf->delay_rts_before_send == 0 && + rs485conf->delay_rts_after_send == 0) { + rs485conf->flags |= SER_RS485_RTS_ON_SEND; + } else { + if (rs485conf->delay_rts_before_send) + rs485conf->flags |= SER_RS485_RTS_BEFORE_SEND; + if (rs485conf->delay_rts_after_send) + rs485conf->flags |= SER_RS485_RTS_AFTER_SEND; + } + if (of_get_property(np, "rs485-rx-during-tx", NULL)) rs485conf->flags |= SER_RS485_RX_DURING_TX; diff --git a/trunk/drivers/tty/serial/crisv10.c b/trunk/drivers/tty/serial/crisv10.c index 1dfba7b779c8..b7435043f2fe 100644 --- a/trunk/drivers/tty/serial/crisv10.c +++ b/trunk/drivers/tty/serial/crisv10.c @@ -3234,8 +3234,9 @@ rs_write(struct tty_struct *tty, e100_disable_rx(info); e100_enable_rx_irq(info); #endif - if (info->rs485.delay_rts_before_send > 0) - msleep(info->rs485.delay_rts_before_send); + if ((info->rs485.flags & SER_RS485_RTS_BEFORE_SEND) && + (info->rs485.delay_rts_before_send > 0)) + msleep(info->rs485.delay_rts_before_send); } #endif /* CONFIG_ETRAX_RS485 */ @@ -3692,6 +3693,10 @@ rs_ioctl(struct tty_struct *tty, rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send; rs485data.flags = 0; + if (rs485data.delay_rts_before_send != 0) + rs485data.flags |= SER_RS485_RTS_BEFORE_SEND; + else + rs485data.flags &= ~(SER_RS485_RTS_BEFORE_SEND); if (rs485ctrl.enabled) rs485data.flags |= SER_RS485_ENABLED; @@ -4526,6 +4531,7 @@ static int __init rs_init(void) /* Set sane defaults */ info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND); info->rs485.flags |= SER_RS485_RTS_AFTER_SEND; + info->rs485.flags &= ~(SER_RS485_RTS_BEFORE_SEND); info->rs485.delay_rts_before_send = 0; info->rs485.flags &= ~(SER_RS485_ENABLED); #endif diff --git a/trunk/drivers/tty/serial/mfd.c b/trunk/drivers/tty/serial/mfd.c index e272d3919c67..286c386d9c46 100644 --- a/trunk/drivers/tty/serial/mfd.c +++ b/trunk/drivers/tty/serial/mfd.c @@ -884,6 +884,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, { struct uart_hsu_port *up = container_of(port, struct uart_hsu_port, port); + struct tty_struct *tty = port->state->port.tty; unsigned char cval, fcr = 0; unsigned long flags; unsigned int baud, quot; @@ -906,7 +907,8 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, } /* CMSPAR isn't supported by this driver */ - termios->c_cflag &= ~CMSPAR; + if (tty) + tty->termios->c_cflag &= ~CMSPAR; if (termios->c_cflag & CSTOPB) cval |= UART_LCR_STOP; diff --git a/trunk/drivers/tty/serial/pch_uart.c b/trunk/drivers/tty/serial/pch_uart.c index d6aba8c087e4..21febef926aa 100644 --- a/trunk/drivers/tty/serial/pch_uart.c +++ b/trunk/drivers/tty/serial/pch_uart.c @@ -1,5 +1,5 @@ /* - *Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. + *Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. * *This program is free software; you can redistribute it and/or modify *it under the terms of the GNU General Public License as published by @@ -46,8 +46,8 @@ enum { /* Set the max number of UART port * Intel EG20T PCH: 4 port - * LAPIS Semiconductor ML7213 IOH: 3 port - * LAPIS Semiconductor ML7223 IOH: 2 port + * OKI SEMICONDUCTOR ML7213 IOH: 3 port + * OKI SEMICONDUCTOR ML7223 IOH: 2 port */ #define PCH_UART_NR 4 @@ -258,8 +258,6 @@ enum pch_uart_num_t { pch_ml7213_uart2, pch_ml7223_uart0, pch_ml7223_uart1, - pch_ml7831_uart0, - pch_ml7831_uart1, }; static struct pch_uart_driver_data drv_dat[] = { @@ -272,8 +270,6 @@ static struct pch_uart_driver_data drv_dat[] = { [pch_ml7213_uart2] = {PCH_UART_2LINE, 2}, [pch_ml7223_uart0] = {PCH_UART_8LINE, 0}, [pch_ml7223_uart1] = {PCH_UART_2LINE, 1}, - [pch_ml7831_uart0] = {PCH_UART_8LINE, 0}, - [pch_ml7831_uart1] = {PCH_UART_2LINE, 1}, }; static unsigned int default_baud = 9600; @@ -632,7 +628,6 @@ static void pch_request_dma(struct uart_port *port) dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n", __func__); dma_release_channel(priv->chan_tx); - priv->chan_tx = NULL; return; } @@ -1220,7 +1215,8 @@ static void pch_uart_shutdown(struct uart_port *port) dev_err(priv->port.dev, "pch_uart_hal_set_fifo Failed(ret=%d)\n", ret); - pch_free_dma(port); + if (priv->use_dma_flag) + pch_free_dma(port); free_irq(priv->port.irq, priv); } @@ -1284,7 +1280,6 @@ static void pch_uart_set_termios(struct uart_port *port, if (rtn) goto out; - pch_uart_set_mctrl(&priv->port, priv->port.mctrl); /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); @@ -1557,10 +1552,6 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = { .driver_data = pch_ml7223_uart0}, {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D), .driver_data = pch_ml7223_uart1}, - {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8811), - .driver_data = pch_ml7831_uart0}, - {PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8812), - .driver_data = pch_ml7831_uart1}, {0,}, }; diff --git a/trunk/drivers/tty/tty_ldisc.c b/trunk/drivers/tty/tty_ldisc.c index 8e0924f55446..512c49f98e85 100644 --- a/trunk/drivers/tty/tty_ldisc.c +++ b/trunk/drivers/tty/tty_ldisc.c @@ -36,7 +36,6 @@ #include #include -#include /* * This guards the refcounted line discipline lists. The lock @@ -548,16 +547,15 @@ static void tty_ldisc_flush_works(struct tty_struct *tty) /** * tty_ldisc_wait_idle - wait for the ldisc to become idle * @tty: tty to wait for - * @timeout: for how long to wait at most * * Wait for the line discipline to become idle. The discipline must * have been halted for this to guarantee it remains idle. */ -static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout) +static int tty_ldisc_wait_idle(struct tty_struct *tty) { - long ret; + int ret; ret = wait_event_timeout(tty_ldisc_idle, - atomic_read(&tty->ldisc->users) == 1, timeout); + atomic_read(&tty->ldisc->users) == 1, 5 * HZ); if (ret < 0) return ret; return ret > 0 ? 0 : -EBUSY; @@ -667,7 +665,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) tty_ldisc_flush_works(tty); - retval = tty_ldisc_wait_idle(tty, 5 * HZ); + retval = tty_ldisc_wait_idle(tty); tty_lock(); mutex_lock(&tty->ldisc_mutex); @@ -764,6 +762,8 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc) if (IS_ERR(ld)) return -1; + WARN_ON_ONCE(tty_ldisc_wait_idle(tty)); + tty_ldisc_close(tty, tty->ldisc); tty_ldisc_put(tty->ldisc); tty->ldisc = NULL; @@ -838,7 +838,7 @@ void tty_ldisc_hangup(struct tty_struct *tty) tty_unlock(); cancel_work_sync(&tty->buf.work); mutex_unlock(&tty->ldisc_mutex); -retry: + tty_lock(); mutex_lock(&tty->ldisc_mutex); @@ -847,22 +847,6 @@ void tty_ldisc_hangup(struct tty_struct *tty) it means auditing a lot of other paths so this is a FIXME */ if (tty->ldisc) { /* Not yet closed */ - if (atomic_read(&tty->ldisc->users) != 1) { - char cur_n[TASK_COMM_LEN], tty_n[64]; - long timeout = 3 * HZ; - tty_unlock(); - - while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { - timeout = MAX_SCHEDULE_TIMEOUT; - printk_ratelimited(KERN_WARNING - "%s: waiting (%s) for %s took too long, but we keep waiting...\n", - __func__, get_task_comm(cur_n, current), - tty_name(tty, tty_n)); - } - mutex_unlock(&tty->ldisc_mutex); - goto retry; - } - if (reset == 0) { if (!tty_ldisc_reinit(tty, tty->termios->c_line)) diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index e8c564a53346..6960715c5063 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -539,6 +539,7 @@ static void acm_port_down(struct acm *acm) { int i; + mutex_lock(&open_mutex); if (acm->dev) { usb_autopm_get_interface(acm->control); acm_set_control(acm, acm->ctrlout = 0); @@ -550,15 +551,14 @@ static void acm_port_down(struct acm *acm) acm->control->needs_remote_wakeup = 0; usb_autopm_put_interface(acm->control); } + mutex_unlock(&open_mutex); } static void acm_tty_hangup(struct tty_struct *tty) { struct acm *acm = tty->driver_data; tty_port_hangup(&acm->port); - mutex_lock(&open_mutex); acm_port_down(acm); - mutex_unlock(&open_mutex); } static void acm_tty_close(struct tty_struct *tty, struct file *filp) @@ -569,9 +569,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) shutdown */ if (!acm) return; - - mutex_lock(&open_mutex); if (tty_port_close_start(&acm->port, tty, filp) == 0) { + mutex_lock(&open_mutex); if (!acm->dev) { tty_port_tty_set(&acm->port, NULL); acm_tty_unregister(acm); @@ -583,7 +582,6 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) acm_port_down(acm); tty_port_close_end(&acm->port, tty); tty_port_tty_set(&acm->port, NULL); - mutex_unlock(&open_mutex); } static int acm_tty_write(struct tty_struct *tty, diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 79781461eec9..96f05b29c9ad 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -813,12 +813,6 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) USB_PORT_FEAT_C_PORT_LINK_STATE); } - if ((portchange & USB_PORT_STAT_C_BH_RESET) && - hub_is_superspeed(hub->hdev)) { - need_debounce_delay = true; - clear_port_feature(hub->hdev, port1, - USB_PORT_FEAT_C_BH_PORT_RESET); - } /* We can forget about a "removed" device when there's a * physical disconnect or the connect status changes. */ diff --git a/trunk/drivers/usb/core/quirks.c b/trunk/drivers/usb/core/quirks.c index ecf12e15a7ef..d6a8d8269bfb 100644 --- a/trunk/drivers/usb/core/quirks.c +++ b/trunk/drivers/usb/core/quirks.c @@ -50,42 +50,15 @@ static const struct usb_device_id usb_quirk_list[] = { /* Logitech Webcam B/C500 */ { USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Webcam C600 */ - { USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Webcam Pro 9000 */ { USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Webcam C905 */ - { USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C210 */ - { USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C260 */ - { USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Webcam C310 */ { USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Webcam C910 */ - { USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Webcam C160 */ - { USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Webcam C270 */ { USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Quickcam Pro 9000 */ - { USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Quickcam E3500 */ - { USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME }, - - /* Logitech Quickcam Vision Pro */ - { USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME }, - /* Logitech Harmony 700-series */ { USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT }, diff --git a/trunk/drivers/usb/dwc3/gadget.c b/trunk/drivers/usb/dwc3/gadget.c index 25dbd8614e72..fa824cfdd2eb 100644 --- a/trunk/drivers/usb/dwc3/gadget.c +++ b/trunk/drivers/usb/dwc3/gadget.c @@ -1284,7 +1284,6 @@ static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc) int ret; dep->endpoint.maxpacket = 1024; - dep->endpoint.max_streams = 15; dep->endpoint.ops = &dwc3_gadget_ep_ops; list_add_tail(&dep->endpoint.ep_list, &dwc->gadget.ep_list); diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index 23a447373c51..b21cd376c11a 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -469,7 +469,7 @@ config USB_LANGWELL gadget drivers to also be dynamically linked. config USB_EG20T - tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC" + tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC" depends on PCI select USB_GADGET_DUALSPEED help @@ -485,11 +485,10 @@ config USB_EG20T This driver dose not support interrupt transfer or isochronous transfer modes. - This driver also can be used for LAPIS Semiconductor's ML7213 which is + This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is for IVI(In-Vehicle Infotainment) use. - ML7831 is for general purpose use. - ML7213/ML7831 is companion chip for Intel Atom E6xx series. - ML7213/ML7831 is completely compatible for Intel EG20T PCH. + ML7213 is companion chip for Intel Atom E6xx series. + ML7213 is completely compatible for Intel EG20T PCH. config USB_CI13XXX_MSM tristate "MIPS USB CI13xxx for MSM" diff --git a/trunk/drivers/usb/gadget/ci13xxx_msm.c b/trunk/drivers/usb/gadget/ci13xxx_msm.c index 1fc612914c52..4eedfe557154 100644 --- a/trunk/drivers/usb/gadget/ci13xxx_msm.c +++ b/trunk/drivers/usb/gadget/ci13xxx_msm.c @@ -122,5 +122,3 @@ static int __init ci13xxx_msm_init(void) return platform_driver_register(&ci13xxx_msm_driver); } module_init(ci13xxx_msm_init); - -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/usb/gadget/ci13xxx_udc.c b/trunk/drivers/usb/gadget/ci13xxx_udc.c index 9a0c3979ff43..83428f56253b 100644 --- a/trunk/drivers/usb/gadget/ci13xxx_udc.c +++ b/trunk/drivers/usb/gadget/ci13xxx_udc.c @@ -71,9 +71,6 @@ /****************************************************************************** * DEFINE *****************************************************************************/ - -#define DMA_ADDR_INVALID (~(dma_addr_t)0) - /* ctrl register bank access */ static DEFINE_SPINLOCK(udc_lock); @@ -1437,7 +1434,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) return -EALREADY; mReq->req.status = -EALREADY; - if (length && mReq->req.dma == DMA_ADDR_INVALID) { + if (length && !mReq->req.dma) { mReq->req.dma = \ dma_map_single(mEp->device, mReq->req.buf, length, mEp->dir ? DMA_TO_DEVICE : @@ -1456,7 +1453,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) dma_unmap_single(mEp->device, mReq->req.dma, length, mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - mReq->req.dma = DMA_ADDR_INVALID; + mReq->req.dma = 0; mReq->map = 0; } return -ENOMEM; @@ -1552,7 +1549,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq) if (mReq->map) { dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - mReq->req.dma = DMA_ADDR_INVALID; + mReq->req.dma = 0; mReq->map = 0; } @@ -1613,6 +1610,7 @@ __acquires(mEp->lock) * @gadget: gadget * * This function returns an error code + * Caller must hold lock */ static int _gadget_stop_activity(struct usb_gadget *gadget) { @@ -2191,7 +2189,6 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags); if (mReq != NULL) { INIT_LIST_HEAD(&mReq->queue); - mReq->req.dma = DMA_ADDR_INVALID; mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags, &mReq->dma); @@ -2331,7 +2328,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req) if (mReq->map) { dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length, mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - mReq->req.dma = DMA_ADDR_INVALID; + mReq->req.dma = 0; mReq->map = 0; } req->status = -ECONNRESET; @@ -2503,12 +2500,12 @@ static int ci13xxx_wakeup(struct usb_gadget *_gadget) spin_lock_irqsave(udc->lock, flags); if (!udc->remote_wakeup) { ret = -EOPNOTSUPP; - trace("remote wakeup feature is not enabled\n"); + dbg_trace("remote wakeup feature is not enabled\n"); goto out; } if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) { ret = -EINVAL; - trace("port is not suspended\n"); + dbg_trace("port is not suspended\n"); goto out; } hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR); @@ -2706,9 +2703,7 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver) if (udc->udc_driver->notify_event) udc->udc_driver->notify_event(udc, CI13XXX_CONTROLLER_STOPPED_EVENT); - spin_unlock_irqrestore(udc->lock, flags); _gadget_stop_activity(&udc->gadget); - spin_lock_irqsave(udc->lock, flags); pm_runtime_put(&udc->gadget.dev); } @@ -2855,7 +2850,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, struct ci13xxx *udc; int retval = 0; - trace("%p, %p, %p", dev, regs, driver->name); + trace("%p, %p, %p", dev, regs, name); if (dev == NULL || regs == NULL || driver == NULL || driver->name == NULL) diff --git a/trunk/drivers/usb/gadget/f_mass_storage.c b/trunk/drivers/usb/gadget/f_mass_storage.c index c39d58860fa0..52583a235330 100644 --- a/trunk/drivers/usb/gadget/f_mass_storage.c +++ b/trunk/drivers/usb/gadget/f_mass_storage.c @@ -624,8 +624,7 @@ static int fsg_setup(struct usb_function *f, if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) break; - if (w_index != fsg->interface_number || w_value != 0 || - w_length != 0) + if (w_index != fsg->interface_number || w_value != 0) return -EDOM; /* @@ -640,8 +639,7 @@ static int fsg_setup(struct usb_function *f, if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) break; - if (w_index != fsg->interface_number || w_value != 0 || - w_length != 1) + if (w_index != fsg->interface_number || w_value != 0) return -EDOM; VDBG(fsg, "get max LUN\n"); *(u8 *)req->buf = fsg->common->nluns - 1; diff --git a/trunk/drivers/usb/gadget/f_midi.c b/trunk/drivers/usb/gadget/f_midi.c index 3797b3d6c622..67b222908cf9 100644 --- a/trunk/drivers/usb/gadget/f_midi.c +++ b/trunk/drivers/usb/gadget/f_midi.c @@ -95,6 +95,7 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req); DECLARE_UAC_AC_HEADER_DESCRIPTOR(1); DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); +DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(16); DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16); /* B.3.1 Standard AC Interface Descriptor */ @@ -139,6 +140,26 @@ static struct usb_ms_header_descriptor ms_header_desc __initdata = { /* .wTotalLength = DYNAMIC */ }; +/* B.4.3 Embedded MIDI IN Jack Descriptor */ +static struct usb_midi_in_jack_descriptor jack_in_emb_desc = { + .bLength = USB_DT_MIDI_IN_SIZE, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubtype = USB_MS_MIDI_IN_JACK, + .bJackType = USB_MS_EMBEDDED, + /* .bJackID = DYNAMIC */ +}; + +/* B.4.4 Embedded MIDI OUT Jack Descriptor */ +static struct usb_midi_out_jack_descriptor_16 jack_out_emb_desc = { + /* .bLength = DYNAMIC */ + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubtype = USB_MS_MIDI_OUT_JACK, + .bJackType = USB_MS_EMBEDDED, + /* .bJackID = DYNAMIC */ + /* .bNrInputPins = DYNAMIC */ + /* .pins = DYNAMIC */ +}; + /* B.5.1 Standard Bulk OUT Endpoint Descriptor */ static struct usb_endpoint_descriptor bulk_out_desc = { .bLength = USB_DT_ENDPOINT_AUDIO_SIZE, @@ -737,11 +758,9 @@ static int f_midi_register_card(struct f_midi *midi) static int __init f_midi_bind(struct usb_configuration *c, struct usb_function *f) { - struct usb_descriptor_header **midi_function; + struct usb_descriptor_header *midi_function[(MAX_PORTS * 2) + 12]; struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS]; - struct usb_midi_in_jack_descriptor jack_in_emb_desc[MAX_PORTS]; struct usb_midi_out_jack_descriptor_1 jack_out_ext_desc[MAX_PORTS]; - struct usb_midi_out_jack_descriptor_1 jack_out_emb_desc[MAX_PORTS]; struct usb_composite_dev *cdev = c->cdev; struct f_midi *midi = func_to_midi(f); int status, n, jack = 1, i = 0; @@ -779,14 +798,6 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f) goto fail; midi->out_ep->driver_data = cdev; /* claim */ - /* allocate temporary function list */ - midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(midi_function), - GFP_KERNEL); - if (!midi_function) { - status = -ENOMEM; - goto fail; - } - /* * construct the function's descriptor set. As the number of * input and output MIDI ports is configurable, we have to do @@ -800,74 +811,73 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f) /* calculate the header's wTotalLength */ n = USB_DT_MS_HEADER_SIZE - + (midi->in_ports + midi->out_ports) * - (USB_DT_MIDI_IN_SIZE + USB_DT_MIDI_OUT_SIZE(1)); + + (1 + midi->in_ports) * USB_DT_MIDI_IN_SIZE + + (1 + midi->out_ports) * USB_DT_MIDI_OUT_SIZE(1); ms_header_desc.wTotalLength = cpu_to_le16(n); midi_function[i++] = (struct usb_descriptor_header *) &ms_header_desc; - /* configure the external IN jacks, each linked to an embedded OUT jack */ + /* we have one embedded IN jack */ + jack_in_emb_desc.bJackID = jack++; + midi_function[i++] = (struct usb_descriptor_header *) &jack_in_emb_desc; + + /* and a dynamic amount of external IN jacks */ + for (n = 0; n < midi->in_ports; n++) { + struct usb_midi_in_jack_descriptor *ext = &jack_in_ext_desc[n]; + + ext->bLength = USB_DT_MIDI_IN_SIZE; + ext->bDescriptorType = USB_DT_CS_INTERFACE; + ext->bDescriptorSubtype = USB_MS_MIDI_IN_JACK; + ext->bJackType = USB_MS_EXTERNAL; + ext->bJackID = jack++; + ext->iJack = 0; + + midi_function[i++] = (struct usb_descriptor_header *) ext; + } + + /* one embedded OUT jack ... */ + jack_out_emb_desc.bLength = USB_DT_MIDI_OUT_SIZE(midi->in_ports); + jack_out_emb_desc.bJackID = jack++; + jack_out_emb_desc.bNrInputPins = midi->in_ports; + /* ... which referencess all external IN jacks */ for (n = 0; n < midi->in_ports; n++) { - struct usb_midi_in_jack_descriptor *in_ext = &jack_in_ext_desc[n]; - struct usb_midi_out_jack_descriptor_1 *out_emb = &jack_out_emb_desc[n]; - - in_ext->bLength = USB_DT_MIDI_IN_SIZE; - in_ext->bDescriptorType = USB_DT_CS_INTERFACE; - in_ext->bDescriptorSubtype = USB_MS_MIDI_IN_JACK; - in_ext->bJackType = USB_MS_EXTERNAL; - in_ext->bJackID = jack++; - in_ext->iJack = 0; - midi_function[i++] = (struct usb_descriptor_header *) in_ext; - - out_emb->bLength = USB_DT_MIDI_OUT_SIZE(1); - out_emb->bDescriptorType = USB_DT_CS_INTERFACE; - out_emb->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK; - out_emb->bJackType = USB_MS_EMBEDDED; - out_emb->bJackID = jack++; - out_emb->bNrInputPins = 1; - out_emb->pins[0].baSourcePin = 1; - out_emb->pins[0].baSourceID = in_ext->bJackID; - out_emb->iJack = 0; - midi_function[i++] = (struct usb_descriptor_header *) out_emb; - - /* link it to the endpoint */ - ms_in_desc.baAssocJackID[n] = out_emb->bJackID; + jack_out_emb_desc.pins[n].baSourceID = jack_in_ext_desc[n].bJackID; + jack_out_emb_desc.pins[n].baSourcePin = 1; } - /* configure the external OUT jacks, each linked to an embedded IN jack */ + midi_function[i++] = (struct usb_descriptor_header *) &jack_out_emb_desc; + + /* and multiple external OUT jacks ... */ for (n = 0; n < midi->out_ports; n++) { - struct usb_midi_in_jack_descriptor *in_emb = &jack_in_emb_desc[n]; - struct usb_midi_out_jack_descriptor_1 *out_ext = &jack_out_ext_desc[n]; - - in_emb->bLength = USB_DT_MIDI_IN_SIZE; - in_emb->bDescriptorType = USB_DT_CS_INTERFACE; - in_emb->bDescriptorSubtype = USB_MS_MIDI_IN_JACK; - in_emb->bJackType = USB_MS_EMBEDDED; - in_emb->bJackID = jack++; - in_emb->iJack = 0; - midi_function[i++] = (struct usb_descriptor_header *) in_emb; - - out_ext->bLength = USB_DT_MIDI_OUT_SIZE(1); - out_ext->bDescriptorType = USB_DT_CS_INTERFACE; - out_ext->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK; - out_ext->bJackType = USB_MS_EXTERNAL; - out_ext->bJackID = jack++; - out_ext->bNrInputPins = 1; - out_ext->iJack = 0; - out_ext->pins[0].baSourceID = in_emb->bJackID; - out_ext->pins[0].baSourcePin = 1; - midi_function[i++] = (struct usb_descriptor_header *) out_ext; - - /* link it to the endpoint */ - ms_out_desc.baAssocJackID[n] = in_emb->bJackID; + struct usb_midi_out_jack_descriptor_1 *ext = &jack_out_ext_desc[n]; + int m; + + ext->bLength = USB_DT_MIDI_OUT_SIZE(1); + ext->bDescriptorType = USB_DT_CS_INTERFACE; + ext->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK; + ext->bJackType = USB_MS_EXTERNAL; + ext->bJackID = jack++; + ext->bNrInputPins = 1; + ext->iJack = 0; + /* ... which all reference the same embedded IN jack */ + for (m = 0; m < midi->out_ports; m++) { + ext->pins[m].baSourceID = jack_in_emb_desc.bJackID; + ext->pins[m].baSourcePin = 1; + } + + midi_function[i++] = (struct usb_descriptor_header *) ext; } /* configure the endpoint descriptors ... */ ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports); ms_out_desc.bNumEmbMIDIJack = midi->in_ports; + for (n = 0; n < midi->in_ports; n++) + ms_out_desc.baAssocJackID[n] = jack_in_emb_desc.bJackID; ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports); ms_in_desc.bNumEmbMIDIJack = midi->out_ports; + for (n = 0; n < midi->out_ports; n++) + ms_in_desc.baAssocJackID[n] = jack_out_emb_desc.bJackID; /* ... and add them to the list */ midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc; @@ -891,8 +901,6 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f) f->descriptors = usb_copy_descriptors(midi_function); } - kfree(midi_function); - return 0; fail: diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index 11b5196284ae..f7e39b0365ce 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -859,7 +859,7 @@ static int class_setup_req(struct fsg_dev *fsg, if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) break; - if (w_index != 0 || w_value != 0 || w_length != 0) { + if (w_index != 0 || w_value != 0) { value = -EDOM; break; } @@ -875,7 +875,7 @@ static int class_setup_req(struct fsg_dev *fsg, if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) break; - if (w_index != 0 || w_value != 0 || w_length != 1) { + if (w_index != 0 || w_value != 0) { value = -EDOM; break; } diff --git a/trunk/drivers/usb/gadget/fsl_udc_core.c b/trunk/drivers/usb/gadget/fsl_udc_core.c index b3b3d83b7c33..d786ba31fc07 100644 --- a/trunk/drivers/usb/gadget/fsl_udc_core.c +++ b/trunk/drivers/usb/gadget/fsl_udc_core.c @@ -2480,7 +2480,8 @@ static int __init fsl_udc_probe(struct platform_device *pdev) #ifndef CONFIG_ARCH_MXC if (pdata->have_sysif_regs) - usb_sys_regs = (void *)dr_regs + USB_DR_SYS_OFFSET; + usb_sys_regs = (struct usb_sys_interface *) + ((u32)dr_regs + USB_DR_SYS_OFFSET); #endif /* Initialize USB clocks */ diff --git a/trunk/drivers/usb/gadget/inode.c b/trunk/drivers/usb/gadget/inode.c index 6ccae2707e59..a392ec0d2d51 100644 --- a/trunk/drivers/usb/gadget/inode.c +++ b/trunk/drivers/usb/gadget/inode.c @@ -1730,9 +1730,8 @@ static void gadgetfs_disconnect (struct usb_gadget *gadget) { struct dev_data *dev = get_gadget_data (gadget); - unsigned long flags; - spin_lock_irqsave (&dev->lock, flags); + spin_lock (&dev->lock); if (dev->state == STATE_DEV_UNCONNECTED) goto exit; dev->state = STATE_DEV_UNCONNECTED; @@ -1741,7 +1740,7 @@ gadgetfs_disconnect (struct usb_gadget *gadget) next_event (dev, GADGETFS_DISCONNECT); ep0_readable (dev); exit: - spin_unlock_irqrestore (&dev->lock, flags); + spin_unlock (&dev->lock); } static void diff --git a/trunk/drivers/usb/gadget/pch_udc.c b/trunk/drivers/usb/gadget/pch_udc.c index 5048a0c07640..550d6dcdf104 100644 --- a/trunk/drivers/usb/gadget/pch_udc.c +++ b/trunk/drivers/usb/gadget/pch_udc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 LAPIS Semiconductor Co., Ltd. + * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -354,7 +354,6 @@ struct pch_udc_dev { #define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808 #define PCI_VENDOR_ID_ROHM 0x10DB #define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D -#define PCI_DEVICE_ID_ML7831_IOH_UDC 0x8808 static const char ep0_string[] = "ep0in"; static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */ @@ -2971,11 +2970,6 @@ static DEFINE_PCI_DEVICE_TABLE(pch_udc_pcidev_id) = { .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, .class_mask = 0xffffffff, }, - { - PCI_DEVICE(PCI_VENDOR_ID_ROHM, PCI_DEVICE_ID_ML7831_IOH_UDC), - .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, - .class_mask = 0xffffffff, - }, { 0 }, }; @@ -3005,5 +2999,5 @@ static void __exit pch_udc_pci_exit(void) module_exit(pch_udc_pci_exit); MODULE_DESCRIPTION("Intel EG20T USB Device Controller"); -MODULE_AUTHOR("LAPIS Semiconductor, "); +MODULE_AUTHOR("OKI SEMICONDUCTOR, "); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/gadget/r8a66597-udc.c b/trunk/drivers/usb/gadget/r8a66597-udc.c index 24f84b210ce1..68a826a1b866 100644 --- a/trunk/drivers/usb/gadget/r8a66597-udc.c +++ b/trunk/drivers/usb/gadget/r8a66597-udc.c @@ -1718,8 +1718,6 @@ static void r8a66597_fifo_flush(struct usb_ep *_ep) if (list_empty(&ep->queue) && !ep->busy) { pipe_stop(ep->r8a66597, ep->pipenum); r8a66597_bclr(ep->r8a66597, BCLR, ep->fifoctr); - r8a66597_write(ep->r8a66597, ACLRM, ep->pipectr); - r8a66597_write(ep->r8a66597, 0, ep->pipectr); } spin_unlock_irqrestore(&ep->r8a66597->lock, flags); } @@ -1744,6 +1742,7 @@ static int r8a66597_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); + int retval; if (!driver || driver->speed != USB_SPEED_HIGH @@ -1753,7 +1752,16 @@ static int r8a66597_start(struct usb_gadget *gadget, return -ENODEV; /* hook up the driver */ + driver->driver.bus = NULL; r8a66597->driver = driver; + r8a66597->gadget.dev.driver = &driver->driver; + + retval = device_add(&r8a66597->gadget.dev); + if (retval) { + dev_err(r8a66597_to_dev(r8a66597), "device_add error (%d)\n", + retval); + goto error; + } init_controller(r8a66597); r8a66597_bset(r8a66597, VBSE, INTENB0); @@ -1767,6 +1775,12 @@ static int r8a66597_start(struct usb_gadget *gadget, } return 0; + +error: + r8a66597->driver = NULL; + r8a66597->gadget.dev.driver = NULL; + + return retval; } static int r8a66597_stop(struct usb_gadget *gadget, @@ -1780,6 +1794,7 @@ static int r8a66597_stop(struct usb_gadget *gadget, disable_controller(r8a66597); spin_unlock_irqrestore(&r8a66597->lock, flags); + device_del(&r8a66597->gadget.dev); r8a66597->driver = NULL; return 0; } @@ -1830,7 +1845,6 @@ static int __exit r8a66597_remove(struct platform_device *pdev) clk_put(r8a66597->clk); } #endif - device_unregister(&r8a66597->gadget.dev); kfree(r8a66597); return 0; } @@ -1910,17 +1924,13 @@ static int __init r8a66597_probe(struct platform_device *pdev) r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW; r8a66597->gadget.ops = &r8a66597_gadget_ops; + device_initialize(&r8a66597->gadget.dev); dev_set_name(&r8a66597->gadget.dev, "gadget"); r8a66597->gadget.is_dualspeed = 1; r8a66597->gadget.dev.parent = &pdev->dev; r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask; r8a66597->gadget.dev.release = pdev->dev.release; r8a66597->gadget.name = udc_name; - ret = device_register(&r8a66597->gadget.dev); - if (ret < 0) { - dev_err(&pdev->dev, "device_register failed\n"); - goto clean_up; - } init_timer(&r8a66597->timer); r8a66597->timer.function = r8a66597_timer; @@ -1935,7 +1945,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name); ret = PTR_ERR(r8a66597->clk); - goto clean_up_dev; + goto clean_up; } clk_enable(r8a66597->clk); } @@ -2004,9 +2014,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) clk_disable(r8a66597->clk); clk_put(r8a66597->clk); } -clean_up_dev: #endif - device_unregister(&r8a66597->gadget.dev); clean_up: if (r8a66597) { if (r8a66597->sudmac_reg) diff --git a/trunk/drivers/usb/gadget/udc-core.c b/trunk/drivers/usb/gadget/udc-core.c index 6939e17f4580..022baeca7c94 100644 --- a/trunk/drivers/usb/gadget/udc-core.c +++ b/trunk/drivers/usb/gadget/udc-core.c @@ -210,10 +210,10 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); 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); } @@ -344,7 +344,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver); static ssize_t usb_udc_srp_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) { - struct usb_udc *udc = container_of(dev, struct usb_udc, dev); + struct usb_udc *udc = dev_get_drvdata(dev); if (sysfs_streq(buf, "1")) usb_gadget_wakeup(udc->gadget); @@ -378,7 +378,7 @@ static ssize_t usb_udc_speed_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%s\n", usb_speed_string(udc->gadget->speed)); } -static DEVICE_ATTR(speed, S_IRUGO, usb_udc_speed_show, NULL); +static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL); #define USB_UDC_ATTR(name) \ ssize_t usb_udc_##name##_show(struct device *dev, \ @@ -389,7 +389,7 @@ ssize_t usb_udc_##name##_show(struct device *dev, \ \ return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name); \ } \ -static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL) +static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL) static USB_UDC_ATTR(is_dualspeed); static USB_UDC_ATTR(is_otg); diff --git a/trunk/drivers/usb/host/ehci-sched.c b/trunk/drivers/usb/host/ehci-sched.c index 56a32033adb3..2e829fae6482 100644 --- a/trunk/drivers/usb/host/ehci-sched.c +++ b/trunk/drivers/usb/host/ehci-sched.c @@ -1479,15 +1479,10 @@ iso_stream_schedule ( /* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */ - /* find a uframe slot with enough bandwidth. - * Early uframes are more precious because full-speed - * iso IN transfers can't use late uframes, - * and therefore they should be allocated last. - */ - next = start; - start += period; - do { - start--; + /* find a uframe slot with enough bandwidth */ + next = start + period; + for (; start < next; start++) { + /* check schedule: enough space? */ if (stream->highspeed) { if (itd_slot_ok(ehci, mod, start, @@ -1500,7 +1495,7 @@ iso_stream_schedule ( start, sched, period)) break; } - } while (start > next); + } /* no room in the schedule */ if (start == next) { diff --git a/trunk/drivers/usb/host/ehci-xls.c b/trunk/drivers/usb/host/ehci-xls.c index b4fb511d24bc..fe74bd676018 100644 --- a/trunk/drivers/usb/host/ehci-xls.c +++ b/trunk/drivers/usb/host/ehci-xls.c @@ -19,7 +19,7 @@ static int ehci_xls_setup(struct usb_hcd *hcd) ehci->caps = hcd->regs; ehci->regs = hcd->regs + - HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); + HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); dbg_hcs_params(ehci, "reset"); dbg_hcc_params(ehci, "reset"); diff --git a/trunk/drivers/usb/host/ohci-at91.c b/trunk/drivers/usb/host/ohci-at91.c index 95a9fec38e89..ba3a46b78b75 100644 --- a/trunk/drivers/usb/host/ohci-at91.c +++ b/trunk/drivers/usb/host/ohci-at91.c @@ -223,9 +223,6 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int if (port < 0 || port >= 2) return; - if (pdata->vbus_pin[port] <= 0) - return; - gpio_set_value(pdata->vbus_pin[port], !pdata->vbus_pin_inverted ^ enable); } @@ -234,9 +231,6 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port) if (port < 0 || port >= 2) return -EINVAL; - if (pdata->vbus_pin[port] <= 0) - return -EINVAL; - return gpio_get_value(pdata->vbus_pin[port]) ^ !pdata->vbus_pin_inverted; } diff --git a/trunk/drivers/usb/host/ohci-hcd.c b/trunk/drivers/usb/host/ohci-hcd.c index b2639191549e..34efd479e068 100644 --- a/trunk/drivers/usb/host/ohci-hcd.c +++ b/trunk/drivers/usb/host/ohci-hcd.c @@ -389,14 +389,17 @@ ohci_shutdown (struct usb_hcd *hcd) struct ohci_hcd *ohci; ohci = hcd_to_ohci (hcd); - ohci_writel(ohci, (u32) ~0, &ohci->regs->intrdisable); + ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); + ohci->hc_control = ohci_readl(ohci, &ohci->regs->control); - /* Software reset, after which the controller goes into SUSPEND */ - ohci_writel(ohci, OHCI_HCR, &ohci->regs->cmdstatus); - ohci_readl(ohci, &ohci->regs->cmdstatus); /* flush the writes */ - udelay(10); + /* If the SHUTDOWN quirk is set, don't put the controller in RESET */ + ohci->hc_control &= (ohci->flags & OHCI_QUIRK_SHUTDOWN ? + OHCI_CTRL_RWC | OHCI_CTRL_HCFS : + OHCI_CTRL_RWC); + ohci_writel(ohci, ohci->hc_control, &ohci->regs->control); - ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval); + /* flush the writes */ + (void) ohci_readl (ohci, &ohci->regs->control); } static int check_ed(struct ohci_hcd *ohci, struct ed *ed) diff --git a/trunk/drivers/usb/host/ohci-pci.c b/trunk/drivers/usb/host/ohci-pci.c index bc01b064585a..ad8166c681e2 100644 --- a/trunk/drivers/usb/host/ohci-pci.c +++ b/trunk/drivers/usb/host/ohci-pci.c @@ -175,6 +175,28 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) return 0; } +/* nVidia controllers continue to drive Reset signalling on the bus + * even after system shutdown, wasting power. This flag tells the + * shutdown routine to leave the controller OPERATIONAL instead of RESET. + */ +static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd) +{ + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + struct ohci_hcd *ohci = hcd_to_ohci(hcd); + + /* Evidently nVidia fixed their later hardware; this is a guess at + * the changeover point. + */ +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB 0x026d + + if (pdev->device < PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB) { + ohci->flags |= OHCI_QUIRK_SHUTDOWN; + ohci_dbg(ohci, "enabled nVidia shutdown quirk\n"); + } + + return 0; +} + static void sb800_prefetch(struct ohci_hcd *ohci, int on) { struct pci_dev *pdev; @@ -238,6 +260,10 @@ static const struct pci_device_id ohci_pci_quirks[] = { PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399), .driver_data = (unsigned long)ohci_quirk_amd700, }, + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), + .driver_data = (unsigned long) ohci_quirk_nvidia_shutdown, + }, /* FIXME for some of the early AMD 760 southbridges, OHCI * won't work at all. blacklist them. diff --git a/trunk/drivers/usb/host/ohci.h b/trunk/drivers/usb/host/ohci.h index 0795b934d00c..35e5fd640ce7 100644 --- a/trunk/drivers/usb/host/ohci.h +++ b/trunk/drivers/usb/host/ohci.h @@ -403,6 +403,7 @@ struct ohci_hcd { #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ #define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/ #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ +#define OHCI_QUIRK_SHUTDOWN 0x800 /* nVidia power bug */ // there are also chip quirks/bugs in init logic struct work_struct nec_work; /* Worker for NEC quirk */ diff --git a/trunk/drivers/usb/host/pci-quirks.c b/trunk/drivers/usb/host/pci-quirks.c index caf87428ca43..27a3dec32fa2 100644 --- a/trunk/drivers/usb/host/pci-quirks.c +++ b/trunk/drivers/usb/host/pci-quirks.c @@ -37,7 +37,6 @@ #define OHCI_INTRENABLE 0x10 #define OHCI_INTRDISABLE 0x14 #define OHCI_FMINTERVAL 0x34 -#define OHCI_HCFS (3 << 6) /* hc functional state */ #define OHCI_HCR (1 << 0) /* host controller reset */ #define OHCI_OCR (1 << 3) /* ownership change request */ #define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ @@ -467,8 +466,6 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) { void __iomem *base; u32 control; - u32 fminterval; - int cnt; if (!mmio_resource_enabled(pdev, 0)) return; @@ -501,32 +498,41 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev) } #endif - /* disable interrupts */ - writel((u32) ~0, base + OHCI_INTRDISABLE); + /* reset controller, preserving RWC (and possibly IR) */ + writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); + readl(base + OHCI_CONTROL); - /* Reset the USB bus, if the controller isn't already in RESET */ - if (control & OHCI_HCFS) { - /* Go into RESET, preserving RWC (and possibly IR) */ - writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL); - readl(base + OHCI_CONTROL); + /* Some NVIDIA controllers stop working if kept in RESET for too long */ + if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) { + u32 fminterval; + int cnt; - /* drive bus reset for at least 50 ms (7.1.7.5) */ + /* drive reset for at least 50 ms (7.1.7.5) */ msleep(50); - } - /* software reset of the controller, preserving HcFmInterval */ - fminterval = readl(base + OHCI_FMINTERVAL); - writel(OHCI_HCR, base + OHCI_CMDSTATUS); + /* software reset of the controller, preserving HcFmInterval */ + fminterval = readl(base + OHCI_FMINTERVAL); + writel(OHCI_HCR, base + OHCI_CMDSTATUS); - /* reset requires max 10 us delay */ - for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */ - if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0) - break; - udelay(1); + /* reset requires max 10 us delay */ + for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */ + if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0) + break; + udelay(1); + } + writel(fminterval, base + OHCI_FMINTERVAL); + + /* Now we're in the SUSPEND state with all devices reset + * and wakeups and interrupts disabled + */ } - writel(fminterval, base + OHCI_FMINTERVAL); - /* Now the controller is safely in SUSPEND and nothing can wake it up */ + /* + * disable interrupts + */ + writel(~(u32)0, base + OHCI_INTRDISABLE); + writel(~(u32)0, base + OHCI_INTRSTATUS); + iounmap(base); } @@ -621,7 +627,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) void __iomem *base, *op_reg_base; u32 hcc_params, cap, val; u8 offset, cap_length; - int wait_time, count = 256/4; + int wait_time, delta, count = 256/4; if (!mmio_resource_enabled(pdev, 0)) return; @@ -667,10 +673,11 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) writel(val, op_reg_base + EHCI_USBCMD); wait_time = 2000; + delta = 100; do { writel(0x3f, op_reg_base + EHCI_USBSTS); - udelay(100); - wait_time -= 100; + udelay(delta); + wait_time -= delta; val = readl(op_reg_base + EHCI_USBSTS); if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { break; diff --git a/trunk/drivers/usb/host/xhci-mem.c b/trunk/drivers/usb/host/xhci-mem.c index 0e4b25fa3bcd..42a22b8e6922 100644 --- a/trunk/drivers/usb/host/xhci-mem.c +++ b/trunk/drivers/usb/host/xhci-mem.c @@ -982,6 +982,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud struct xhci_virt_device *dev; struct xhci_ep_ctx *ep0_ctx; struct xhci_slot_ctx *slot_ctx; + struct xhci_input_control_ctx *ctrl_ctx; u32 port_num; struct usb_device *top_dev; @@ -993,8 +994,12 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud return -EINVAL; } ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0); + ctrl_ctx = xhci_get_input_control_ctx(xhci, dev->in_ctx); slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx); + /* 2) New slot context and endpoint 0 context are valid*/ + ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); + /* 3) Only the control endpoint is valid - one endpoint context */ slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route); switch (udev->speed) { diff --git a/trunk/drivers/usb/host/xhci-ring.c b/trunk/drivers/usb/host/xhci-ring.c index 9f1d4b15d818..940321b3ec68 100644 --- a/trunk/drivers/usb/host/xhci-ring.c +++ b/trunk/drivers/usb/host/xhci-ring.c @@ -816,24 +816,23 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) struct xhci_ring *ring; struct xhci_td *cur_td; int ret, i, j; - unsigned long flags; ep = (struct xhci_virt_ep *) arg; xhci = ep->xhci; - spin_lock_irqsave(&xhci->lock, flags); + spin_lock(&xhci->lock); ep->stop_cmds_pending--; if (xhci->xhc_state & XHCI_STATE_DYING) { xhci_dbg(xhci, "Stop EP timer ran, but another timer marked " "xHCI as DYING, exiting.\n"); - spin_unlock_irqrestore(&xhci->lock, flags); + spin_unlock(&xhci->lock); return; } if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) { xhci_dbg(xhci, "Stop EP timer ran, but no command pending, " "exiting.\n"); - spin_unlock_irqrestore(&xhci->lock, flags); + spin_unlock(&xhci->lock); return; } @@ -845,11 +844,11 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) xhci->xhc_state |= XHCI_STATE_DYING; /* Disable interrupts from the host controller and start halting it */ xhci_quiesce(xhci); - spin_unlock_irqrestore(&xhci->lock, flags); + spin_unlock(&xhci->lock); ret = xhci_halt(xhci); - spin_lock_irqsave(&xhci->lock, flags); + spin_lock(&xhci->lock); if (ret < 0) { /* This is bad; the host is not responding to commands and it's * not allowing itself to be halted. At least interrupts are @@ -897,7 +896,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) } } } - spin_unlock_irqrestore(&xhci->lock, flags); + spin_unlock(&xhci->lock); xhci_dbg(xhci, "Calling usb_hc_died()\n"); usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); xhci_dbg(xhci, "xHCI host controller is dead.\n"); diff --git a/trunk/drivers/usb/host/xhci.c b/trunk/drivers/usb/host/xhci.c index aa94c0195791..1ff95a0df576 100644 --- a/trunk/drivers/usb/host/xhci.c +++ b/trunk/drivers/usb/host/xhci.c @@ -799,7 +799,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) u32 command, temp = 0; struct usb_hcd *hcd = xhci_to_hcd(xhci); struct usb_hcd *secondary_hcd; - int retval = 0; + int retval; /* Wait a bit if either of the roothubs need to settle from the * transition into bus suspend. @@ -809,9 +809,6 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) xhci->bus_state[1].next_statechange)) msleep(100); - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); - spin_lock_irq(&xhci->lock); if (xhci->quirks & XHCI_RESET_ON_RESUME) hibernated = true; @@ -881,13 +878,20 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) return retval; xhci_dbg(xhci, "Start the primary HCD\n"); retval = xhci_run(hcd->primary_hcd); + if (retval) + goto failed_restart; + + xhci_dbg(xhci, "Start the secondary HCD\n"); + retval = xhci_run(secondary_hcd); if (!retval) { - xhci_dbg(xhci, "Start the secondary HCD\n"); - retval = xhci_run(secondary_hcd); + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + set_bit(HCD_FLAG_HW_ACCESSIBLE, + &xhci->shared_hcd->flags); } +failed_restart: hcd->state = HC_STATE_SUSPENDED; xhci->shared_hcd->state = HC_STATE_SUSPENDED; - goto done; + return retval; } /* step 4: set Run/Stop bit */ @@ -906,14 +910,11 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) * Running endpoints by ringing their doorbells */ - spin_unlock_irq(&xhci->lock); + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); - done: - if (retval == 0) { - usb_hcd_resume_root_hub(hcd); - usb_hcd_resume_root_hub(xhci->shared_hcd); - } - return retval; + spin_unlock_irq(&xhci->lock); + return 0; } #endif /* CONFIG_PM */ @@ -3503,10 +3504,6 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) /* Otherwise, update the control endpoint ring enqueue pointer. */ else xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev); - ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); - ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG); - ctrl_ctx->drop_flags = 0; - xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id); xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2); @@ -3588,6 +3585,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev) virt_dev->address = (le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK) + 1; /* Zero the input context control for later use */ + ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx); ctrl_ctx->add_flags = 0; ctrl_ctx->drop_flags = 0; diff --git a/trunk/drivers/usb/musb/Kconfig b/trunk/drivers/usb/musb/Kconfig index 07a03460a598..fc34b8b11910 100644 --- a/trunk/drivers/usb/musb/Kconfig +++ b/trunk/drivers/usb/musb/Kconfig @@ -11,7 +11,6 @@ config USB_MUSB_HDRC select TWL4030_USB if MACH_OMAP_3430SDP select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA select USB_OTG_UTILS - select USB_GADGET_DUALSPEED tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' help Say Y here if your system has a dual role high speed USB @@ -61,7 +60,7 @@ config USB_MUSB_BLACKFIN config USB_MUSB_UX500 tristate "U8500 and U5500" - depends on (ARCH_U8500 && AB8500_USB) + depends on (ARCH_U8500 && AB8500_USB) || (ARCH_U5500) endchoice diff --git a/trunk/drivers/usb/musb/am35x.c b/trunk/drivers/usb/musb/am35x.c index e233d2b7d335..08f1d0b662a3 100644 --- a/trunk/drivers/usb/musb/am35x.c +++ b/trunk/drivers/usb/musb/am35x.c @@ -27,7 +27,6 @@ */ #include -#include #include #include #include diff --git a/trunk/drivers/usb/musb/da8xx.c b/trunk/drivers/usb/musb/da8xx.c index 2613bfdb09b6..4da7492ddbdb 100644 --- a/trunk/drivers/usb/musb/da8xx.c +++ b/trunk/drivers/usb/musb/da8xx.c @@ -27,7 +27,6 @@ */ #include -#include #include #include #include diff --git a/trunk/drivers/usb/musb/musb_core.c b/trunk/drivers/usb/musb/musb_core.c index c1fa12ec7a9a..20a28731c338 100644 --- a/trunk/drivers/usb/musb/musb_core.c +++ b/trunk/drivers/usb/musb/musb_core.c @@ -1477,7 +1477,8 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb) /*-------------------------------------------------------------------------*/ #if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \ - defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500) + defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500) || \ + defined(CONFIG_ARCH_U5500) static irqreturn_t generic_interrupt(int irq, void *__hci) { diff --git a/trunk/drivers/usb/musb/musb_gadget.c b/trunk/drivers/usb/musb/musb_gadget.c index d51043acfe1a..ae4a20acef6c 100644 --- a/trunk/drivers/usb/musb/musb_gadget.c +++ b/trunk/drivers/usb/musb/musb_gadget.c @@ -1999,6 +1999,10 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver) nuke(&hw_ep->ep_out, -ESHUTDOWN); } } + + spin_unlock(&musb->lock); + driver->disconnect(&musb->g); + spin_lock(&musb->lock); } } diff --git a/trunk/drivers/usb/renesas_usbhs/common.c b/trunk/drivers/usb/renesas_usbhs/common.c index 08c679c0dde5..d2e2efaba658 100644 --- a/trunk/drivers/usb/renesas_usbhs/common.c +++ b/trunk/drivers/usb/renesas_usbhs/common.c @@ -405,7 +405,7 @@ int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) /* * platform functions */ -static int usbhs_probe(struct platform_device *pdev) +static int __devinit usbhs_probe(struct platform_device *pdev) { struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; struct renesas_usbhs_driver_callback *dfunc; diff --git a/trunk/drivers/usb/renesas_usbhs/fifo.c b/trunk/drivers/usb/renesas_usbhs/fifo.c index ffdf5d15085e..8da685e796d1 100644 --- a/trunk/drivers/usb/renesas_usbhs/fifo.c +++ b/trunk/drivers/usb/renesas_usbhs/fifo.c @@ -820,7 +820,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done) if (len % 4) /* 32bit alignment */ goto usbhsf_pio_prepare_push; - if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ + if ((*(u32 *) pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ goto usbhsf_pio_prepare_push; /* get enable DMA fifo */ @@ -897,7 +897,7 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done) if (!fifo) goto usbhsf_pio_prepare_pop; - if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ + if ((*(u32 *) pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ goto usbhsf_pio_prepare_pop; ret = usbhsf_fifo_select(pipe, fifo, 0); diff --git a/trunk/drivers/usb/renesas_usbhs/mod.h b/trunk/drivers/usb/renesas_usbhs/mod.h index 6c6875533f01..8ae3733031cd 100644 --- a/trunk/drivers/usb/renesas_usbhs/mod.h +++ b/trunk/drivers/usb/renesas_usbhs/mod.h @@ -143,8 +143,8 @@ void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod); */ #if defined(CONFIG_USB_RENESAS_USBHS_HCD) || \ defined(CONFIG_USB_RENESAS_USBHS_HCD_MODULE) -extern int usbhs_mod_host_probe(struct usbhs_priv *priv); -extern int usbhs_mod_host_remove(struct usbhs_priv *priv); +extern int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv); +extern int __devexit usbhs_mod_host_remove(struct usbhs_priv *priv); #else static inline int usbhs_mod_host_probe(struct usbhs_priv *priv) { @@ -157,8 +157,8 @@ static inline void usbhs_mod_host_remove(struct usbhs_priv *priv) #if defined(CONFIG_USB_RENESAS_USBHS_UDC) || \ defined(CONFIG_USB_RENESAS_USBHS_UDC_MODULE) -extern int usbhs_mod_gadget_probe(struct usbhs_priv *priv); -extern void usbhs_mod_gadget_remove(struct usbhs_priv *priv); +extern int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv); +extern void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv); #else static inline int usbhs_mod_gadget_probe(struct usbhs_priv *priv) { diff --git a/trunk/drivers/usb/renesas_usbhs/mod_gadget.c b/trunk/drivers/usb/renesas_usbhs/mod_gadget.c index d9717e0bc1ff..4cc7ee0babc6 100644 --- a/trunk/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/trunk/drivers/usb/renesas_usbhs/mod_gadget.c @@ -830,7 +830,7 @@ static int usbhsg_stop(struct usbhs_priv *priv) return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); } -int usbhs_mod_gadget_probe(struct usbhs_priv *priv) +int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv) { struct usbhsg_gpriv *gpriv; struct usbhsg_uep *uep; @@ -927,7 +927,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) return ret; } -void usbhs_mod_gadget_remove(struct usbhs_priv *priv) +void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv) { struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); diff --git a/trunk/drivers/usb/renesas_usbhs/mod_host.c b/trunk/drivers/usb/renesas_usbhs/mod_host.c index bade761a1e52..1a7208a50afc 100644 --- a/trunk/drivers/usb/renesas_usbhs/mod_host.c +++ b/trunk/drivers/usb/renesas_usbhs/mod_host.c @@ -103,7 +103,7 @@ struct usbhsh_hpriv { u32 port_stat; /* USB_PORT_STAT_xxx */ - struct completion setup_ack_done; + struct completion *done; /* see usbhsh_req_alloc/free */ struct list_head ureq_link_active; @@ -355,7 +355,6 @@ static void usbhsh_device_free(struct usbhsh_hpriv *hpriv, struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, struct usbhsh_device *udev, struct usb_host_endpoint *ep, - int dir_in_req, gfp_t mem_flags) { struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); @@ -365,38 +364,27 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, struct usbhs_pipe *pipe, *best_pipe; struct device *dev = usbhsh_hcd_to_dev(hcd); struct usb_endpoint_descriptor *desc = &ep->desc; - int type, i, dir_in; + int type, i; unsigned int min_usr; - dir_in_req = !!dir_in_req; - uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); if (!uep) { dev_err(dev, "usbhsh_ep alloc fail\n"); return NULL; } - - if (usb_endpoint_xfer_control(desc)) { - best_pipe = usbhsh_hpriv_to_dcp(hpriv); - goto usbhsh_endpoint_alloc_find_pipe; - } + type = usb_endpoint_type(desc); /* * find best pipe for endpoint * see * HARDWARE LIMITATION */ - type = usb_endpoint_type(desc); min_usr = ~0; best_pipe = NULL; - usbhs_for_each_pipe(pipe, priv, i) { + usbhs_for_each_pipe_with_dcp(pipe, priv, i) { if (!usbhs_pipe_type_is(pipe, type)) continue; - dir_in = !!usbhs_pipe_is_dir_in(pipe); - if (0 != (dir_in - dir_in_req)) - continue; - info = usbhsh_pipe_info(pipe); if (min_usr > info->usr_cnt) { @@ -410,7 +398,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, kfree(uep); return NULL; } -usbhsh_endpoint_alloc_find_pipe: + /* * init uep */ @@ -435,7 +423,6 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, * see * DCPMAXP/PIPEMAXP */ - usbhs_pipe_sequence_data0(uep->pipe); usbhs_pipe_config_update(uep->pipe, usbhsh_device_number(hpriv, udev), usb_endpoint_num(desc), @@ -443,7 +430,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, dev_dbg(dev, "%s [%d-%s](%p)\n", __func__, usbhsh_device_number(hpriv, udev), - usbhs_pipe_name(uep->pipe), uep); + usbhs_pipe_name(pipe), uep); return uep; } @@ -562,7 +549,8 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv, * usbhsh_irq_setup_ack() * usbhsh_irq_setup_err() */ - init_completion(&hpriv->setup_ack_done); + DECLARE_COMPLETION(done); + hpriv->done = &done; /* copy original request */ memcpy(&req, urb->setup_packet, sizeof(struct usb_ctrlrequest)); @@ -584,7 +572,8 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv, /* * wait setup packet ACK */ - wait_for_completion(&hpriv->setup_ack_done); + wait_for_completion(&done); + hpriv->done = NULL; dev_dbg(dev, "%s done\n", __func__); } @@ -735,11 +724,11 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, struct usbhsh_device *udev, *new_udev = NULL; struct usbhs_pipe *pipe; struct usbhsh_ep *uep; - int is_dir_in = usb_pipein(urb->pipe); int ret; - dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); + dev_dbg(dev, "%s (%s)\n", + __func__, usb_pipein(urb->pipe) ? "in" : "out"); ret = usb_hcd_link_urb_to_ep(hcd, urb); if (ret) @@ -762,8 +751,7 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, */ uep = usbhsh_ep_to_uep(ep); if (!uep) { - uep = usbhsh_endpoint_alloc(hpriv, udev, ep, - is_dir_in, mem_flags); + uep = usbhsh_endpoint_alloc(hpriv, udev, ep, mem_flags); if (!uep) goto usbhsh_urb_enqueue_error_free_device; } @@ -1107,7 +1095,10 @@ static int usbhsh_irq_setup_ack(struct usbhs_priv *priv, dev_dbg(dev, "setup packet OK\n"); - complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */ + if (unlikely(!hpriv->done)) + dev_err(dev, "setup ack happen without necessary data\n"); + else + complete(hpriv->done); /* see usbhsh_urb_enqueue() */ return 0; } @@ -1120,7 +1111,10 @@ static int usbhsh_irq_setup_err(struct usbhs_priv *priv, dev_dbg(dev, "setup packet Err\n"); - complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */ + if (unlikely(!hpriv->done)) + dev_err(dev, "setup err happen without necessary data\n"); + else + complete(hpriv->done); /* see usbhsh_urb_enqueue() */ return 0; } @@ -1227,18 +1221,8 @@ static int usbhsh_stop(struct usbhs_priv *priv) { struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); - struct usbhs_mod *mod = usbhs_mod_get_current(priv); struct device *dev = usbhs_priv_to_dev(priv); - /* - * disable irq callback - */ - mod->irq_attch = NULL; - mod->irq_dtch = NULL; - mod->irq_sack = NULL; - mod->irq_sign = NULL; - usbhs_irq_callback_update(priv, mod); - usb_remove_hcd(hcd); /* disable sys */ @@ -1251,7 +1235,7 @@ static int usbhsh_stop(struct usbhs_priv *priv) return 0; } -int usbhs_mod_host_probe(struct usbhs_priv *priv) +int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv) { struct usbhsh_hpriv *hpriv; struct usb_hcd *hcd; @@ -1295,6 +1279,7 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) hpriv->mod.stop = usbhsh_stop; hpriv->pipe_info = pipe_info; hpriv->pipe_size = pipe_size; + hpriv->done = NULL; usbhsh_req_list_init(hpriv); usbhsh_port_stat_init(hpriv); @@ -1314,7 +1299,7 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) return -ENOMEM; } -int usbhs_mod_host_remove(struct usbhs_priv *priv) +int __devexit usbhs_mod_host_remove(struct usbhs_priv *priv) { struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); diff --git a/trunk/drivers/usb/serial/ark3116.c b/trunk/drivers/usb/serial/ark3116.c index 18e875b92e00..5cdb9d912275 100644 --- a/trunk/drivers/usb/serial/ark3116.c +++ b/trunk/drivers/usb/serial/ark3116.c @@ -42,7 +42,7 @@ static int debug; * Version information */ -#define DRIVER_VERSION "v0.7" +#define DRIVER_VERSION "v0.6" #define DRIVER_AUTHOR "Bart Hartgers " #define DRIVER_DESC "USB ARK3116 serial/IrDA driver" #define DRIVER_DEV_DESC "ARK3116 RS232/IrDA" @@ -380,6 +380,10 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) goto err_out; } + /* setup termios */ + if (tty) + ark3116_set_termios(tty, port, NULL); + /* remove any data still left: also clears error state */ ark3116_read_reg(serial, UART_RX, buf); @@ -402,10 +406,6 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port) /* enable DMA */ ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT); - /* setup termios */ - if (tty) - ark3116_set_termios(tty, port, NULL); - err_out: kfree(buf); return result; diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index bd4298bb6750..8fe034d2d3e7 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -2104,19 +2104,13 @@ static void ftdi_set_termios(struct tty_struct *tty, cflag = termios->c_cflag; - if (old_termios->c_cflag == termios->c_cflag - && old_termios->c_ispeed == termios->c_ispeed - && old_termios->c_ospeed == termios->c_ospeed) - goto no_c_cflag_changes; - + /* FIXME -For this cut I don't care if the line is really changing or + not - so just do the change regardless - should be able to + compare old_termios and tty->termios */ /* NOTE These routines can get interrupted by ftdi_sio_read_bulk_callback - need to examine what this means - don't see any problems yet */ - if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) == - (termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB))) - goto no_data_parity_stop_changes; - /* Set number of data bits, parity, stop bits */ urb_value = 0; @@ -2157,7 +2151,6 @@ static void ftdi_set_termios(struct tty_struct *tty, } /* Now do the baudrate */ -no_data_parity_stop_changes: if ((cflag & CBAUD) == B0) { /* Disable flow control */ if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), @@ -2185,7 +2178,6 @@ static void ftdi_set_termios(struct tty_struct *tty, /* Set flow control */ /* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */ -no_c_cflag_changes: if (cflag & CRTSCTS) { dbg("%s Setting to CRTSCTS flow control", __func__); if (usb_control_msg(dev, diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index d865878c9f97..89ae1f65e1b1 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -156,7 +156,6 @@ static void option_instat_callback(struct urb *urb); #define HUAWEI_PRODUCT_K4511 0x14CC #define HUAWEI_PRODUCT_ETS1220 0x1803 #define HUAWEI_PRODUCT_E353 0x1506 -#define HUAWEI_PRODUCT_E173S 0x1C05 #define QUANTA_VENDOR_ID 0x0408 #define QUANTA_PRODUCT_Q101 0xEA02 @@ -317,9 +316,6 @@ static void option_instat_callback(struct urb *urb); #define ZTE_PRODUCT_AC8710 0xfff1 #define ZTE_PRODUCT_AC2726 0xfff5 #define ZTE_PRODUCT_AC8710T 0xffff -#define ZTE_PRODUCT_MC2718 0xffe8 -#define ZTE_PRODUCT_AD3812 0xffeb -#define ZTE_PRODUCT_MC2716 0xffed #define BENQ_VENDOR_ID 0x04a5 #define BENQ_PRODUCT_H10 0x4068 @@ -472,10 +468,6 @@ static void option_instat_callback(struct urb *urb); #define YUGA_PRODUCT_CLU528 0x260D #define YUGA_PRODUCT_CLU526 0x260F -/* Viettel products */ -#define VIETTEL_VENDOR_ID 0x2262 -#define VIETTEL_PRODUCT_VT1000 0x0002 - /* some devices interfaces need special handling due to a number of reasons */ enum option_blacklist_reason { OPTION_BLACKLIST_NONE = 0, @@ -508,18 +500,6 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = { .reserved = BIT(4), }; -static const struct option_blacklist_info zte_ad3812_z_blacklist = { - .sendsetup = BIT(0) | BIT(1) | BIT(2), -}; - -static const struct option_blacklist_info zte_mc2718_z_blacklist = { - .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), -}; - -static const struct option_blacklist_info zte_mc2716_z_blacklist = { - .sendsetup = BIT(1) | BIT(2) | BIT(3), -}; - static const struct option_blacklist_info huawei_cdc12_blacklist = { .reserved = BIT(1) | BIT(2), }; @@ -642,7 +622,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), @@ -1064,12 +1043,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), - .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ @@ -1168,7 +1141,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) }, { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) }, { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) }, - { USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index fc2d66f7f4eb..9083d1e616b4 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/drivers/usb/serial/pl2303.c @@ -91,6 +91,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, + { USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) }, { USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) }, { } /* Terminating entry */ }; diff --git a/trunk/drivers/usb/serial/pl2303.h b/trunk/drivers/usb/serial/pl2303.h index c38b8c00c06f..3d10d7f02072 100644 --- a/trunk/drivers/usb/serial/pl2303.h +++ b/trunk/drivers/usb/serial/pl2303.h @@ -145,6 +145,10 @@ #define ADLINK_VENDOR_ID 0x0b63 #define ADLINK_ND6530_PRODUCT_ID 0x6530 +/* WinChipHead USB->RS 232 adapter */ +#define WINCHIPHEAD_VENDOR_ID 0x4348 +#define WINCHIPHEAD_USBSER_PRODUCT_ID 0x5523 + /* SMART USB Serial Adapter */ #define SMART_VENDOR_ID 0x0b8c #define SMART_PRODUCT_ID 0x2303 diff --git a/trunk/drivers/usb/storage/ene_ub6250.c b/trunk/drivers/usb/storage/ene_ub6250.c index 9fbe742343c6..4dca3ef0668c 100644 --- a/trunk/drivers/usb/storage/ene_ub6250.c +++ b/trunk/drivers/usb/storage/ene_ub6250.c @@ -1762,9 +1762,10 @@ static int ms_scsi_write(struct us_data *us, struct scsi_cmnd *srb) result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1); } else { void *buf; - int offset = 0; + int offset; u16 PhyBlockAddr; u8 PageNum; + u32 result; u16 len, oldphy, newphy; buf = kmalloc(blenByte, GFP_KERNEL); diff --git a/trunk/drivers/usb/storage/protocol.c b/trunk/drivers/usb/storage/protocol.c index 82dd834709c7..93c1a4d86f51 100644 --- a/trunk/drivers/usb/storage/protocol.c +++ b/trunk/drivers/usb/storage/protocol.c @@ -59,9 +59,7 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) { - /* - * Pad the SCSI command with zeros out to 12 bytes. If the - * command already is 12 bytes or longer, leave it alone. + /* Pad the SCSI command with zeros out to 12 bytes * * NOTE: This only works because a scsi_cmnd struct field contains * a unsigned char cmnd[16], so we know we have storage available @@ -69,6 +67,9 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us) for (; srb->cmd_len<12; srb->cmd_len++) srb->cmnd[srb->cmd_len] = 0; + /* set command length to 12 bytes */ + srb->cmd_len = 12; + /* send the command to the transport layer */ usb_stor_invoke_transport(srb, us); } diff --git a/trunk/drivers/watchdog/Kconfig b/trunk/drivers/watchdog/Kconfig index 79fd606b7cd5..6285867a9356 100644 --- a/trunk/drivers/watchdog/Kconfig +++ b/trunk/drivers/watchdog/Kconfig @@ -314,6 +314,13 @@ config NUC900_WATCHDOG To compile this driver as a module, choose M here: the module will be called nuc900_wdt. +config ADX_WATCHDOG + tristate "Avionic Design Xanthos watchdog" + depends on ARCH_PXA_ADX + help + Say Y here if you want support for the watchdog timer on Avionic + Design Xanthos boards. + config TS72XX_WATCHDOG tristate "TS-72XX SBC Watchdog" depends on MACH_TS72XX diff --git a/trunk/drivers/watchdog/Makefile b/trunk/drivers/watchdog/Makefile index fe893e91935b..55bd5740e910 100644 --- a/trunk/drivers/watchdog/Makefile +++ b/trunk/drivers/watchdog/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_ORION_WATCHDOG) += orion_wdt.o obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o obj-$(CONFIG_STMP3XXX_WATCHDOG) += stmp3xxx_wdt.o obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o +obj-$(CONFIG_ADX_WATCHDOG) += adx_wdt.o obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o diff --git a/trunk/drivers/watchdog/adx_wdt.c b/trunk/drivers/watchdog/adx_wdt.c new file mode 100644 index 000000000000..af6e6b16475a --- /dev/null +++ b/trunk/drivers/watchdog/adx_wdt.c @@ -0,0 +1,355 @@ +/* + * Copyright (C) 2008-2009 Avionic Design GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WATCHDOG_NAME "adx-wdt" + +/* register offsets */ +#define ADX_WDT_CONTROL 0x00 +#define ADX_WDT_CONTROL_ENABLE (1 << 0) +#define ADX_WDT_CONTROL_nRESET (1 << 1) +#define ADX_WDT_TIMEOUT 0x08 + +static struct platform_device *adx_wdt_dev; +static unsigned long driver_open; + +#define WDT_STATE_STOP 0 +#define WDT_STATE_START 1 + +struct adx_wdt { + void __iomem *base; + unsigned long timeout; + unsigned int state; + unsigned int wake; + spinlock_t lock; +}; + +static const struct watchdog_info adx_wdt_info = { + .identity = "Avionic Design Xanthos Watchdog", + .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, +}; + +static void adx_wdt_start_locked(struct adx_wdt *wdt) +{ + u32 ctrl; + + ctrl = readl(wdt->base + ADX_WDT_CONTROL); + ctrl |= ADX_WDT_CONTROL_ENABLE; + writel(ctrl, wdt->base + ADX_WDT_CONTROL); + wdt->state = WDT_STATE_START; +} + +static void adx_wdt_start(struct adx_wdt *wdt) +{ + unsigned long flags; + + spin_lock_irqsave(&wdt->lock, flags); + adx_wdt_start_locked(wdt); + spin_unlock_irqrestore(&wdt->lock, flags); +} + +static void adx_wdt_stop_locked(struct adx_wdt *wdt) +{ + u32 ctrl; + + ctrl = readl(wdt->base + ADX_WDT_CONTROL); + ctrl &= ~ADX_WDT_CONTROL_ENABLE; + writel(ctrl, wdt->base + ADX_WDT_CONTROL); + wdt->state = WDT_STATE_STOP; +} + +static void adx_wdt_stop(struct adx_wdt *wdt) +{ + unsigned long flags; + + spin_lock_irqsave(&wdt->lock, flags); + adx_wdt_stop_locked(wdt); + spin_unlock_irqrestore(&wdt->lock, flags); +} + +static void adx_wdt_set_timeout(struct adx_wdt *wdt, unsigned long seconds) +{ + unsigned long timeout = seconds * 1000; + unsigned long flags; + unsigned int state; + + spin_lock_irqsave(&wdt->lock, flags); + state = wdt->state; + adx_wdt_stop_locked(wdt); + writel(timeout, wdt->base + ADX_WDT_TIMEOUT); + + if (state == WDT_STATE_START) + adx_wdt_start_locked(wdt); + + wdt->timeout = timeout; + spin_unlock_irqrestore(&wdt->lock, flags); +} + +static void adx_wdt_get_timeout(struct adx_wdt *wdt, unsigned long *seconds) +{ + *seconds = wdt->timeout / 1000; +} + +static void adx_wdt_keepalive(struct adx_wdt *wdt) +{ + unsigned long flags; + + spin_lock_irqsave(&wdt->lock, flags); + writel(wdt->timeout, wdt->base + ADX_WDT_TIMEOUT); + spin_unlock_irqrestore(&wdt->lock, flags); +} + +static int adx_wdt_open(struct inode *inode, struct file *file) +{ + struct adx_wdt *wdt = platform_get_drvdata(adx_wdt_dev); + + if (test_and_set_bit(0, &driver_open)) + return -EBUSY; + + file->private_data = wdt; + adx_wdt_set_timeout(wdt, 30); + adx_wdt_start(wdt); + + return nonseekable_open(inode, file); +} + +static int adx_wdt_release(struct inode *inode, struct file *file) +{ + struct adx_wdt *wdt = file->private_data; + + adx_wdt_stop(wdt); + clear_bit(0, &driver_open); + + return 0; +} + +static long adx_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct adx_wdt *wdt = file->private_data; + void __user *argp = (void __user *)arg; + unsigned long __user *p = argp; + unsigned long seconds = 0; + unsigned int options; + long ret = -EINVAL; + + switch (cmd) { + case WDIOC_GETSUPPORT: + if (copy_to_user(argp, &adx_wdt_info, sizeof(adx_wdt_info))) + return -EFAULT; + else + return 0; + + case WDIOC_GETSTATUS: + case WDIOC_GETBOOTSTATUS: + return put_user(0, p); + + case WDIOC_KEEPALIVE: + adx_wdt_keepalive(wdt); + return 0; + + case WDIOC_SETTIMEOUT: + if (get_user(seconds, p)) + return -EFAULT; + + adx_wdt_set_timeout(wdt, seconds); + + /* fallthrough */ + case WDIOC_GETTIMEOUT: + adx_wdt_get_timeout(wdt, &seconds); + return put_user(seconds, p); + + case WDIOC_SETOPTIONS: + if (copy_from_user(&options, argp, sizeof(options))) + return -EFAULT; + + if (options & WDIOS_DISABLECARD) { + adx_wdt_stop(wdt); + ret = 0; + } + + if (options & WDIOS_ENABLECARD) { + adx_wdt_start(wdt); + ret = 0; + } + + return ret; + + default: + break; + } + + return -ENOTTY; +} + +static ssize_t adx_wdt_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) +{ + struct adx_wdt *wdt = file->private_data; + + if (len) + adx_wdt_keepalive(wdt); + + return len; +} + +static const struct file_operations adx_wdt_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .open = adx_wdt_open, + .release = adx_wdt_release, + .unlocked_ioctl = adx_wdt_ioctl, + .write = adx_wdt_write, +}; + +static struct miscdevice adx_wdt_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &adx_wdt_fops, +}; + +static int __devinit adx_wdt_probe(struct platform_device *pdev) +{ + struct resource *res; + struct adx_wdt *wdt; + int ret = 0; + u32 ctrl; + + wdt = devm_kzalloc(&pdev->dev, sizeof(*wdt), GFP_KERNEL); + if (!wdt) { + dev_err(&pdev->dev, "cannot allocate WDT structure\n"); + return -ENOMEM; + } + + spin_lock_init(&wdt->lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "cannot obtain I/O memory region\n"); + return -ENXIO; + } + + res = devm_request_mem_region(&pdev->dev, res->start, + resource_size(res), res->name); + if (!res) { + dev_err(&pdev->dev, "cannot request I/O memory region\n"); + return -ENXIO; + } + + wdt->base = devm_ioremap_nocache(&pdev->dev, res->start, + resource_size(res)); + if (!wdt->base) { + dev_err(&pdev->dev, "cannot remap I/O memory region\n"); + return -ENXIO; + } + + /* disable watchdog and reboot on timeout */ + ctrl = readl(wdt->base + ADX_WDT_CONTROL); + ctrl &= ~ADX_WDT_CONTROL_ENABLE; + ctrl &= ~ADX_WDT_CONTROL_nRESET; + writel(ctrl, wdt->base + ADX_WDT_CONTROL); + + platform_set_drvdata(pdev, wdt); + adx_wdt_dev = pdev; + + ret = misc_register(&adx_wdt_miscdev); + if (ret) { + dev_err(&pdev->dev, "cannot register miscdev on minor %d " + "(err=%d)\n", WATCHDOG_MINOR, ret); + return ret; + } + + return 0; +} + +static int __devexit adx_wdt_remove(struct platform_device *pdev) +{ + struct adx_wdt *wdt = platform_get_drvdata(pdev); + + misc_deregister(&adx_wdt_miscdev); + adx_wdt_stop(wdt); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +static void adx_wdt_shutdown(struct platform_device *pdev) +{ + struct adx_wdt *wdt = platform_get_drvdata(pdev); + adx_wdt_stop(wdt); +} + +#ifdef CONFIG_PM +static int adx_wdt_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct adx_wdt *wdt = platform_get_drvdata(pdev); + + wdt->wake = (wdt->state == WDT_STATE_START) ? 1 : 0; + adx_wdt_stop(wdt); + + return 0; +} + +static int adx_wdt_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct adx_wdt *wdt = platform_get_drvdata(pdev); + + if (wdt->wake) + adx_wdt_start(wdt); + + return 0; +} + +static const struct dev_pm_ops adx_wdt_pm_ops = { + .suspend = adx_wdt_suspend, + .resume = adx_wdt_resume, +}; + +# define ADX_WDT_PM_OPS (&adx_wdt_pm_ops) +#else +# define ADX_WDT_PM_OPS NULL +#endif + +static struct platform_driver adx_wdt_driver = { + .probe = adx_wdt_probe, + .remove = __devexit_p(adx_wdt_remove), + .shutdown = adx_wdt_shutdown, + .driver = { + .name = WATCHDOG_NAME, + .owner = THIS_MODULE, + .pm = ADX_WDT_PM_OPS, + }, +}; + +static int __init adx_wdt_init(void) +{ + return platform_driver_register(&adx_wdt_driver); +} + +static void __exit adx_wdt_exit(void) +{ + platform_driver_unregister(&adx_wdt_driver); +} + +module_init(adx_wdt_init); +module_exit(adx_wdt_exit); + +MODULE_DESCRIPTION("Avionic Design Xanthos Watchdog Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Thierry Reding "); +MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); diff --git a/trunk/drivers/watchdog/s3c2410_wdt.c b/trunk/drivers/watchdog/s3c2410_wdt.c index a79e3840782a..5de7e4fa5b8a 100644 --- a/trunk/drivers/watchdog/s3c2410_wdt.c +++ b/trunk/drivers/watchdog/s3c2410_wdt.c @@ -401,8 +401,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) dev_info(dev, "watchdog %sactive, reset %sabled, irq %sabled\n", (wtcon & S3C2410_WTCON_ENABLE) ? "" : "in", - (wtcon & S3C2410_WTCON_RSTEN) ? "en" : "dis", - (wtcon & S3C2410_WTCON_INTEN) ? "en" : "dis"); + (wtcon & S3C2410_WTCON_RSTEN) ? "" : "dis", + (wtcon & S3C2410_WTCON_INTEN) ? "" : "en"); return 0; diff --git a/trunk/drivers/watchdog/wm831x_wdt.c b/trunk/drivers/watchdog/wm831x_wdt.c index e789a47db41f..7be38556aed0 100644 --- a/trunk/drivers/watchdog/wm831x_wdt.c +++ b/trunk/drivers/watchdog/wm831x_wdt.c @@ -150,7 +150,7 @@ static int wm831x_wdt_set_timeout(struct watchdog_device *wdt_dev, if (wm831x_wdt_cfgs[i].time == timeout) break; if (i == ARRAY_SIZE(wm831x_wdt_cfgs)) - return -EINVAL; + ret = -EINVAL; ret = wm831x_reg_unlock(wm831x); if (ret == 0) { diff --git a/trunk/fs/btrfs/backref.c b/trunk/fs/btrfs/backref.c index 22c64fff1bd5..8855aad3929c 100644 --- a/trunk/fs/btrfs/backref.c +++ b/trunk/fs/btrfs/backref.c @@ -683,7 +683,7 @@ static int inode_to_path(u64 inum, struct btrfs_inode_ref *iref, return PTR_ERR(fspath); if (fspath > fspath_min) { - ipath->fspath->val[i] = (u64)(unsigned long)fspath; + ipath->fspath->val[i] = (u64)fspath; ++ipath->fspath->elem_cnt; ipath->fspath->bytes_left = fspath - fspath_min; } else { diff --git a/trunk/fs/btrfs/ctree.c b/trunk/fs/btrfs/ctree.c index dede441bdeee..0fe615e4ea38 100644 --- a/trunk/fs/btrfs/ctree.c +++ b/trunk/fs/btrfs/ctree.c @@ -514,25 +514,10 @@ static inline int should_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf) { - /* ensure we can see the force_cow */ - smp_rmb(); - - /* - * We do not need to cow a block if - * 1) this block is not created or changed in this transaction; - * 2) this block does not belong to TREE_RELOC tree; - * 3) the root is not forced COW. - * - * What is forced COW: - * when we create snapshot during commiting the transaction, - * after we've finished coping src root, we must COW the shared - * block to ensure the metadata consistency. - */ if (btrfs_header_generation(buf) == trans->transid && !btrfs_header_flag(buf, BTRFS_HEADER_FLAG_WRITTEN) && !(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID && - btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC)) && - !root->force_cow) + btrfs_header_flag(buf, BTRFS_HEADER_FLAG_RELOC))) return 0; return 1; } diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index 04a5dfcee5a1..b9ba59ff9292 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -848,8 +848,7 @@ struct btrfs_free_cluster { enum btrfs_caching_type { BTRFS_CACHE_NO = 0, BTRFS_CACHE_STARTED = 1, - BTRFS_CACHE_FAST = 2, - BTRFS_CACHE_FINISHED = 3, + BTRFS_CACHE_FINISHED = 2, }; enum btrfs_disk_cache_state { @@ -1272,8 +1271,6 @@ struct btrfs_root { * for stat. It may be used for more later */ dev_t anon_dev; - - int force_cow; }; struct btrfs_ioctl_defrag_range_args { diff --git a/trunk/fs/btrfs/disk-io.c b/trunk/fs/btrfs/disk-io.c index 632f8f3cc9db..62afe5c5694e 100644 --- a/trunk/fs/btrfs/disk-io.c +++ b/trunk/fs/btrfs/disk-io.c @@ -620,7 +620,7 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, static int btree_io_failed_hook(struct bio *failed_bio, struct page *page, u64 start, u64 end, - int mirror_num, struct extent_state *state) + u64 mirror_num, struct extent_state *state) { struct extent_io_tree *tree; unsigned long len; @@ -2573,10 +2573,22 @@ static int write_dev_supers(struct btrfs_device *device, int errors = 0; u32 crc; u64 bytenr; + int last_barrier = 0; if (max_mirrors == 0) max_mirrors = BTRFS_SUPER_MIRROR_MAX; + /* make sure only the last submit_bh does a barrier */ + if (do_barriers) { + for (i = 0; i < max_mirrors; i++) { + bytenr = btrfs_sb_offset(i); + if (bytenr + BTRFS_SUPER_INFO_SIZE >= + device->total_bytes) + break; + last_barrier = i; + } + } + for (i = 0; i < max_mirrors; i++) { bytenr = btrfs_sb_offset(i); if (bytenr + BTRFS_SUPER_INFO_SIZE >= device->total_bytes) @@ -2622,134 +2634,15 @@ static int write_dev_supers(struct btrfs_device *device, bh->b_end_io = btrfs_end_buffer_write_sync; } - /* - * we fua the first super. The others we allow - * to go down lazy. - */ - ret = submit_bh(WRITE_FUA, bh); - if (ret) - errors++; - } - return errors < i ? 0 : -1; -} - -/* - * endio for the write_dev_flush, this will wake anyone waiting - * for the barrier when it is done - */ -static void btrfs_end_empty_barrier(struct bio *bio, int err) -{ - if (err) { - if (err == -EOPNOTSUPP) - set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); - clear_bit(BIO_UPTODATE, &bio->bi_flags); - } - if (bio->bi_private) - complete(bio->bi_private); - bio_put(bio); -} - -/* - * trigger flushes for one the devices. If you pass wait == 0, the flushes are - * sent down. With wait == 1, it waits for the previous flush. - * - * any device where the flush fails with eopnotsupp are flagged as not-barrier - * capable - */ -static int write_dev_flush(struct btrfs_device *device, int wait) -{ - struct bio *bio; - int ret = 0; - - if (device->nobarriers) - return 0; - - if (wait) { - bio = device->flush_bio; - if (!bio) - return 0; - - wait_for_completion(&device->flush_wait); - - if (bio_flagged(bio, BIO_EOPNOTSUPP)) { - printk("btrfs: disabling barriers on dev %s\n", - device->name); - device->nobarriers = 1; - } - if (!bio_flagged(bio, BIO_UPTODATE)) { - ret = -EIO; - } - - /* drop the reference from the wait == 0 run */ - bio_put(bio); - device->flush_bio = NULL; - - return ret; - } - - /* - * one reference for us, and we leave it for the - * caller - */ - device->flush_bio = NULL;; - bio = bio_alloc(GFP_NOFS, 0); - if (!bio) - return -ENOMEM; - - bio->bi_end_io = btrfs_end_empty_barrier; - bio->bi_bdev = device->bdev; - init_completion(&device->flush_wait); - bio->bi_private = &device->flush_wait; - device->flush_bio = bio; - - bio_get(bio); - submit_bio(WRITE_FLUSH, bio); - - return 0; -} - -/* - * send an empty flush down to each device in parallel, - * then wait for them - */ -static int barrier_all_devices(struct btrfs_fs_info *info) -{ - struct list_head *head; - struct btrfs_device *dev; - int errors = 0; - int ret; - - /* send down all the barriers */ - head = &info->fs_devices->devices; - list_for_each_entry_rcu(dev, head, dev_list) { - if (!dev->bdev) { - errors++; - continue; - } - if (!dev->in_fs_metadata || !dev->writeable) - continue; - - ret = write_dev_flush(dev, 0); - if (ret) - errors++; - } - - /* wait for all the barriers */ - list_for_each_entry_rcu(dev, head, dev_list) { - if (!dev->bdev) { - errors++; - continue; - } - if (!dev->in_fs_metadata || !dev->writeable) - continue; + if (i == last_barrier && do_barriers) + ret = submit_bh(WRITE_FLUSH_FUA, bh); + else + ret = submit_bh(WRITE_SYNC, bh); - ret = write_dev_flush(dev, 1); if (ret) errors++; } - if (errors) - return -EIO; - return 0; + return errors < i ? 0 : -1; } int write_all_supers(struct btrfs_root *root, int max_mirrors) @@ -2773,10 +2666,6 @@ int write_all_supers(struct btrfs_root *root, int max_mirrors) mutex_lock(&root->fs_info->fs_devices->device_list_mutex); head = &root->fs_info->fs_devices->devices; - - if (do_barriers) - barrier_all_devices(root->fs_info); - list_for_each_entry_rcu(dev, head, dev_list) { if (!dev->bdev) { total_errors++; diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index 930ae8949737..b232150b5b6b 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -467,59 +467,13 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, struct btrfs_root *root, int load_cache_only) { - DEFINE_WAIT(wait); struct btrfs_fs_info *fs_info = cache->fs_info; struct btrfs_caching_control *caching_ctl; int ret = 0; - caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS); - BUG_ON(!caching_ctl); - - INIT_LIST_HEAD(&caching_ctl->list); - mutex_init(&caching_ctl->mutex); - init_waitqueue_head(&caching_ctl->wait); - caching_ctl->block_group = cache; - caching_ctl->progress = cache->key.objectid; - atomic_set(&caching_ctl->count, 1); - caching_ctl->work.func = caching_thread; - - spin_lock(&cache->lock); - /* - * This should be a rare occasion, but this could happen I think in the - * case where one thread starts to load the space cache info, and then - * some other thread starts a transaction commit which tries to do an - * allocation while the other thread is still loading the space cache - * info. The previous loop should have kept us from choosing this block - * group, but if we've moved to the state where we will wait on caching - * block groups we need to first check if we're doing a fast load here, - * so we can wait for it to finish, otherwise we could end up allocating - * from a block group who's cache gets evicted for one reason or - * another. - */ - while (cache->cached == BTRFS_CACHE_FAST) { - struct btrfs_caching_control *ctl; - - ctl = cache->caching_ctl; - atomic_inc(&ctl->count); - prepare_to_wait(&ctl->wait, &wait, TASK_UNINTERRUPTIBLE); - spin_unlock(&cache->lock); - - schedule(); - - finish_wait(&ctl->wait, &wait); - put_caching_control(ctl); - spin_lock(&cache->lock); - } - - if (cache->cached != BTRFS_CACHE_NO) { - spin_unlock(&cache->lock); - kfree(caching_ctl); + smp_mb(); + if (cache->cached != BTRFS_CACHE_NO) return 0; - } - WARN_ON(cache->caching_ctl); - cache->caching_ctl = caching_ctl; - cache->cached = BTRFS_CACHE_FAST; - spin_unlock(&cache->lock); /* * We can't do the read from on-disk cache during a commit since we need @@ -530,51 +484,56 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, if (trans && (!trans->transaction->in_commit) && (root && root != root->fs_info->tree_root) && btrfs_test_opt(root, SPACE_CACHE)) { + spin_lock(&cache->lock); + if (cache->cached != BTRFS_CACHE_NO) { + spin_unlock(&cache->lock); + return 0; + } + cache->cached = BTRFS_CACHE_STARTED; + spin_unlock(&cache->lock); + ret = load_free_space_cache(fs_info, cache); spin_lock(&cache->lock); if (ret == 1) { - cache->caching_ctl = NULL; cache->cached = BTRFS_CACHE_FINISHED; cache->last_byte_to_unpin = (u64)-1; } else { - if (load_cache_only) { - cache->caching_ctl = NULL; - cache->cached = BTRFS_CACHE_NO; - } else { - cache->cached = BTRFS_CACHE_STARTED; - } + cache->cached = BTRFS_CACHE_NO; } spin_unlock(&cache->lock); - wake_up(&caching_ctl->wait); if (ret == 1) { - put_caching_control(caching_ctl); free_excluded_extents(fs_info->extent_root, cache); return 0; } - } else { - /* - * We are not going to do the fast caching, set cached to the - * appropriate value and wakeup any waiters. - */ - spin_lock(&cache->lock); - if (load_cache_only) { - cache->caching_ctl = NULL; - cache->cached = BTRFS_CACHE_NO; - } else { - cache->cached = BTRFS_CACHE_STARTED; - } - spin_unlock(&cache->lock); - wake_up(&caching_ctl->wait); } - if (load_cache_only) { - put_caching_control(caching_ctl); + if (load_cache_only) + return 0; + + caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS); + BUG_ON(!caching_ctl); + + INIT_LIST_HEAD(&caching_ctl->list); + mutex_init(&caching_ctl->mutex); + init_waitqueue_head(&caching_ctl->wait); + caching_ctl->block_group = cache; + caching_ctl->progress = cache->key.objectid; + /* one for caching kthread, one for caching block group list */ + atomic_set(&caching_ctl->count, 2); + caching_ctl->work.func = caching_thread; + + spin_lock(&cache->lock); + if (cache->cached != BTRFS_CACHE_NO) { + spin_unlock(&cache->lock); + kfree(caching_ctl); return 0; } + cache->caching_ctl = caching_ctl; + cache->cached = BTRFS_CACHE_STARTED; + spin_unlock(&cache->lock); down_write(&fs_info->extent_commit_sem); - atomic_inc(&caching_ctl->count); list_add_tail(&caching_ctl->list, &fs_info->caching_block_groups); up_write(&fs_info->extent_commit_sem); @@ -5219,15 +5178,13 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, } have_block_group: - cached = block_group_cache_done(block_group); - if (unlikely(!cached)) { + if (unlikely(block_group->cached == BTRFS_CACHE_NO)) { u64 free_percent; - found_uncached_bg = true; ret = cache_block_group(block_group, trans, orig_root, 1); if (block_group->cached == BTRFS_CACHE_FINISHED) - goto alloc; + goto have_block_group; free_percent = btrfs_block_group_used(&block_group->item); free_percent *= 100; @@ -5249,6 +5206,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, orig_root, 0); BUG_ON(ret); } + found_uncached_bg = true; /* * If loop is set for cached only, try the next block @@ -5258,7 +5216,10 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, goto loop; } -alloc: + cached = block_group_cache_done(block_group); + if (unlikely(!cached)) + found_uncached_bg = true; + if (unlikely(block_group->ro)) goto loop; diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index 9472d3de5e52..1f87c4d0e7a0 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -2285,8 +2285,8 @@ static void end_bio_extent_readpage(struct bio *bio, int err) clean_io_failure(start, page); } if (!uptodate) { - int failed_mirror; - failed_mirror = (int)(unsigned long)bio->bi_bdev; + u64 failed_mirror; + failed_mirror = (u64)bio->bi_bdev; if (tree->ops && tree->ops->readpage_io_failed_hook) ret = tree->ops->readpage_io_failed_hook( bio, page, start, end, @@ -3366,9 +3366,6 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, return -ENOMEM; path->leave_spinning = 1; - start = ALIGN(start, BTRFS_I(inode)->root->sectorsize); - len = ALIGN(len, BTRFS_I(inode)->root->sectorsize); - /* * lookup the last file extent. We're not using i_size here * because there might be preallocation past i_size @@ -3416,7 +3413,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0, &cached_state, GFP_NOFS); - em = get_extent_skip_holes(inode, start, last_for_get_extent, + em = get_extent_skip_holes(inode, off, last_for_get_extent, get_extent); if (!em) goto out; diff --git a/trunk/fs/btrfs/extent_io.h b/trunk/fs/btrfs/extent_io.h index 7604c3001322..feb9be0e23bc 100644 --- a/trunk/fs/btrfs/extent_io.h +++ b/trunk/fs/btrfs/extent_io.h @@ -70,7 +70,7 @@ struct extent_io_ops { unsigned long bio_flags); int (*readpage_io_hook)(struct page *page, u64 start, u64 end); int (*readpage_io_failed_hook)(struct bio *bio, struct page *page, - u64 start, u64 end, int failed_mirror, + u64 start, u64 end, u64 failed_mirror, struct extent_state *state); int (*writepage_io_failed_hook)(struct bio *bio, struct page *page, u64 start, u64 end, diff --git a/trunk/fs/btrfs/free-space-cache.c b/trunk/fs/btrfs/free-space-cache.c index 6e5b7e463698..181760f9d2ab 100644 --- a/trunk/fs/btrfs/free-space-cache.c +++ b/trunk/fs/btrfs/free-space-cache.c @@ -351,11 +351,6 @@ static int io_ctl_prepare_pages(struct io_ctl *io_ctl, struct inode *inode, } } - for (i = 0; i < io_ctl->num_pages; i++) { - clear_page_dirty_for_io(io_ctl->pages[i]); - set_page_extent_mapped(io_ctl->pages[i]); - } - return 0; } @@ -1849,13 +1844,7 @@ int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group, info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 1, 0); if (!info) { - /* the tree logging code might be calling us before we - * have fully loaded the free space rbtree for this - * block group. So it is possible the entry won't - * be in the rbtree yet at all. The caching code - * will make sure not to put it in the rbtree if - * the logging code has pinned it. - */ + WARN_ON(1); goto out_lock; } } @@ -2462,23 +2451,16 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, { struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; struct btrfs_free_space *entry; + struct rb_node *node; int ret = -ENOSPC; - u64 bitmap_offset = offset_to_bitmap(ctl, offset); if (ctl->total_bitmaps == 0) return -ENOSPC; /* - * The bitmap that covers offset won't be in the list unless offset - * is just its start offset. + * First check our cached list of bitmaps and see if there is an entry + * here that will work. */ - entry = list_first_entry(bitmaps, struct btrfs_free_space, list); - if (entry->offset != bitmap_offset) { - entry = tree_search_offset(ctl, bitmap_offset, 1, 0); - if (entry && list_empty(&entry->list)) - list_add(&entry->list, bitmaps); - } - list_for_each_entry(entry, bitmaps, list) { if (entry->bytes < min_bytes) continue; @@ -2489,10 +2471,38 @@ setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, } /* - * The bitmaps list has all the bitmaps that record free space - * starting after offset, so no more search is required. + * If we do have entries on our list and we are here then we didn't find + * anything, so go ahead and get the next entry after the last entry in + * this list and start the search from there. */ - return -ENOSPC; + if (!list_empty(bitmaps)) { + entry = list_entry(bitmaps->prev, struct btrfs_free_space, + list); + node = rb_next(&entry->offset_index); + if (!node) + return -ENOSPC; + entry = rb_entry(node, struct btrfs_free_space, offset_index); + goto search; + } + + entry = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 0, 1); + if (!entry) + return -ENOSPC; + +search: + node = &entry->offset_index; + do { + entry = rb_entry(node, struct btrfs_free_space, offset_index); + node = rb_next(&entry->offset_index); + if (!entry->bitmap) + continue; + if (entry->bytes < min_bytes) + continue; + ret = btrfs_bitmap_cluster(block_group, entry, cluster, offset, + bytes, min_bytes); + } while (ret && node); + + return ret; } /* @@ -2510,8 +2520,8 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans, u64 offset, u64 bytes, u64 empty_size) { struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; + struct list_head bitmaps; struct btrfs_free_space *entry, *tmp; - LIST_HEAD(bitmaps); u64 min_bytes; int ret; @@ -2550,6 +2560,7 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans, goto out; } + INIT_LIST_HEAD(&bitmaps); ret = setup_cluster_no_bitmap(block_group, cluster, &bitmaps, offset, bytes, min_bytes); if (ret) diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index 526dd51a1966..116ab67a06df 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -6794,13 +6794,11 @@ static int btrfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { struct inode *inode = dentry->d_inode; - u32 blocksize = inode->i_sb->s_blocksize; - generic_fillattr(inode, stat); stat->dev = BTRFS_I(inode)->root->anon_dev; stat->blksize = PAGE_CACHE_SIZE; - stat->blocks = (ALIGN(inode_get_bytes(inode), blocksize) + - ALIGN(BTRFS_I(inode)->delalloc_bytes, blocksize)) >> 9; + stat->blocks = (inode_get_bytes(inode) + + BTRFS_I(inode)->delalloc_bytes) >> 9; return 0; } diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index a90e749ed6d2..4a34c472f126 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -1216,12 +1216,12 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root, *devstr = '\0'; devstr = vol_args->name; devid = simple_strtoull(devstr, &end, 10); - printk(KERN_INFO "btrfs: resizing devid %llu\n", + printk(KERN_INFO "resizing devid %llu\n", (unsigned long long)devid); } device = btrfs_find_device(root, devid, NULL, NULL); if (!device) { - printk(KERN_INFO "btrfs: resizer unable to find device %llu\n", + printk(KERN_INFO "resizer unable to find device %llu\n", (unsigned long long)devid); ret = -EINVAL; goto out_unlock; @@ -1267,7 +1267,7 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root, do_div(new_size, root->sectorsize); new_size *= root->sectorsize; - printk(KERN_INFO "btrfs: new size for %s is %llu\n", + printk(KERN_INFO "new size for %s is %llu\n", device->name, (unsigned long long)new_size); if (new_size > old_size) { @@ -2930,13 +2930,11 @@ static long btrfs_ioctl_ino_to_path(struct btrfs_root *root, void __user *arg) goto out; for (i = 0; i < ipath->fspath->elem_cnt; ++i) { - rel_ptr = ipath->fspath->val[i] - - (u64)(unsigned long)ipath->fspath->val; + rel_ptr = ipath->fspath->val[i] - (u64)ipath->fspath->val; ipath->fspath->val[i] = rel_ptr; } - ret = copy_to_user((void *)(unsigned long)ipa->fspath, - (void *)(unsigned long)ipath->fspath, size); + ret = copy_to_user((void *)ipa->fspath, (void *)ipath->fspath, size); if (ret) { ret = -EFAULT; goto out; @@ -3019,8 +3017,7 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root, if (ret < 0) goto out; - ret = copy_to_user((void *)(unsigned long)loi->inodes, - (void *)(unsigned long)inodes, size); + ret = copy_to_user((void *)loi->inodes, (void *)inodes, size); if (ret) ret = -EFAULT; diff --git a/trunk/fs/btrfs/scrub.c b/trunk/fs/btrfs/scrub.c index fab420db5121..f4190f22edfb 100644 --- a/trunk/fs/btrfs/scrub.c +++ b/trunk/fs/btrfs/scrub.c @@ -272,7 +272,7 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root, void *ctx) swarn->logical, swarn->dev->name, (unsigned long long)swarn->sector, root, inum, offset, min(isize - offset, (u64)PAGE_SIZE), nlink, - (char *)(unsigned long)ipath->fspath->val[i]); + (char *)ipath->fspath->val[i]); free_ipath(ipath); return 0; diff --git a/trunk/fs/btrfs/transaction.c b/trunk/fs/btrfs/transaction.c index 81376d94cd3c..6a0574e923bc 100644 --- a/trunk/fs/btrfs/transaction.c +++ b/trunk/fs/btrfs/transaction.c @@ -785,10 +785,6 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans, btrfs_save_ino_cache(root, trans); - /* see comments in should_cow_block() */ - root->force_cow = 0; - smp_wmb(); - if (root->commit_root != root->node) { mutex_lock(&root->fs_commit_mutex); switch_commit_root(root); @@ -951,10 +947,6 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, btrfs_tree_unlock(old); free_extent_buffer(old); - /* see comments in should_cow_block() */ - root->force_cow = 1; - smp_wmb(); - btrfs_set_root_node(new_root_item, tmp); /* record when the snapshot was created in key.offset */ key.offset = trans->transid; diff --git a/trunk/fs/btrfs/volumes.h b/trunk/fs/btrfs/volumes.h index 78f2d4d4f37f..ab5b1c49f352 100644 --- a/trunk/fs/btrfs/volumes.h +++ b/trunk/fs/btrfs/volumes.h @@ -100,12 +100,6 @@ struct btrfs_device { struct reada_zone *reada_curr_zone; struct radix_tree_root reada_zones; struct radix_tree_root reada_extents; - - /* for sending down flush barriers */ - struct bio *flush_bio; - struct completion flush_wait; - int nobarriers; - }; struct btrfs_fs_devices { diff --git a/trunk/fs/ceph/dir.c b/trunk/fs/ceph/dir.c index bca3948e9dbf..2abd0dfad7f8 100644 --- a/trunk/fs/ceph/dir.c +++ b/trunk/fs/ceph/dir.c @@ -1143,7 +1143,7 @@ static void ceph_d_prune(struct dentry *dentry) { struct ceph_dentry_info *di; - dout("ceph_d_prune %p\n", dentry); + dout("d_release %p\n", dentry); /* do we have a valid parent? */ if (!dentry->d_parent || IS_ROOT(dentry)) diff --git a/trunk/fs/ceph/inode.c b/trunk/fs/ceph/inode.c index 116f36502f17..e392bfce84a3 100644 --- a/trunk/fs/ceph/inode.c +++ b/trunk/fs/ceph/inode.c @@ -1328,13 +1328,12 @@ int ceph_inode_set_size(struct inode *inode, loff_t size) */ void ceph_queue_writeback(struct inode *inode) { - ihold(inode); if (queue_work(ceph_inode_to_client(inode)->wb_wq, &ceph_inode(inode)->i_wb_work)) { dout("ceph_queue_writeback %p\n", inode); + ihold(inode); } else { dout("ceph_queue_writeback %p failed\n", inode); - iput(inode); } } @@ -1354,13 +1353,12 @@ static void ceph_writeback_work(struct work_struct *work) */ void ceph_queue_invalidate(struct inode *inode) { - ihold(inode); if (queue_work(ceph_inode_to_client(inode)->pg_inv_wq, &ceph_inode(inode)->i_pg_inv_work)) { dout("ceph_queue_invalidate %p\n", inode); + ihold(inode); } else { dout("ceph_queue_invalidate %p failed\n", inode); - iput(inode); } } @@ -1436,14 +1434,13 @@ void ceph_queue_vmtruncate(struct inode *inode) { struct ceph_inode_info *ci = ceph_inode(inode); - ihold(inode); if (queue_work(ceph_sb_to_client(inode->i_sb)->trunc_wq, &ci->i_vmtruncate_work)) { dout("ceph_queue_vmtruncate %p\n", inode); + ihold(inode); } else { dout("ceph_queue_vmtruncate %p failed, pending=%d\n", inode, ci->i_truncate_pending); - iput(inode); } } diff --git a/trunk/fs/ceph/super.c b/trunk/fs/ceph/super.c index 8dc73a594a90..a90846fac759 100644 --- a/trunk/fs/ceph/super.c +++ b/trunk/fs/ceph/super.c @@ -638,12 +638,10 @@ static struct dentry *open_root_dentry(struct ceph_fs_client *fsc, if (err == 0) { dout("open_root_inode success\n"); if (ceph_ino(req->r_target_inode) == CEPH_INO_ROOT && - fsc->sb->s_root == NULL) { + fsc->sb->s_root == NULL) root = d_alloc_root(req->r_target_inode); - ceph_init_dentry(root); - } else { + else root = d_obtain_alias(req->r_target_inode); - } req->r_target_inode = NULL; dout("open_root_inode success, root dentry is %p\n", root); } else { diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index 10ba92def3f6..a901c6901bce 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "internal.h" /* @@ -2384,16 +2383,8 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) actual = __d_unalias(inode, dentry, alias); } write_sequnlock(&rename_lock); - if (IS_ERR(actual)) { - if (PTR_ERR(actual) == -ELOOP) - pr_warn_ratelimited( - "VFS: Lookup of '%s' in %s %s" - " would have caused loop\n", - dentry->d_name.name, - inode->i_sb->s_type->name, - inode->i_sb->s_id); + if (IS_ERR(actual)) dput(alias); - } goto out_nolock; } } diff --git a/trunk/fs/ecryptfs/crypto.c b/trunk/fs/ecryptfs/crypto.c index 58609bde3b9f..203a1fdff666 100644 --- a/trunk/fs/ecryptfs/crypto.c +++ b/trunk/fs/ecryptfs/crypto.c @@ -967,7 +967,7 @@ static void ecryptfs_set_default_crypt_stat_vals( /** * ecryptfs_new_file_context - * @ecryptfs_dentry: The eCryptfs dentry + * @ecryptfs_inode: The eCryptfs inode * * If the crypto context for the file has not yet been established, * this is where we do that. Establishing a new crypto context @@ -984,13 +984,13 @@ static void ecryptfs_set_default_crypt_stat_vals( * * Returns zero on success; non-zero otherwise */ -int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry) +int ecryptfs_new_file_context(struct inode *ecryptfs_inode) { struct ecryptfs_crypt_stat *crypt_stat = - &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; + &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; struct ecryptfs_mount_crypt_stat *mount_crypt_stat = &ecryptfs_superblock_to_private( - ecryptfs_dentry->d_sb)->mount_crypt_stat; + ecryptfs_inode->i_sb)->mount_crypt_stat; int cipher_name_len; int rc = 0; @@ -1299,12 +1299,12 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t max, } static int -ecryptfs_write_metadata_to_contents(struct dentry *ecryptfs_dentry, +ecryptfs_write_metadata_to_contents(struct inode *ecryptfs_inode, char *virt, size_t virt_len) { int rc; - rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt, + rc = ecryptfs_write_lower(ecryptfs_inode, virt, 0, virt_len); if (rc < 0) printk(KERN_ERR "%s: Error attempting to write header " @@ -1338,7 +1338,8 @@ static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask, /** * ecryptfs_write_metadata - * @ecryptfs_dentry: The eCryptfs dentry + * @ecryptfs_dentry: The eCryptfs dentry, which should be negative + * @ecryptfs_inode: The newly created eCryptfs inode * * Write the file headers out. This will likely involve a userspace * callout, in which the session key is encrypted with one or more @@ -1348,10 +1349,11 @@ static unsigned long ecryptfs_get_zeroed_pages(gfp_t gfp_mask, * * Returns zero on success; non-zero on error */ -int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) +int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry, + struct inode *ecryptfs_inode) { struct ecryptfs_crypt_stat *crypt_stat = - &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; + &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; unsigned int order; char *virt; size_t virt_len; @@ -1391,7 +1393,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, virt, size); else - rc = ecryptfs_write_metadata_to_contents(ecryptfs_dentry, virt, + rc = ecryptfs_write_metadata_to_contents(ecryptfs_inode, virt, virt_len); if (rc) { printk(KERN_ERR "%s: Error writing metadata out to lower file; " diff --git a/trunk/fs/ecryptfs/ecryptfs_kernel.h b/trunk/fs/ecryptfs/ecryptfs_kernel.h index 54481a3b2c79..a9f29b12fbf2 100644 --- a/trunk/fs/ecryptfs/ecryptfs_kernel.h +++ b/trunk/fs/ecryptfs/ecryptfs_kernel.h @@ -584,9 +584,10 @@ int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat); int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode); int ecryptfs_encrypt_page(struct page *page); int ecryptfs_decrypt_page(struct page *page); -int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry); +int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry, + struct inode *ecryptfs_inode); int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry); -int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); +int ecryptfs_new_file_context(struct inode *ecryptfs_inode); void ecryptfs_write_crypt_stat_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat, size_t *written); diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index a36d327f1521..32f90a3ae63e 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -172,22 +172,23 @@ ecryptfs_create_underlying_file(struct inode *lower_dir_inode, * it. It will also update the eCryptfs directory inode to mimic the * stat of the lower directory inode. * - * Returns zero on success; non-zero on error condition + * Returns the new eCryptfs inode on success; an ERR_PTR on error condition */ -static int +static struct inode * ecryptfs_do_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, int mode) { int rc; struct dentry *lower_dentry; struct dentry *lower_dir_dentry; + struct inode *inode; lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); lower_dir_dentry = lock_parent(lower_dentry); if (IS_ERR(lower_dir_dentry)) { ecryptfs_printk(KERN_ERR, "Error locking directory of " "dentry\n"); - rc = PTR_ERR(lower_dir_dentry); + inode = ERR_CAST(lower_dir_dentry); goto out; } rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode, @@ -195,20 +196,19 @@ ecryptfs_do_create(struct inode *directory_inode, if (rc) { printk(KERN_ERR "%s: Failure to create dentry in lower fs; " "rc = [%d]\n", __func__, rc); + inode = ERR_PTR(rc); goto out_lock; } - rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, - directory_inode->i_sb); - if (rc) { - ecryptfs_printk(KERN_ERR, "Failure in ecryptfs_interpose\n"); + inode = __ecryptfs_get_inode(lower_dentry->d_inode, + directory_inode->i_sb); + if (IS_ERR(inode)) goto out_lock; - } fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); out_lock: unlock_dir(lower_dir_dentry); out: - return rc; + return inode; } /** @@ -219,26 +219,26 @@ ecryptfs_do_create(struct inode *directory_inode, * * Returns zero on success */ -static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) +static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, + struct inode *ecryptfs_inode) { struct ecryptfs_crypt_stat *crypt_stat = - &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; + &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; int rc = 0; - if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { + if (S_ISDIR(ecryptfs_inode->i_mode)) { ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); goto out; } ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); - rc = ecryptfs_new_file_context(ecryptfs_dentry); + rc = ecryptfs_new_file_context(ecryptfs_inode); if (rc) { ecryptfs_printk(KERN_ERR, "Error creating new file " "context; rc = [%d]\n", rc); goto out; } - rc = ecryptfs_get_lower_file(ecryptfs_dentry, - ecryptfs_dentry->d_inode); + rc = ecryptfs_get_lower_file(ecryptfs_dentry, ecryptfs_inode); if (rc) { printk(KERN_ERR "%s: Error attempting to initialize " "the lower file for the dentry with name " @@ -246,10 +246,10 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) ecryptfs_dentry->d_name.name, rc); goto out; } - rc = ecryptfs_write_metadata(ecryptfs_dentry); + rc = ecryptfs_write_metadata(ecryptfs_dentry, ecryptfs_inode); if (rc) printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); - ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); + ecryptfs_put_lower_file(ecryptfs_inode); out: return rc; } @@ -269,18 +269,28 @@ static int ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, int mode, struct nameidata *nd) { + struct inode *ecryptfs_inode; int rc; - /* ecryptfs_do_create() calls ecryptfs_interpose() */ - rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode); - if (unlikely(rc)) { + ecryptfs_inode = ecryptfs_do_create(directory_inode, ecryptfs_dentry, + mode); + if (unlikely(IS_ERR(ecryptfs_inode))) { ecryptfs_printk(KERN_WARNING, "Failed to create file in" "lower filesystem\n"); + rc = PTR_ERR(ecryptfs_inode); goto out; } /* At this point, a file exists on "disk"; we need to make sure * that this on disk file is prepared to be an ecryptfs file */ - rc = ecryptfs_initialize_file(ecryptfs_dentry); + rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); + if (rc) { + drop_nlink(ecryptfs_inode); + unlock_new_inode(ecryptfs_inode); + iput(ecryptfs_inode); + goto out; + } + d_instantiate(ecryptfs_dentry, ecryptfs_inode); + unlock_new_inode(ecryptfs_inode); out: return rc; } diff --git a/trunk/fs/ext4/balloc.c b/trunk/fs/ext4/balloc.c index 12ccacda44e0..f6dba4505f1c 100644 --- a/trunk/fs/ext4/balloc.c +++ b/trunk/fs/ext4/balloc.c @@ -565,7 +565,7 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb) brelse(bitmap_bh); printk(KERN_DEBUG "ext4_count_free_clusters: stored = %llu" ", computed = %llu, %llu\n", - EXT4_B2C(EXT4_SB(sb), ext4_free_blocks_count(es)), + EXT4_B2C(sbi, ext4_free_blocks_count(es)), desc_count, bitmap_count); return bitmap_count; #else diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index fffec40d5996..240f6e2dc7ee 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -2270,7 +2270,6 @@ static int ext4_da_writepages(struct address_space *mapping, ext4_msg(inode->i_sb, KERN_CRIT, "%s: jbd2_start: " "%ld pages, ino %lu; err %d", __func__, wbc->nr_to_write, inode->i_ino, ret); - blk_finish_plug(&plug); goto out_writepages; } diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 3858767ec672..9953d80145ad 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -1683,9 +1683,7 @@ static int parse_options(char *options, struct super_block *sb, data_opt = EXT4_MOUNT_WRITEBACK_DATA; datacheck: if (is_remount) { - if (!sbi->s_journal) - ext4_msg(sb, KERN_WARNING, "Remounting file system with no journal so ignoring journalled data option"); - else if (test_opt(sb, DATA_FLAGS) != data_opt) { + if (test_opt(sb, DATA_FLAGS) != data_opt) { ext4_msg(sb, KERN_ERR, "Cannot change data mode on remount"); return 0; @@ -3101,6 +3099,8 @@ static void ext4_destroy_lazyinit_thread(void) } static int ext4_fill_super(struct super_block *sb, void *data, int silent) + __releases(kernel_lock) + __acquires(kernel_lock) { char *orig_data = kstrdup(data, GFP_KERNEL); struct buffer_head *bh; diff --git a/trunk/fs/minix/bitmap.c b/trunk/fs/minix/bitmap.c index ef175cb8cfd8..3f32bcb0d9bd 100644 --- a/trunk/fs/minix/bitmap.c +++ b/trunk/fs/minix/bitmap.c @@ -16,26 +16,38 @@ #include #include +static const int nibblemap[] = { 4,3,3,2,3,2,2,1,3,2,2,1,2,1,1,0 }; + static DEFINE_SPINLOCK(bitmap_lock); -/* - * bitmap consists of blocks filled with 16bit words - * bit set == busy, bit clear == free - * endianness is a mess, but for counting zero bits it really doesn't matter... - */ -static __u32 count_free(struct buffer_head *map[], unsigned blocksize, __u32 numbits) +static unsigned long count_free(struct buffer_head *map[], unsigned numblocks, __u32 numbits) { - __u32 sum = 0; - unsigned blocks = DIV_ROUND_UP(numbits, blocksize * 8); + unsigned i, j, sum = 0; + struct buffer_head *bh; + + for (i=0; ib_size; j++) + sum += nibblemap[bh->b_data[j] & 0xf] + + nibblemap[(bh->b_data[j]>>4) & 0xf]; + } - while (blocks--) { - unsigned words = blocksize / 2; - __u16 *p = (__u16 *)(*map++)->b_data; - while (words--) - sum += 16 - hweight16(*p++); + if (numblocks==0 || !(bh=map[numblocks-1])) + return(0); + i = ((numbits - (numblocks-1) * bh->b_size * 8) / 16) * 2; + for (j=0; jb_data[j] & 0xf] + + nibblemap[(bh->b_data[j]>>4) & 0xf]; } - return sum; + i = numbits%16; + if (i!=0) { + i = *(__u16 *)(&bh->b_data[j]) | ~((1<>4) & 0xf]; + sum += nibblemap[(i>>8) & 0xf] + nibblemap[(i>>12) & 0xf]; + } + return(sum); } void minix_free_block(struct inode *inode, unsigned long block) @@ -93,12 +105,10 @@ int minix_new_block(struct inode * inode) return 0; } -unsigned long minix_count_free_blocks(struct super_block *sb) +unsigned long minix_count_free_blocks(struct minix_sb_info *sbi) { - struct minix_sb_info *sbi = minix_sb(sb); - u32 bits = sbi->s_nzones - (sbi->s_firstdatazone + 1); - - return (count_free(sbi->s_zmap, sb->s_blocksize, bits) + return (count_free(sbi->s_zmap, sbi->s_zmap_blocks, + sbi->s_nzones - sbi->s_firstdatazone + 1) << sbi->s_log_zone_size); } @@ -263,10 +273,7 @@ struct inode *minix_new_inode(const struct inode *dir, int mode, int *error) return inode; } -unsigned long minix_count_free_inodes(struct super_block *sb) +unsigned long minix_count_free_inodes(struct minix_sb_info *sbi) { - struct minix_sb_info *sbi = minix_sb(sb); - u32 bits = sbi->s_ninodes + 1; - - return count_free(sbi->s_imap, sb->s_blocksize, bits); + return count_free(sbi->s_imap, sbi->s_imap_blocks, sbi->s_ninodes + 1); } diff --git a/trunk/fs/minix/inode.c b/trunk/fs/minix/inode.c index 1d9e33966db0..64cdcd662ffc 100644 --- a/trunk/fs/minix/inode.c +++ b/trunk/fs/minix/inode.c @@ -279,27 +279,6 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) else if (sbi->s_mount_state & MINIX_ERROR_FS) printk("MINIX-fs: mounting file system with errors, " "running fsck is recommended\n"); - - /* Apparently minix can create filesystems that allocate more blocks for - * the bitmaps than needed. We simply ignore that, but verify it didn't - * create one with not enough blocks and bail out if so. - */ - block = minix_blocks_needed(sbi->s_ninodes, s->s_blocksize); - if (sbi->s_imap_blocks < block) { - printk("MINIX-fs: file system does not have enough " - "imap blocks allocated. Refusing to mount\n"); - goto out_iput; - } - - block = minix_blocks_needed( - (sbi->s_nzones - (sbi->s_firstdatazone + 1)), - s->s_blocksize); - if (sbi->s_zmap_blocks < block) { - printk("MINIX-fs: file system does not have enough " - "zmap blocks allocated. Refusing to mount.\n"); - goto out_iput; - } - return 0; out_iput: @@ -360,10 +339,10 @@ static int minix_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_type = sb->s_magic; buf->f_bsize = sb->s_blocksize; buf->f_blocks = (sbi->s_nzones - sbi->s_firstdatazone) << sbi->s_log_zone_size; - buf->f_bfree = minix_count_free_blocks(sb); + buf->f_bfree = minix_count_free_blocks(sbi); buf->f_bavail = buf->f_bfree; buf->f_files = sbi->s_ninodes; - buf->f_ffree = minix_count_free_inodes(sb); + buf->f_ffree = minix_count_free_inodes(sbi); buf->f_namelen = sbi->s_namelen; buf->f_fsid.val[0] = (u32)id; buf->f_fsid.val[1] = (u32)(id >> 32); diff --git a/trunk/fs/minix/minix.h b/trunk/fs/minix/minix.h index 26bbd55e82ea..341e2122879a 100644 --- a/trunk/fs/minix/minix.h +++ b/trunk/fs/minix/minix.h @@ -48,10 +48,10 @@ extern struct minix_inode * minix_V1_raw_inode(struct super_block *, ino_t, stru extern struct minix2_inode * minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **); extern struct inode * minix_new_inode(const struct inode *, int, int *); extern void minix_free_inode(struct inode * inode); -extern unsigned long minix_count_free_inodes(struct super_block *sb); +extern unsigned long minix_count_free_inodes(struct minix_sb_info *sbi); extern int minix_new_block(struct inode * inode); extern void minix_free_block(struct inode *inode, unsigned long block); -extern unsigned long minix_count_free_blocks(struct super_block *sb); +extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi); extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len); @@ -88,11 +88,6 @@ static inline struct minix_inode_info *minix_i(struct inode *inode) return list_entry(inode, struct minix_inode_info, vfs_inode); } -static inline unsigned minix_blocks_needed(unsigned bits, unsigned blocksize) -{ - return DIV_ROUND_UP(bits, blocksize * 8); -} - #if defined(CONFIG_MINIX_FS_NATIVE_ENDIAN) && \ defined(CONFIG_MINIX_FS_BIG_ENDIAN_16BIT_INDEXED) @@ -130,7 +125,7 @@ static inline int minix_find_first_zero_bit(const void *vaddr, unsigned size) if (!size) return 0; - size >>= 4; + size = (size >> 4) + ((size & 15) > 0); while (*p++ == 0xffff) { if (--size == 0) return (p - addr) << 4; diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index 6d3a1963879b..50ee30345b4f 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -2493,7 +2493,6 @@ EXPORT_SYMBOL(create_mnt_ns); struct dentry *mount_subtree(struct vfsmount *mnt, const char *name) { struct mnt_namespace *ns; - struct super_block *s; struct path path; int err; @@ -2510,11 +2509,10 @@ struct dentry *mount_subtree(struct vfsmount *mnt, const char *name) return ERR_PTR(err); /* trade a vfsmount reference for active sb one */ - s = path.mnt->mnt_sb; - atomic_inc(&s->s_active); + atomic_inc(&path.mnt->mnt_sb->s_active); mntput(path.mnt); /* lock the sucker */ - down_write(&s->s_umount); + down_write(&path.mnt->mnt_sb->s_umount); /* ... and return the root of (sub)tree on it */ return path.dentry; } diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index ac2899098147..b238d95ac48c 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -1468,12 +1468,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry res = NULL; goto out; /* This turned out not to be a regular file */ - case -EISDIR: case -ENOTDIR: goto no_open; case -ELOOP: if (!(nd->intent.open.flags & O_NOFOLLOW)) goto no_open; + /* case -EISDIR: */ /* case -EINVAL: */ default: res = ERR_CAST(inode); diff --git a/trunk/fs/nfs/file.c b/trunk/fs/nfs/file.c index eca56d4b39c0..0a1f8312b4dc 100644 --- a/trunk/fs/nfs/file.c +++ b/trunk/fs/nfs/file.c @@ -40,8 +40,48 @@ #define NFSDBG_FACILITY NFSDBG_FILE +static int nfs_file_open(struct inode *, struct file *); +static int nfs_file_release(struct inode *, struct file *); +static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin); +static int nfs_file_mmap(struct file *, struct vm_area_struct *); +static ssize_t nfs_file_splice_read(struct file *filp, loff_t *ppos, + struct pipe_inode_info *pipe, + size_t count, unsigned int flags); +static ssize_t nfs_file_read(struct kiocb *, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); +static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe, + struct file *filp, loff_t *ppos, + size_t count, unsigned int flags); +static ssize_t nfs_file_write(struct kiocb *, const struct iovec *iov, + unsigned long nr_segs, loff_t pos); +static int nfs_file_flush(struct file *, fl_owner_t id); +static int nfs_file_fsync(struct file *, loff_t, loff_t, int datasync); +static int nfs_check_flags(int flags); +static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); +static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); +static int nfs_setlease(struct file *file, long arg, struct file_lock **fl); + static const struct vm_operations_struct nfs_file_vm_ops; +const struct file_operations nfs_file_operations = { + .llseek = nfs_file_llseek, + .read = do_sync_read, + .write = do_sync_write, + .aio_read = nfs_file_read, + .aio_write = nfs_file_write, + .mmap = nfs_file_mmap, + .open = nfs_file_open, + .flush = nfs_file_flush, + .release = nfs_file_release, + .fsync = nfs_file_fsync, + .lock = nfs_lock, + .flock = nfs_flock, + .splice_read = nfs_file_splice_read, + .splice_write = nfs_file_splice_write, + .check_flags = nfs_check_flags, + .setlease = nfs_setlease, +}; + const struct inode_operations nfs_file_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, @@ -846,54 +886,3 @@ static int nfs_setlease(struct file *file, long arg, struct file_lock **fl) file->f_path.dentry->d_name.name, arg); return -EINVAL; } - -const struct file_operations nfs_file_operations = { - .llseek = nfs_file_llseek, - .read = do_sync_read, - .write = do_sync_write, - .aio_read = nfs_file_read, - .aio_write = nfs_file_write, - .mmap = nfs_file_mmap, - .open = nfs_file_open, - .flush = nfs_file_flush, - .release = nfs_file_release, - .fsync = nfs_file_fsync, - .lock = nfs_lock, - .flock = nfs_flock, - .splice_read = nfs_file_splice_read, - .splice_write = nfs_file_splice_write, - .check_flags = nfs_check_flags, - .setlease = nfs_setlease, -}; - -#ifdef CONFIG_NFS_V4 -static int -nfs4_file_open(struct inode *inode, struct file *filp) -{ - /* - * NFSv4 opens are handled in d_lookup and d_revalidate. If we get to - * this point, then something is very wrong - */ - dprintk("NFS: %s called! inode=%p filp=%p\n", __func__, inode, filp); - return -ENOTDIR; -} - -const struct file_operations nfs4_file_operations = { - .llseek = nfs_file_llseek, - .read = do_sync_read, - .write = do_sync_write, - .aio_read = nfs_file_read, - .aio_write = nfs_file_write, - .mmap = nfs_file_mmap, - .open = nfs4_file_open, - .flush = nfs_file_flush, - .release = nfs_file_release, - .fsync = nfs_file_fsync, - .lock = nfs_lock, - .flock = nfs_flock, - .splice_read = nfs_file_splice_read, - .splice_write = nfs_file_splice_write, - .check_flags = nfs_check_flags, - .setlease = nfs_setlease, -}; -#endif /* CONFIG_NFS_V4 */ diff --git a/trunk/fs/nfs/inode.c b/trunk/fs/nfs/inode.c index 50a15fa8cf98..c07a55aec838 100644 --- a/trunk/fs/nfs/inode.c +++ b/trunk/fs/nfs/inode.c @@ -291,7 +291,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) */ inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->file_inode_ops; if (S_ISREG(inode->i_mode)) { - inode->i_fop = NFS_SB(sb)->nfs_client->rpc_ops->file_ops; + inode->i_fop = &nfs_file_operations; inode->i_data.a_ops = &nfs_file_aops; inode->i_data.backing_dev_info = &NFS_SB(sb)->backing_dev_info; } else if (S_ISDIR(inode->i_mode)) { diff --git a/trunk/fs/nfs/internal.h b/trunk/fs/nfs/internal.h index 3f4d95751d52..c1a1bd8ddf1c 100644 --- a/trunk/fs/nfs/internal.h +++ b/trunk/fs/nfs/internal.h @@ -299,8 +299,6 @@ extern void nfs_read_prepare(struct rpc_task *task, void *calldata); extern int nfs_generic_pagein(struct nfs_pageio_descriptor *desc, struct list_head *head); -extern void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio, - struct inode *inode); extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio); extern void nfs_readdata_release(struct nfs_read_data *rdata); diff --git a/trunk/fs/nfs/nfs3proc.c b/trunk/fs/nfs/nfs3proc.c index d4bc9ed91748..85f1690ca08c 100644 --- a/trunk/fs/nfs/nfs3proc.c +++ b/trunk/fs/nfs/nfs3proc.c @@ -853,7 +853,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = { .dentry_ops = &nfs_dentry_operations, .dir_inode_ops = &nfs3_dir_inode_operations, .file_inode_ops = &nfs3_file_inode_operations, - .file_ops = &nfs_file_operations, .getroot = nfs3_proc_get_root, .getattr = nfs3_proc_getattr, .setattr = nfs3_proc_setattr, diff --git a/trunk/fs/nfs/nfs4proc.c b/trunk/fs/nfs/nfs4proc.c index be2bbac13817..b60fddf606f7 100644 --- a/trunk/fs/nfs/nfs4proc.c +++ b/trunk/fs/nfs/nfs4proc.c @@ -2464,7 +2464,8 @@ static int nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir, struct qst case -NFS4ERR_BADNAME: return -ENOENT; case -NFS4ERR_MOVED: - return nfs4_get_referral(dir, name, fattr, fhandle); + err = nfs4_get_referral(dir, name, fattr, fhandle); + break; case -NFS4ERR_WRONGSEC: nfs_fixup_secinfo_attributes(fattr, fhandle); } @@ -6252,7 +6253,6 @@ const struct nfs_rpc_ops nfs_v4_clientops = { .dentry_ops = &nfs4_dentry_operations, .dir_inode_ops = &nfs4_dir_inode_operations, .file_inode_ops = &nfs4_file_inode_operations, - .file_ops = &nfs4_file_operations, .getroot = nfs4_proc_get_root, .getattr = nfs4_proc_getattr, .setattr = nfs4_proc_setattr, diff --git a/trunk/fs/nfs/pnfs.c b/trunk/fs/nfs/pnfs.c index 8e672a2b2d69..baf73536bc04 100644 --- a/trunk/fs/nfs/pnfs.c +++ b/trunk/fs/nfs/pnfs.c @@ -1260,25 +1260,6 @@ pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) } EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages); -static void pnfs_ld_handle_read_error(struct nfs_read_data *data) -{ - struct nfs_pageio_descriptor pgio; - - put_lseg(data->lseg); - data->lseg = NULL; - dprintk("pnfs write error = %d\n", data->pnfs_error); - - nfs_pageio_init_read_mds(&pgio, data->inode); - - while (!list_empty(&data->pages)) { - struct nfs_page *req = nfs_list_entry(data->pages.next); - - nfs_list_remove_request(req); - nfs_pageio_add_request(&pgio, req); - } - nfs_pageio_complete(&pgio); -} - /* * Called by non rpc-based layout drivers */ @@ -1287,8 +1268,11 @@ void pnfs_ld_read_done(struct nfs_read_data *data) if (likely(!data->pnfs_error)) { __nfs4_read_done_cb(data); data->mds_ops->rpc_call_done(&data->task, data); - } else - pnfs_ld_handle_read_error(data); + } else { + put_lseg(data->lseg); + data->lseg = NULL; + dprintk("pnfs write error = %d\n", data->pnfs_error); + } data->mds_ops->rpc_release(data); } EXPORT_SYMBOL_GPL(pnfs_ld_read_done); diff --git a/trunk/fs/nfs/proc.c b/trunk/fs/nfs/proc.c index f48125da198a..ac40b8535d7e 100644 --- a/trunk/fs/nfs/proc.c +++ b/trunk/fs/nfs/proc.c @@ -710,7 +710,6 @@ const struct nfs_rpc_ops nfs_v2_clientops = { .dentry_ops = &nfs_dentry_operations, .dir_inode_ops = &nfs_dir_inode_operations, .file_inode_ops = &nfs_file_inode_operations, - .file_ops = &nfs_file_operations, .getroot = nfs_proc_get_root, .getattr = nfs_proc_getattr, .setattr = nfs_proc_setattr, diff --git a/trunk/fs/nfs/read.c b/trunk/fs/nfs/read.c index cfa175c223dc..8b48ec63f722 100644 --- a/trunk/fs/nfs/read.c +++ b/trunk/fs/nfs/read.c @@ -109,7 +109,7 @@ static void nfs_readpage_truncate_uninitialised_page(struct nfs_read_data *data) } } -void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio, +static void nfs_pageio_init_read_mds(struct nfs_pageio_descriptor *pgio, struct inode *inode) { nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops, @@ -534,13 +534,23 @@ static void nfs_readpage_result_full(struct rpc_task *task, void *calldata) static void nfs_readpage_release_full(void *calldata) { struct nfs_read_data *data = calldata; + struct nfs_pageio_descriptor pgio; + if (data->pnfs_error) { + nfs_pageio_init_read_mds(&pgio, data->inode); + pgio.pg_recoalesce = 1; + } while (!list_empty(&data->pages)) { struct nfs_page *req = nfs_list_entry(data->pages.next); nfs_list_remove_request(req); - nfs_readpage_release(req); + if (!data->pnfs_error) + nfs_readpage_release(req); + else + nfs_pageio_add_request(&pgio, req); } + if (data->pnfs_error) + nfs_pageio_complete(&pgio); nfs_readdata_release(calldata); } diff --git a/trunk/include/drm/drm_mode.h b/trunk/include/drm/drm_mode.h index ddd46db65b57..d30bedfeb7ef 100644 --- a/trunk/include/drm/drm_mode.h +++ b/trunk/include/drm/drm_mode.h @@ -235,8 +235,6 @@ struct drm_mode_fb_cmd { #define DRM_MODE_FB_DIRTY_ANNOTATE_FILL 0x02 #define DRM_MODE_FB_DIRTY_FLAGS 0x03 -#define DRM_MODE_FB_DIRTY_MAX_CLIPS 256 - /* * Mark a region of a framebuffer as dirty. * diff --git a/trunk/include/drm/radeon_drm.h b/trunk/include/drm/radeon_drm.h index be94be6d6f17..b65be6054a18 100644 --- a/trunk/include/drm/radeon_drm.h +++ b/trunk/include/drm/radeon_drm.h @@ -874,10 +874,6 @@ struct drm_radeon_gem_pwrite { #define RADEON_CHUNK_ID_RELOCS 0x01 #define RADEON_CHUNK_ID_IB 0x02 -#define RADEON_CHUNK_ID_FLAGS 0x03 - -/* The first dword of RADEON_CHUNK_ID_FLAGS is a uint32 of these flags: */ -#define RADEON_CS_KEEP_TILING_FLAGS 0x01 struct drm_radeon_cs_chunk { uint32_t chunk_id; diff --git a/trunk/include/linux/ceph/osd_client.h b/trunk/include/linux/ceph/osd_client.h index 7c05ac202d90..f88eacb111d4 100644 --- a/trunk/include/linux/ceph/osd_client.h +++ b/trunk/include/linux/ceph/osd_client.h @@ -10,12 +10,6 @@ #include "osdmap.h" #include "messenger.h" -/* - * Maximum object name size - * (must be at least as big as RBD_MAX_MD_NAME_LEN -- currently 100) - */ -#define MAX_OBJ_NAME_SIZE 100 - struct ceph_msg; struct ceph_snap_context; struct ceph_osd_request; @@ -81,7 +75,7 @@ struct ceph_osd_request { struct inode *r_inode; /* for use by callbacks */ void *r_priv; /* ditto */ - char r_oid[MAX_OBJ_NAME_SIZE]; /* object name */ + char r_oid[40]; /* object name */ int r_oid_len; unsigned long r_stamp; /* send OR check time */ diff --git a/trunk/include/linux/device.h b/trunk/include/linux/device.h index 3136ede5a1e1..52b3a4111df9 100644 --- a/trunk/include/linux/device.h +++ b/trunk/include/linux/device.h @@ -69,7 +69,7 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); * @resume: Called to bring a device on this bus out of sleep mode. * @pm: Power management operations of this bus, callback the specific * device driver's pm-ops. - * @iommu_ops: IOMMU specific operations for this bus, used to attach IOMMU + * @iommu_ops IOMMU specific operations for this bus, used to attach IOMMU * driver implementations to a bus and allow the driver to do * bus-specific setup * @p: The private data of the driver core, only the driver core can diff --git a/trunk/include/linux/i2c.h b/trunk/include/linux/i2c.h index 07d103a06d64..a81bf6d23b3e 100644 --- a/trunk/include/linux/i2c.h +++ b/trunk/include/linux/i2c.h @@ -432,6 +432,9 @@ void i2c_unlock_adapter(struct i2c_adapter *); /* Internal numbers to terminate lists */ #define I2C_CLIENT_END 0xfffeU +/* The numbers to use to set I2C bus address */ +#define ANY_I2C_BUS 0xffff + /* Construct an I2C_CLIENT_END-terminated array of i2c addresses */ #define I2C_ADDRS(addr, addrs...) \ ((const unsigned short []){ addr, ## addrs, I2C_CLIENT_END }) diff --git a/trunk/include/linux/init_task.h b/trunk/include/linux/init_task.h index 94b1e356c02a..08ffab01e76c 100644 --- a/trunk/include/linux/init_task.h +++ b/trunk/include/linux/init_task.h @@ -184,6 +184,7 @@ extern struct cred init_cred; [PIDTYPE_SID] = INIT_PID_LINK(PIDTYPE_SID), \ }, \ .thread_group = LIST_HEAD_INIT(tsk.thread_group), \ + .dirties = INIT_PROP_LOCAL_SINGLE(dirties), \ INIT_IDS \ INIT_PERF_EVENTS(tsk) \ INIT_TRACE_IRQFLAGS \ diff --git a/trunk/include/linux/mfd/tps65910.h b/trunk/include/linux/mfd/tps65910.h index 8bf2cb9502dd..82b4c8801a4f 100644 --- a/trunk/include/linux/mfd/tps65910.h +++ b/trunk/include/linux/mfd/tps65910.h @@ -243,8 +243,7 @@ /*Registers VDD1, VDD2 voltage values definitions */ -#define VDD1_2_NUM_VOLT_FINE 73 -#define VDD1_2_NUM_VOLT_COARSE 3 +#define VDD1_2_NUM_VOLTS 73 #define VDD1_2_MIN_VOLT 6000 #define VDD1_2_OFFSET 125 diff --git a/trunk/include/linux/nfs_fs.h b/trunk/include/linux/nfs_fs.h index 92ecf5585fac..ab2c6343361a 100644 --- a/trunk/include/linux/nfs_fs.h +++ b/trunk/include/linux/nfs_fs.h @@ -410,9 +410,6 @@ extern const struct inode_operations nfs_file_inode_operations; extern const struct inode_operations nfs3_file_inode_operations; #endif /* CONFIG_NFS_V3 */ extern const struct file_operations nfs_file_operations; -#ifdef CONFIG_NFS_V4 -extern const struct file_operations nfs4_file_operations; -#endif /* CONFIG_NFS_V4 */ extern const struct address_space_operations nfs_file_aops; extern const struct address_space_operations nfs_dir_aops; diff --git a/trunk/include/linux/nfs_xdr.h b/trunk/include/linux/nfs_xdr.h index 2a7c533be5dd..c74595ba7094 100644 --- a/trunk/include/linux/nfs_xdr.h +++ b/trunk/include/linux/nfs_xdr.h @@ -1192,7 +1192,6 @@ struct nfs_rpc_ops { const struct dentry_operations *dentry_ops; const struct inode_operations *dir_inode_ops; const struct inode_operations *file_inode_ops; - const struct file_operations *file_ops; int (*getroot) (struct nfs_server *, struct nfs_fh *, struct nfs_fsinfo *); diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 1c4f3e9b9bc5..68daf4f27e2c 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -1521,6 +1521,7 @@ struct task_struct { #ifdef CONFIG_FAULT_INJECTION int make_it_fail; #endif + struct prop_local_single dirties; /* * when (nr_dirtied >= nr_dirtied_pause), it's time to call * balance_dirty_pages() for some dirty throttling pause diff --git a/trunk/include/linux/serial.h b/trunk/include/linux/serial.h index 3d86517fe7d5..97ff8e27a6cc 100644 --- a/trunk/include/linux/serial.h +++ b/trunk/include/linux/serial.h @@ -207,15 +207,13 @@ struct serial_icounter_struct { struct serial_rs485 { __u32 flags; /* RS485 feature flags */ -#define SER_RS485_ENABLED (1 << 0) /* If enabled */ -#define SER_RS485_RTS_ON_SEND (1 << 1) /* Logical level for - RTS pin when - sending */ -#define SER_RS485_RTS_AFTER_SEND (1 << 2) /* Logical level for - RTS pin after sent*/ +#define SER_RS485_ENABLED (1 << 0) +#define SER_RS485_RTS_ON_SEND (1 << 1) +#define SER_RS485_RTS_AFTER_SEND (1 << 2) +#define SER_RS485_RTS_BEFORE_SEND (1 << 3) #define SER_RS485_RX_DURING_TX (1 << 4) - __u32 delay_rts_before_send; /* Delay before send (milliseconds) */ - __u32 delay_rts_after_send; /* Delay after send (milliseconds) */ + __u32 delay_rts_before_send; /* Milliseconds */ + __u32 delay_rts_after_send; /* Milliseconds */ __u32 padding[5]; /* Memory is cheap, new structs are a royal PITA .. */ }; diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index da4a6a10d088..ba0d17261329 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -162,6 +162,7 @@ static void account_kernel_stack(struct thread_info *ti, int account) void free_task(struct task_struct *tsk) { + prop_local_destroy_single(&tsk->dirties); account_kernel_stack(tsk->stack, -1); free_thread_info(tsk->stack); rt_mutex_debug_task_free(tsk); @@ -273,6 +274,10 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) tsk->stack = ti; + err = prop_local_init_single(&tsk->dirties); + if (err) + goto out; + setup_thread_stack(tsk, orig); clear_user_return_notifier(tsk); clear_tsk_need_resched(tsk); diff --git a/trunk/mm/page-writeback.c b/trunk/mm/page-writeback.c index 71252486bc6f..a3278f005230 100644 --- a/trunk/mm/page-writeback.c +++ b/trunk/mm/page-writeback.c @@ -128,6 +128,7 @@ unsigned long global_dirty_limit; * */ static struct prop_descriptor vm_completions; +static struct prop_descriptor vm_dirties; /* * couple the period to the dirty_ratio: @@ -153,6 +154,7 @@ static void update_completion_period(void) { int shift = calc_period_shift(); prop_change_shift(&vm_completions, shift); + prop_change_shift(&vm_dirties, shift); writeback_set_ratelimit(); } @@ -233,6 +235,11 @@ void bdi_writeout_inc(struct backing_dev_info *bdi) } EXPORT_SYMBOL_GPL(bdi_writeout_inc); +void task_dirty_inc(struct task_struct *tsk) +{ + prop_inc_single(&vm_dirties, &tsk->dirties); +} + /* * Obtain an accurate fraction of the BDI's portion. */ @@ -1126,17 +1133,17 @@ static void balance_dirty_pages(struct address_space *mapping, pages_dirtied, pause, start_time); - __set_current_state(TASK_KILLABLE); + __set_current_state(TASK_UNINTERRUPTIBLE); io_schedule_timeout(pause); + dirty_thresh = hard_dirty_limit(dirty_thresh); /* - * This is typically equal to (nr_dirty < dirty_thresh) and can - * also keep "1000+ dd on a slow USB stick" under control. + * max-pause area. If dirty exceeded but still within this + * area, no need to sleep for more than 200ms: (a) 8 pages per + * 200ms is typically more than enough to curb heavy dirtiers; + * (b) the pause time limit makes the dirtiers more responsive. */ - if (task_ratelimit) - break; - - if (fatal_signal_pending(current)) + if (nr_dirty < dirty_thresh) break; } @@ -1388,6 +1395,7 @@ void __init page_writeback_init(void) shift = calc_period_shift(); prop_descriptor_init(&vm_completions, shift); + prop_descriptor_init(&vm_dirties, shift); } /** @@ -1716,6 +1724,7 @@ void account_page_dirtied(struct page *page, struct address_space *mapping) __inc_zone_page_state(page, NR_DIRTIED); __inc_bdi_stat(mapping->backing_dev_info, BDI_RECLAIMABLE); __inc_bdi_stat(mapping->backing_dev_info, BDI_DIRTIED); + task_dirty_inc(current); task_io_account_write(PAGE_CACHE_SIZE); } } diff --git a/trunk/net/ceph/osd_client.c b/trunk/net/ceph/osd_client.c index f4f3f58f5234..733e46008b89 100644 --- a/trunk/net/ceph/osd_client.c +++ b/trunk/net/ceph/osd_client.c @@ -244,7 +244,7 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc, ceph_pagelist_init(req->r_trail); } /* create request message; allow space for oid */ - msg_size += MAX_OBJ_NAME_SIZE; + msg_size += 40; if (snapc) msg_size += sizeof(u64) * snapc->num_snaps; if (use_mempool) diff --git a/trunk/net/sunrpc/xprtsock.c b/trunk/net/sunrpc/xprtsock.c index 2d78d95955ab..d7f97ef26590 100644 --- a/trunk/net/sunrpc/xprtsock.c +++ b/trunk/net/sunrpc/xprtsock.c @@ -2530,10 +2530,8 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, int err; err = xs_init_anyaddr(args->dstaddr->sa_family, (struct sockaddr *)&new->srcaddr); - if (err != 0) { - xprt_free(xprt); + if (err != 0) return ERR_PTR(err); - } } return xprt; diff --git a/trunk/tools/testing/ktest/ktest.pl b/trunk/tools/testing/ktest/ktest.pl index 8b4c2535b266..30e2befd6f2a 100755 --- a/trunk/tools/testing/ktest/ktest.pl +++ b/trunk/tools/testing/ktest/ktest.pl @@ -747,18 +747,6 @@ sub __eval_option { # Add space to evaluate the character before $ $option = " $option"; my $retval = ""; - my $repeated = 0; - my $parent = 0; - - foreach my $test (keys %repeat_tests) { - if ($i >= $test && - $i < $test + $repeat_tests{$test}) { - - $repeated = 1; - $parent = $test; - last; - } - } while ($option =~ /(.*?[^\\])\$\{(.*?)\}(.*)/) { my $start = $1; @@ -772,14 +760,10 @@ sub __eval_option { # otherwise see if the default OPT (without [$i]) exists. my $o = "$var\[$i\]"; - my $parento = "$var\[$parent\]"; if (defined($opt{$o})) { $o = $opt{$o}; $retval = "$retval$o"; - } elsif ($repeated && defined($opt{$parento})) { - $o = $opt{$parento}; - $retval = "$retval$o"; } elsif (defined($opt{$var})) { $o = $opt{$var}; $retval = "$retval$o";