summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libahci.c2
-rw-r--r--drivers/base/platform.c2
-rw-r--r--drivers/connector/connector.c1
-rw-r--r--drivers/crypto/caam/caamalg.c6
-rw-r--r--drivers/firmware/google/Kconfig1
-rw-r--r--drivers/gpu/drm/drm_gem.c1
-rw-r--r--drivers/gpu/drm/i915/i915_debugfs.c16
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c34
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c11
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h35
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c52
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c4
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c81
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h1
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c16
-rw-r--r--drivers/gpu/drm/i915/intel_display.c308
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c12
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c2
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c5
-rw-r--r--drivers/gpu/drm/radeon/nid.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_bios.c2
-rw-r--r--drivers/gpu/drm/radeon/rv770.c6
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c5
-rw-r--r--drivers/hid/hid-core.c1
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-multitouch.c12
-rw-r--r--drivers/hwmon/Kconfig2
-rw-r--r--drivers/hwmon/adm1275.c16
-rw-r--r--drivers/hwmon/emc6w201.c58
-rw-r--r--drivers/hwmon/f71882fg.c19
-rw-r--r--drivers/hwmon/hwmon-vid.c2
-rw-r--r--drivers/hwmon/pmbus.c10
-rw-r--r--drivers/hwmon/pmbus_core.c11
-rw-r--r--drivers/hwmon/sch5627.c2
-rw-r--r--drivers/i2c/busses/i2c-taos-evm.c8
-rw-r--r--drivers/i2c/muxes/pca954x.c7
-rw-r--r--drivers/infiniband/core/cm.c3
-rw-r--r--drivers/infiniband/core/uverbs_main.c3
-rw-r--r--drivers/leds/leds-lp5521.c4
-rw-r--r--drivers/leds/leds-lp5523.c4
-rw-r--r--drivers/md/md.c1
-rw-r--r--drivers/misc/cb710/sgbuf2.c2
-rw-r--r--drivers/misc/ioc4.c2
-rw-r--r--drivers/misc/lkdtm.c8
-rw-r--r--drivers/misc/pti.c11
-rw-r--r--drivers/misc/ti-st/st_core.c2
-rw-r--r--drivers/misc/ti-st/st_kim.c8
-rw-r--r--drivers/mmc/card/block.c5
-rw-r--r--drivers/mmc/card/queue.c15
-rw-r--r--drivers/mmc/card/queue.h3
-rw-r--r--drivers/mmc/core/core.c2
-rw-r--r--drivers/mmc/core/sdio.c39
-rw-r--r--drivers/mmc/core/sdio_bus.c2
-rw-r--r--drivers/mmc/host/of_mmc_spi.c5
-rw-r--r--drivers/mmc/host/omap_hsmmc.c6
-rw-r--r--drivers/mmc/host/sh_mobile_sdhi.c5
-rw-r--r--drivers/mmc/host/tmio_mmc_pio.c4
-rw-r--r--drivers/mmc/host/vub300.c11
-rw-r--r--drivers/mtd/nand/fsl_elbc_nand.c6
-rw-r--r--drivers/net/Kconfig3
-rw-r--r--drivers/net/bnx2x/bnx2x_main.c6
-rw-r--r--drivers/net/can/Kconfig4
-rw-r--r--drivers/net/cxgb3/sge.c4
-rw-r--r--drivers/net/ppp_deflate.c5
-rw-r--r--drivers/net/r8169.c2
-rw-r--r--drivers/net/rionet.c28
-rw-r--r--drivers/net/usb/kalmia.c42
-rw-r--r--drivers/net/usb/zaurus.c10
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c13
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c20
-rw-r--r--drivers/pci/quirks.c2
-rw-r--r--drivers/rtc/rtc-ds1307.c1
-rw-r--r--drivers/rtc/rtc-vt8500.c45
-rw-r--r--drivers/staging/brcm80211/Kconfig2
-rw-r--r--drivers/staging/comedi/Kconfig22
-rw-r--r--drivers/staging/iio/Kconfig2
-rw-r--r--drivers/staging/iio/accel/adis16204.h2
-rw-r--r--drivers/staging/iio/accel/adis16209.h4
-rw-r--r--drivers/staging/iio/gyro/adis16260.h2
-rw-r--r--drivers/staging/iio/imu/adis16400.h2
-rw-r--r--drivers/staging/mei/init.c2
-rw-r--r--drivers/staging/mei/wd.c13
-rw-r--r--drivers/tty/n_gsm.c26
-rw-r--r--drivers/tty/n_tty.c1
-rw-r--r--drivers/tty/serial/8250.c1
-rw-r--r--drivers/tty/serial/8250_pci.c61
-rw-r--r--drivers/tty/serial/amba-pl011.c123
-rw-r--r--drivers/tty/serial/bcm63xx_uart.c18
-rw-r--r--drivers/tty/serial/jsm/jsm_driver.c2
-rw-r--r--drivers/tty/serial/s5pv210.c4
-rw-r--r--drivers/tty/tty_ldisc.c4
-rw-r--r--drivers/usb/core/driver.c11
-rw-r--r--drivers/usb/core/hub.c16
-rw-r--r--drivers/usb/core/message.c15
-rw-r--r--drivers/usb/host/ehci-ath79.c10
-rw-r--r--drivers/usb/host/ehci-hcd.c4
-rw-r--r--drivers/usb/host/isp1760-hcd.c2
-rw-r--r--drivers/usb/host/ohci-hcd.c4
-rw-r--r--drivers/usb/host/r8a66597-hcd.c1
-rw-r--r--drivers/usb/host/xhci-mem.c2
-rw-r--r--drivers/usb/host/xhci-pci.c8
-rw-r--r--drivers/usb/host/xhci-ring.c30
-rw-r--r--drivers/usb/host/xhci.c39
-rw-r--r--drivers/usb/host/xhci.h3
-rw-r--r--drivers/usb/musb/musb_gadget.c6
-rw-r--r--drivers/usb/musb/musb_host.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.c19
-rw-r--r--drivers/usb/serial/ftdi_sio.h3
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h1
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c1
-rw-r--r--drivers/video/amba-clcd.c2
-rw-r--r--drivers/video/fsl-diu-fb.c16
-rw-r--r--drivers/video/geode/gx1fb_core.c14
-rw-r--r--drivers/video/hecubafb.c3
-rw-r--r--drivers/video/sh_mobile_meram.c2
-rw-r--r--drivers/video/sm501fb.c2
-rw-r--r--drivers/video/udlfb.c8
-rw-r--r--drivers/video/vesafb.c1
-rw-r--r--drivers/watchdog/Kconfig3
-rw-r--r--drivers/watchdog/at32ap700x_wdt.c2
-rw-r--r--drivers/watchdog/gef_wdt.c2
-rw-r--r--drivers/watchdog/intel_scu_watchdog.c1
-rw-r--r--drivers/watchdog/mtx-1_wdt.c29
-rw-r--r--drivers/watchdog/wm831x_wdt.c5
124 files changed, 1126 insertions, 522 deletions
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index d38c40fe4ddb..41223c7f0206 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -452,7 +452,7 @@ void ahci_save_initial_config(struct device *dev,
}
if (mask_port_map) {
- dev_printk(KERN_ERR, dev, "masking port_map 0x%x -> 0x%x\n",
+ dev_printk(KERN_WARNING, dev, "masking port_map 0x%x -> 0x%x\n",
port_map,
port_map & mask_port_map);
port_map &= mask_port_map;
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 1c291af637b3..6040717b62bb 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -367,7 +367,7 @@ EXPORT_SYMBOL_GPL(platform_device_unregister);
*
* Returns &struct platform_device pointer on success, or ERR_PTR() on error.
*/
-struct platform_device *__init_or_module platform_device_register_resndata(
+struct platform_device *platform_device_register_resndata(
struct device *parent,
const char *name, int id,
const struct resource *res, unsigned int num,
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index 219d88a0eeae..dde6a0fad408 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -139,6 +139,7 @@ static int cn_call_callback(struct sk_buff *skb)
spin_unlock_bh(&dev->cbdev->queue_lock);
if (cbq != NULL) {
+ err = 0;
cbq->callback(msg, nsp);
kfree_skb(skb);
cn_queue_release_callback(cbq);
diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index d0e65d6ddc77..676d957c22b0 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -238,9 +238,9 @@ static int build_sh_desc_ipsec(struct caam_ctx *ctx)
/* build shared descriptor for this session */
sh_desc = kmalloc(CAAM_CMD_SZ * DESC_AEAD_SHARED_TEXT_LEN +
- keys_fit_inline ?
- ctx->split_key_pad_len + ctx->enckeylen :
- CAAM_PTR_SZ * 2, GFP_DMA | GFP_KERNEL);
+ (keys_fit_inline ?
+ ctx->split_key_pad_len + ctx->enckeylen :
+ CAAM_PTR_SZ * 2), GFP_DMA | GFP_KERNEL);
if (!sh_desc) {
dev_err(jrdev, "could not allocate shared descriptor\n");
return -ENOMEM;
diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig
index 87096b6ca5c9..2f21b0bfe653 100644
--- a/drivers/firmware/google/Kconfig
+++ b/drivers/firmware/google/Kconfig
@@ -13,6 +13,7 @@ menu "Google Firmware Drivers"
config GOOGLE_SMI
tristate "SMI interface for Google platforms"
depends on ACPI && DMI
+ select EFI
select EFI_VARS
help
Say Y here if you want to enable SMI callbacks for Google
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 74e4ff578017..4012fe423460 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -34,6 +34,7 @@
#include <linux/module.h>
#include <linux/mman.h>
#include <linux/pagemap.h>
+#include <linux/shmem_fs.h>
#include "drmP.h"
/** @file drm_gem.c
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 4d46441cbe2d..0a893f7400fa 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1207,13 +1207,17 @@ static int i915_context_status(struct seq_file *m, void *unused)
if (ret)
return ret;
- seq_printf(m, "power context ");
- describe_obj(m, dev_priv->pwrctx);
- seq_printf(m, "\n");
+ if (dev_priv->pwrctx) {
+ seq_printf(m, "power context ");
+ describe_obj(m, dev_priv->pwrctx);
+ seq_printf(m, "\n");
+ }
- seq_printf(m, "render context ");
- describe_obj(m, dev_priv->renderctx);
- seq_printf(m, "\n");
+ if (dev_priv->renderctx) {
+ seq_printf(m, "render context ");
+ describe_obj(m, dev_priv->renderctx);
+ seq_printf(m, "\n");
+ }
mutex_unlock(&dev->mode_config.mutex);
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 0239e9974bf2..e1787022d6c8 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1266,30 +1266,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
intel_modeset_gem_init(dev);
- if (IS_IVYBRIDGE(dev)) {
- /* Share pre & uninstall handlers with ILK/SNB */
- dev->driver->irq_handler = ivybridge_irq_handler;
- dev->driver->irq_preinstall = ironlake_irq_preinstall;
- dev->driver->irq_postinstall = ivybridge_irq_postinstall;
- dev->driver->irq_uninstall = ironlake_irq_uninstall;
- dev->driver->enable_vblank = ivybridge_enable_vblank;
- dev->driver->disable_vblank = ivybridge_disable_vblank;
- } else if (HAS_PCH_SPLIT(dev)) {
- dev->driver->irq_handler = ironlake_irq_handler;
- dev->driver->irq_preinstall = ironlake_irq_preinstall;
- dev->driver->irq_postinstall = ironlake_irq_postinstall;
- dev->driver->irq_uninstall = ironlake_irq_uninstall;
- dev->driver->enable_vblank = ironlake_enable_vblank;
- dev->driver->disable_vblank = ironlake_disable_vblank;
- } else {
- dev->driver->irq_preinstall = i915_driver_irq_preinstall;
- dev->driver->irq_postinstall = i915_driver_irq_postinstall;
- dev->driver->irq_uninstall = i915_driver_irq_uninstall;
- dev->driver->irq_handler = i915_driver_irq_handler;
- dev->driver->enable_vblank = i915_enable_vblank;
- dev->driver->disable_vblank = i915_disable_vblank;
- }
-
ret = drm_irq_install(dev);
if (ret)
goto cleanup_gem;
@@ -2017,12 +1993,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
/* enable GEM by default */
dev_priv->has_gem = 1;
- dev->driver->get_vblank_counter = i915_get_vblank_counter;
- dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
- if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) {
- dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
- dev->driver->get_vblank_counter = gm45_get_vblank_counter;
- }
+ intel_irq_init(dev);
/* Try to make sure MCHBAR is enabled before poking at it */
intel_setup_mchbar(dev);
@@ -2182,9 +2153,8 @@ int i915_driver_unload(struct drm_device *dev)
/* Flush any outstanding unpin_work. */
flush_workqueue(dev_priv->wq);
- i915_gem_free_all_phys_object(dev);
-
mutex_lock(&dev->struct_mutex);
+ i915_gem_free_all_phys_object(dev);
i915_gem_cleanup_ringbuffer(dev);
mutex_unlock(&dev->struct_mutex);
if (I915_HAS_FBC(dev) && i915_powersave)
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 0defd4270594..013d304455b9 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -579,6 +579,9 @@ int i915_reset(struct drm_device *dev, u8 flags)
} else switch (INTEL_INFO(dev)->gen) {
case 6:
ret = gen6_do_reset(dev, flags);
+ /* If reset with a user forcewake, try to restore */
+ if (atomic_read(&dev_priv->forcewake_count))
+ __gen6_gt_force_wake_get(dev_priv);
break;
case 5:
ret = ironlake_do_reset(dev, flags);
@@ -762,14 +765,6 @@ static struct drm_driver driver = {
.resume = i915_resume,
.device_is_agp = i915_driver_device_is_agp,
- .enable_vblank = i915_enable_vblank,
- .disable_vblank = i915_disable_vblank,
- .get_vblank_timestamp = i915_get_vblank_timestamp,
- .get_scanout_position = i915_get_crtc_scanoutpos,
- .irq_preinstall = i915_driver_irq_preinstall,
- .irq_postinstall = i915_driver_irq_postinstall,
- .irq_uninstall = i915_driver_irq_uninstall,
- .irq_handler = i915_driver_irq_handler,
.reclaim_buffers = drm_core_reclaim_buffers,
.master_create = i915_master_create,
.master_destroy = i915_master_destroy,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index f63ee162f124..f245c588ae95 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -211,6 +211,9 @@ struct drm_i915_display_funcs {
void (*fdi_link_train)(struct drm_crtc *crtc);
void (*init_clock_gating)(struct drm_device *dev);
void (*init_pch_clock_gating)(struct drm_device *dev);
+ int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_i915_gem_object *obj);
/* clock updates for mode set */
/* cursor updates */
/* render clock increase/decrease */
@@ -994,8 +997,6 @@ extern unsigned int i915_enable_fbc;
extern int i915_suspend(struct drm_device *dev, pm_message_t state);
extern int i915_resume(struct drm_device *dev);
-extern void i915_save_display(struct drm_device *dev);
-extern void i915_restore_display(struct drm_device *dev);
extern int i915_master_create(struct drm_device *dev, struct drm_master *master);
extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master);
@@ -1030,33 +1031,12 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
extern int i915_irq_wait(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
-extern void i915_driver_irq_preinstall(struct drm_device * dev);
-extern int i915_driver_irq_postinstall(struct drm_device *dev);
-extern void i915_driver_irq_uninstall(struct drm_device * dev);
-
-extern irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS);
-extern void ironlake_irq_preinstall(struct drm_device *dev);
-extern int ironlake_irq_postinstall(struct drm_device *dev);
-extern void ironlake_irq_uninstall(struct drm_device *dev);
-
-extern irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS);
-extern void ivybridge_irq_preinstall(struct drm_device *dev);
-extern int ivybridge_irq_postinstall(struct drm_device *dev);
-extern void ivybridge_irq_uninstall(struct drm_device *dev);
+extern void intel_irq_init(struct drm_device *dev);
extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-extern int i915_enable_vblank(struct drm_device *dev, int crtc);
-extern void i915_disable_vblank(struct drm_device *dev, int crtc);
-extern int ironlake_enable_vblank(struct drm_device *dev, int crtc);
-extern void ironlake_disable_vblank(struct drm_device *dev, int crtc);
-extern int ivybridge_enable_vblank(struct drm_device *dev, int crtc);
-extern void ivybridge_disable_vblank(struct drm_device *dev, int crtc);
-extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
-extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc);
extern int i915_vblank_swap(struct drm_device *dev, void *data,
struct drm_file *file_priv);
@@ -1067,13 +1047,6 @@ void
i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
void intel_enable_asle (struct drm_device *dev);
-int i915_get_vblank_timestamp(struct drm_device *dev, int crtc,
- int *max_error,
- struct timeval *vblank_time,
- unsigned flags);
-
-int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
- int *vpos, int *hpos);
#ifdef CONFIG_DEBUG_FS
extern void i915_destroy_error_state(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 94c84d744100..5c0d1247f453 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -31,6 +31,7 @@
#include "i915_drv.h"
#include "i915_trace.h"
#include "intel_drv.h"
+#include <linux/shmem_fs.h>
#include <linux/slab.h>
#include <linux/swap.h>
#include <linux/pci.h>
@@ -359,8 +360,7 @@ i915_gem_shmem_pread_fast(struct drm_device *dev,
if ((page_offset + remain) > PAGE_SIZE)
page_length = PAGE_SIZE - page_offset;
- page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT,
- GFP_HIGHUSER | __GFP_RECLAIMABLE);
+ page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
if (IS_ERR(page))
return PTR_ERR(page);
@@ -463,8 +463,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev,
if ((data_page_offset + page_length) > PAGE_SIZE)
page_length = PAGE_SIZE - data_page_offset;
- page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT,
- GFP_HIGHUSER | __GFP_RECLAIMABLE);
+ page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
if (IS_ERR(page)) {
ret = PTR_ERR(page);
goto out;
@@ -797,8 +796,7 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev,
if ((page_offset + remain) > PAGE_SIZE)
page_length = PAGE_SIZE - page_offset;
- page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT,
- GFP_HIGHUSER | __GFP_RECLAIMABLE);
+ page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
if (IS_ERR(page))
return PTR_ERR(page);
@@ -907,8 +905,7 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev,
if ((data_page_offset + page_length) > PAGE_SIZE)
page_length = PAGE_SIZE - data_page_offset;
- page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT,
- GFP_HIGHUSER | __GFP_RECLAIMABLE);
+ page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
if (IS_ERR(page)) {
ret = PTR_ERR(page);
goto out;
@@ -1219,11 +1216,11 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
ret = i915_gem_object_bind_to_gtt(obj, 0, true);
if (ret)
goto unlock;
- }
- ret = i915_gem_object_set_to_gtt_domain(obj, write);
- if (ret)
- goto unlock;
+ ret = i915_gem_object_set_to_gtt_domain(obj, write);
+ if (ret)
+ goto unlock;
+ }
if (obj->tiling_mode == I915_TILING_NONE)
ret = i915_gem_object_put_fence(obj);
@@ -1558,12 +1555,10 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj,
inode = obj->base.filp->f_path.dentry->d_inode;
mapping = inode->i_mapping;
+ gfpmask |= mapping_gfp_mask(mapping);
+
for (i = 0; i < page_count; i++) {
- page = read_cache_page_gfp(mapping, i,
- GFP_HIGHUSER |
- __GFP_COLD |
- __GFP_RECLAIMABLE |
- gfpmask);
+ page = shmem_read_mapping_page_gfp(mapping, i, gfpmask);
if (IS_ERR(page))
goto err_pages;
@@ -1701,13 +1696,10 @@ i915_gem_object_truncate(struct drm_i915_gem_object *obj)
/* Our goal here is to return as much of the memory as
* is possible back to the system as we are called from OOM.
* To do this we must instruct the shmfs to drop all of its
- * backing pages, *now*. Here we mirror the actions taken
- * when by shmem_delete_inode() to release the backing store.
+ * backing pages, *now*.
*/
inode = obj->base.filp->f_path.dentry->d_inode;
- truncate_inode_pages(inode->i_mapping, 0);
- if (inode->i_op->truncate_range)
- inode->i_op->truncate_range(inode, 0, (loff_t)-1);
+ shmem_truncate_range(inode, 0, (loff_t)-1);
obj->madv = __I915_MADV_PURGED;
}
@@ -2080,8 +2072,8 @@ i915_wait_request(struct intel_ring_buffer *ring,
if (!ier) {
DRM_ERROR("something (likely vbetool) disabled "
"interrupts, re-enabling\n");
- i915_driver_irq_preinstall(ring->dev);
- i915_driver_irq_postinstall(ring->dev);
+ ring->dev->driver->irq_preinstall(ring->dev);
+ ring->dev->driver->irq_postinstall(ring->dev);
}
trace_i915_gem_request_wait_begin(ring, seqno);
@@ -2926,8 +2918,6 @@ i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj)
*/
wmb();
- i915_gem_release_mmap(obj);
-
old_write_domain = obj->base.write_domain;
obj->base.write_domain = 0;
@@ -3567,6 +3557,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj;
+ struct address_space *mapping;
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
if (obj == NULL)
@@ -3577,6 +3568,9 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
return NULL;
}
+ mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
+ mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE);
+
i915_gem_info_add_obj(dev_priv, size);
obj->base.write_domain = I915_GEM_DOMAIN_CPU;
@@ -3952,8 +3946,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev,
page_count = obj->base.size / PAGE_SIZE;
for (i = 0; i < page_count; i++) {
- struct page *page = read_cache_page_gfp(mapping, i,
- GFP_HIGHUSER | __GFP_RECLAIMABLE);
+ struct page *page = shmem_read_mapping_page(mapping, i);
if (!IS_ERR(page)) {
char *dst = kmap_atomic(page);
memcpy(dst, vaddr + i*PAGE_SIZE, PAGE_SIZE);
@@ -4014,8 +4007,7 @@ i915_gem_attach_phys_object(struct drm_device *dev,
struct page *page;
char *dst, *src;
- page = read_cache_page_gfp(mapping, i,
- GFP_HIGHUSER | __GFP_RECLAIMABLE);
+ page = shmem_read_mapping_page(mapping, i);
if (IS_ERR(page))
return PTR_ERR(page);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 20a4cc5b818f..4934cf84c320 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -187,10 +187,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj,
if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU)
i915_gem_clflush_object(obj);
- /* blow away mappings if mapped through GTT */
- if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_GTT)
- i915_gem_release_mmap(obj);
-
if (obj->base.pending_write_domain)
cd->flips |= atomic_read(&obj->pending_flip);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 9e34a1abeb61..3b03f85ea627 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -152,7 +152,7 @@ i915_pipe_enabled(struct drm_device *dev, int pipe)
/* Called from drm generic code, passed a 'crtc', which
* we use as a pipe index
*/
-u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
+static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long high_frame;
@@ -184,7 +184,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
return (high1 << 8) | low;
}
-u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
+static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int reg = PIPE_FRMCOUNT_GM45(pipe);
@@ -198,7 +198,7 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
return I915_READ(reg);
}
-int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
+static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
int *vpos, int *hpos)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -264,7 +264,7 @@ int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
return ret;
}
-int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
+static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
int *max_error,
struct timeval *vblank_time,
unsigned flags)
@@ -462,7 +462,7 @@ static void pch_irq_handler(struct drm_device *dev)
DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n");
}
-irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
+static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -550,7 +550,7 @@ done:
return ret;
}
-irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
+static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -1209,7 +1209,7 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe)
}
}
-irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
+static irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -1454,7 +1454,7 @@ int i915_irq_wait(struct drm_device *dev, void *data,
/* Called from drm generic code, passed 'crtc' which
* we use as a pipe index
*/
-int i915_enable_vblank(struct drm_device *dev, int pipe)
+static int i915_enable_vblank(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
@@ -1478,7 +1478,7 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
return 0;
}
-int ironlake_enable_vblank(struct drm_device *dev, int pipe)
+static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
@@ -1494,7 +1494,7 @@ int ironlake_enable_vblank(struct drm_device *dev, int pipe)
return 0;
}
-int ivybridge_enable_vblank(struct drm_device *dev, int pipe)
+static int ivybridge_enable_vblank(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
@@ -1513,7 +1513,7 @@ int ivybridge_enable_vblank(struct drm_device *dev, int pipe)
/* Called from drm generic code, passed 'crtc' which
* we use as a pipe index
*/
-void i915_disable_vblank(struct drm_device *dev, int pipe)
+static void i915_disable_vblank(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
@@ -1529,7 +1529,7 @@ void i915_disable_vblank(struct drm_device *dev, int pipe)
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
}
-void ironlake_disable_vblank(struct drm_device *dev, int pipe)
+static void ironlake_disable_vblank(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
@@ -1540,7 +1540,7 @@ void ironlake_disable_vblank(struct drm_device *dev, int pipe)
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
}
-void ivybridge_disable_vblank(struct drm_device *dev, int pipe)
+static void ivybridge_disable_vblank(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long irqflags;
@@ -1728,7 +1728,7 @@ repeat:
/* drm_dma.h hooks
*/
-void ironlake_irq_preinstall(struct drm_device *dev)
+static void ironlake_irq_preinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -1740,7 +1740,7 @@ void ironlake_irq_preinstall(struct drm_device *dev)
INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
I915_WRITE(HWSTAM, 0xeffe);
- if (IS_GEN6(dev)) {
+ if (IS_GEN6(dev) || IS_GEN7(dev)) {
/* Workaround stalls observed on Sandy Bridge GPUs by
* making the blitter command streamer generate a
* write to the Hardware Status Page for
@@ -1749,6 +1749,7 @@ void ironlake_irq_preinstall(struct drm_device *dev)
* happens.
*/
I915_WRITE(GEN6_BLITTER_HWSTAM, ~GEN6_BLITTER_USER_INTERRUPT);
+ I915_WRITE(GEN6_BSD_HWSTAM, ~GEN6_BSD_USER_INTERRUPT);
}
/* XXX hotplug from PCH */
@@ -1768,7 +1769,7 @@ void ironlake_irq_preinstall(struct drm_device *dev)
POSTING_READ(SDEIER);
}
-int ironlake_irq_postinstall(struct drm_device *dev)
+static int ironlake_irq_postinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
/* enable kind of interrupts always enabled */
@@ -1840,7 +1841,7 @@ int ironlake_irq_postinstall(struct drm_device *dev)
return 0;
}
-int ivybridge_irq_postinstall(struct drm_device *dev)
+static int ivybridge_irq_postinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
/* enable kind of interrupts always enabled */
@@ -1890,7 +1891,7 @@ int ivybridge_irq_postinstall(struct drm_device *dev)
return 0;
}
-void i915_driver_irq_preinstall(struct drm_device * dev)
+static void i915_driver_irq_preinstall(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int pipe;
@@ -1917,7 +1918,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
* Must be called after intel_modeset_init or hotplug interrupts won't be
* enabled correctly.
*/
-int i915_driver_irq_postinstall(struct drm_device *dev)
+static int i915_driver_irq_postinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
@@ -1993,7 +1994,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
return 0;
}
-void ironlake_irq_uninstall(struct drm_device *dev)
+static void ironlake_irq_uninstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -2013,7 +2014,7 @@ void ironlake_irq_uninstall(struct drm_device *dev)
I915_WRITE(GTIIR, I915_READ(GTIIR));
}
-void i915_driver_irq_uninstall(struct drm_device * dev)
+static void i915_driver_irq_uninstall(struct drm_device * dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int pipe;
@@ -2039,3 +2040,41 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
I915_READ(PIPESTAT(pipe)) & 0x8000ffff);
I915_WRITE(IIR, I915_READ(IIR));
}
+
+void intel_irq_init(struct drm_device *dev)
+{
+ dev->driver->get_vblank_counter = i915_get_vblank_counter;
+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
+ if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) {
+ dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
+ dev->driver->get_vblank_counter = gm45_get_vblank_counter;
+ }
+
+
+ dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
+ dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
+
+ if (IS_IVYBRIDGE(dev)) {
+ /* Share pre & uninstall handlers with ILK/SNB */
+ dev->driver->irq_handler = ivybridge_irq_handler;
+ dev->driver->irq_preinstall = ironlake_irq_preinstall;
+ dev->driver->irq_postinstall = ivybridge_irq_postinstall;
+ dev->driver->irq_uninstall = ironlake_irq_uninstall;
+ dev->driver->enable_vblank = ivybridge_enable_vblank;
+ dev->driver->disable_vblank = ivybridge_disable_vblank;
+ } else if (HAS_PCH_SPLIT(dev)) {
+ dev->driver->irq_handler = ironlake_irq_handler;
+ dev->driver->irq_preinstall = ironlake_irq_preinstall;
+ dev->driver->irq_postinstall = ironlake_irq_postinstall;
+ dev->driver->irq_uninstall = ironlake_irq_uninstall;
+ dev->driver->enable_vblank = ironlake_enable_vblank;
+ dev->driver->disable_vblank = ironlake_disable_vblank;
+ } else {
+ dev->driver->irq_preinstall = i915_driver_irq_preinstall;
+ dev->driver->irq_postinstall = i915_driver_irq_postinstall;
+ dev->driver->irq_uninstall = i915_driver_irq_uninstall;
+ dev->driver->irq_handler = i915_driver_irq_handler;
+ dev->driver->enable_vblank = i915_enable_vblank;
+ dev->driver->disable_vblank = i915_disable_vblank;
+ }
+}
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 2f967af8e62e..5d5def756c9e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -531,6 +531,7 @@
#define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE 0
#define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3)
+#define GEN6_BSD_HWSTAM 0x12098
#define GEN6_BSD_IMR 0x120a8
#define GEN6_BSD_USER_INTERRUPT (1 << 12)
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 60a94d2b5264..5257cfc34c35 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -597,7 +597,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev)
return;
}
-void i915_save_display(struct drm_device *dev)
+static void i915_save_display(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -689,7 +689,7 @@ void i915_save_display(struct drm_device *dev)
i915_save_vga(dev);
}
-void i915_restore_display(struct drm_device *dev)
+static void i915_restore_display(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -780,6 +780,7 @@ void i915_restore_display(struct drm_device *dev)
I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL);
else
I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
+
I915_WRITE(VGA0, dev_priv->saveVGA0);
I915_WRITE(VGA1, dev_priv->saveVGA1);
I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
@@ -796,6 +797,8 @@ int i915_save_state(struct drm_device *dev)
pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
+ mutex_lock(&dev->struct_mutex);
+
/* Hardware status page */
dev_priv->saveHWS = I915_READ(HWS_PGA);
@@ -835,6 +838,8 @@ int i915_save_state(struct drm_device *dev)
for (i = 0; i < 3; i++)
dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
+ mutex_unlock(&dev->struct_mutex);
+
return 0;
}
@@ -845,6 +850,8 @@ int i915_restore_state(struct drm_device *dev)
pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
+ mutex_lock(&dev->struct_mutex);
+
/* Hardware status page */
I915_WRITE(HWS_PGA, dev_priv->saveHWS);
@@ -862,6 +869,7 @@ int i915_restore_state(struct drm_device *dev)
I915_WRITE(IER, dev_priv->saveIER);
I915_WRITE(IMR, dev_priv->saveIMR);
}
+ mutex_unlock(&dev->struct_mutex);
intel_init_clock_gating(dev);
@@ -873,6 +881,8 @@ int i915_restore_state(struct drm_device *dev)
if (IS_GEN6(dev))
gen6_enable_rps(dev_priv);
+ mutex_lock(&dev->struct_mutex);
+
/* Cache mode state */
I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
@@ -886,6 +896,8 @@ int i915_restore_state(struct drm_device *dev)
for (i = 0; i < 3; i++)
I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
+ mutex_unlock(&dev->struct_mutex);
+
intel_i2c_reset(dev);
return 0;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 81a9059b6a94..21b6f93fe919 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4687,6 +4687,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(DSPCNTR(plane), dspcntr);
POSTING_READ(DSPCNTR(plane));
+ intel_enable_plane(dev_priv, plane, pipe);
ret = intel_pipe_set_base(crtc, x, y, old_fb);
@@ -5217,8 +5218,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(DSPCNTR(plane), dspcntr);
POSTING_READ(DSPCNTR(plane));
- if (!HAS_PCH_SPLIT(dev))
- intel_enable_plane(dev_priv, plane, pipe);
ret = intel_pipe_set_base(crtc, x, y, old_fb);
@@ -6262,6 +6261,197 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane)
spin_unlock_irqrestore(&dev->event_lock, flags);
}
+static int intel_gen2_queue_flip(struct drm_device *dev,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_i915_gem_object *obj)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ unsigned long offset;
+ u32 flip_mask;
+ int ret;
+
+ ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
+ if (ret)
+ goto out;
+
+ /* Offset into the new buffer for cases of shared fbs between CRTCs */
+ offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;
+
+ ret = BEGIN_LP_RING(6);
+ if (ret)
+ goto out;
+
+ /* Can't queue multiple flips, so wait for the previous
+ * one to finish before executing the next.
+ */
+ if (intel_crtc->plane)
+ flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
+ else
+ flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
+ OUT_RING(MI_WAIT_FOR_EVENT | flip_mask);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_DISPLAY_FLIP |
+ MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+ OUT_RING(fb->pitch);
+ OUT_RING(obj->gtt_offset + offset);
+ OUT_RING(MI_NOOP);
+ ADVANCE_LP_RING();
+out:
+ return ret;
+}
+
+static int intel_gen3_queue_flip(struct drm_device *dev,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_i915_gem_object *obj)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ unsigned long offset;
+ u32 flip_mask;
+ int ret;
+
+ ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
+ if (ret)
+ goto out;
+
+ /* Offset into the new buffer for cases of shared fbs between CRTCs */
+ offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;
+
+ ret = BEGIN_LP_RING(6);
+ if (ret)
+ goto out;
+
+ if (intel_crtc->plane)
+ flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
+ else
+ flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
+ OUT_RING(MI_WAIT_FOR_EVENT | flip_mask);
+ OUT_RING(MI_NOOP);
+ OUT_RING(MI_DISPLAY_FLIP_I915 |
+ MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+ OUT_RING(fb->pitch);
+ OUT_RING(obj->gtt_offset + offset);
+ OUT_RING(MI_NOOP);
+
+ ADVANCE_LP_RING();
+out:
+ return ret;
+}
+
+static int intel_gen4_queue_flip(struct drm_device *dev,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_i915_gem_object *obj)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ uint32_t pf, pipesrc;
+ int ret;
+
+ ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
+ if (ret)
+ goto out;
+
+ ret = BEGIN_LP_RING(4);
+ if (ret)
+ goto out;
+
+ /* i965+ uses the linear or tiled offsets from the
+ * Display Registers (which do not change across a page-flip)
+ * so we need only reprogram the base address.
+ */
+ OUT_RING(MI_DISPLAY_FLIP |
+ MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+ OUT_RING(fb->pitch);
+ OUT_RING(obj->gtt_offset | obj->tiling_mode);
+
+ /* XXX Enabling the panel-fitter across page-flip is so far
+ * untested on non-native modes, so ignore it for now.
+ * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
+ */
+ pf = 0;
+ pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
+ OUT_RING(pf | pipesrc);
+ ADVANCE_LP_RING();
+out:
+ return ret;
+}
+
+static int intel_gen6_queue_flip(struct drm_device *dev,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_i915_gem_object *obj)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ uint32_t pf, pipesrc;
+ int ret;
+
+ ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
+ if (ret)
+ goto out;
+
+ ret = BEGIN_LP_RING(4);
+ if (ret)
+ goto out;
+
+ OUT_RING(MI_DISPLAY_FLIP |
+ MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+ OUT_RING(fb->pitch | obj->tiling_mode);
+ OUT_RING(obj->gtt_offset);
+
+ pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
+ pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
+ OUT_RING(pf | pipesrc);
+ ADVANCE_LP_RING();
+out:
+ return ret;
+}
+
+/*
+ * On gen7 we currently use the blit ring because (in early silicon at least)
+ * the render ring doesn't give us interrpts for page flip completion, which
+ * means clients will hang after the first flip is queued. Fortunately the
+ * blit ring generates interrupts properly, so use it instead.
+ */
+static int intel_gen7_queue_flip(struct drm_device *dev,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_i915_gem_object *obj)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ struct intel_ring_buffer *ring = &dev_priv->ring[BCS];
+ int ret;
+
+ ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
+ if (ret)
+ goto out;
+
+ ret = intel_ring_begin(ring, 4);
+ if (ret)
+ goto out;
+
+ intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19));
+ intel_ring_emit(ring, (fb->pitch | obj->tiling_mode));
+ intel_ring_emit(ring, (obj->gtt_offset));
+ intel_ring_emit(ring, (MI_NOOP));
+ intel_ring_advance(ring);
+out:
+ return ret;
+}
+
+static int intel_default_queue_flip(struct drm_device *dev,
+ struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_i915_gem_object *obj)
+{
+ return -ENODEV;
+}
+
static int intel_crtc_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event)
@@ -6272,9 +6462,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
struct drm_i915_gem_object *obj;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_unpin_work *work;
- unsigned long flags, offset;
- int pipe = intel_crtc->pipe;
- u32 pf, pipesrc;
+ unsigned long flags;
int ret;
work = kzalloc(sizeof *work, GFP_KERNEL);
@@ -6303,9 +6491,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
obj = intel_fb->obj;
mutex_lock(&dev->struct_mutex);
- ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
- if (ret)
- goto cleanup_work;
/* Reference the objects for the scheduled work. */
drm_gem_object_reference(&work->old_fb_obj->base);
@@ -6317,91 +6502,18 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
if (ret)
goto cleanup_objs;
- if (IS_GEN3(dev) || IS_GEN2(dev)) {
- u32 flip_mask;
-
- /* Can't queue multiple flips, so wait for the previous
- * one to finish before executing the next.
- */
- ret = BEGIN_LP_RING(2);
- if (ret)
- goto cleanup_objs;
-
- if (intel_crtc->plane)
- flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
- else
- flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
- OUT_RING(MI_WAIT_FOR_EVENT | flip_mask);
- OUT_RING(MI_NOOP);
- ADVANCE_LP_RING();
- }
-
work->pending_flip_obj = obj;
work->enable_stall_check = true;
- /* Offset into the new buffer for cases of shared fbs between CRTCs */
- offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;
-
- ret = BEGIN_LP_RING(4);
- if (ret)
- goto cleanup_objs;
-
/* Block clients from rendering to the new back buffer until
* the flip occurs and the object is no longer visible.
*/
atomic_add(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
- switch (INTEL_INFO(dev)->gen) {
- case 2:
- OUT_RING(MI_DISPLAY_FLIP |
- MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
- OUT_RING(fb->pitch);
- OUT_RING(obj->gtt_offset + offset);
- OUT_RING(MI_NOOP);
- break;
-
- case 3:
- OUT_RING(MI_DISPLAY_FLIP_I915 |
- MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
- OUT_RING(fb->pitch);
- OUT_RING(obj->gtt_offset + offset);
- OUT_RING(MI_NOOP);
- break;
-
- case 4:
- case 5:
- /* i965+ uses the linear or tiled offsets from the
- * Display Registers (which do not change across a page-flip)
- * so we need only reprogram the base address.
- */
- OUT_RING(MI_DISPLAY_FLIP |
- MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
- OUT_RING(fb->pitch);
- OUT_RING(obj->gtt_offset | obj->tiling_mode);
-
- /* XXX Enabling the panel-fitter across page-flip is so far
- * untested on non-native modes, so ignore it for now.
- * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
- */
- pf = 0;
- pipesrc = I915_READ(PIPESRC(pipe)) & 0x0fff0fff;
- OUT_RING(pf | pipesrc);
- break;
-
- case 6:
- case 7:
- OUT_RING(MI_DISPLAY_FLIP |
- MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
- OUT_RING(fb->pitch | obj->tiling_mode);
- OUT_RING(obj->gtt_offset);
-
- pf = I915_READ(PF_CTL(pipe)) & PF_ENABLE;
- pipesrc = I915_READ(PIPESRC(pipe)) & 0x0fff0fff;
- OUT_RING(pf | pipesrc);
- break;
- }
- ADVANCE_LP_RING();
+ ret = dev_priv->display.queue_flip(dev, crtc, fb, obj);
+ if (ret)
+ goto cleanup_pending;
mutex_unlock(&dev->struct_mutex);
@@ -6409,10 +6521,11 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
return 0;
+cleanup_pending:
+ atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
cleanup_objs:
drm_gem_object_unreference(&work->old_fb_obj->base);
drm_gem_object_unreference(&obj->base);
-cleanup_work:
mutex_unlock(&dev->struct_mutex);
spin_lock_irqsave(&dev->event_lock, flags);
@@ -7657,6 +7770,31 @@ static void intel_init_display(struct drm_device *dev)
else
dev_priv->display.get_fifo_size = i830_get_fifo_size;
}
+
+ /* Default just returns -ENODEV to indicate unsupported */
+ dev_priv->display.queue_flip = intel_default_queue_flip;
+
+ switch (INTEL_INFO(dev)->gen) {
+ case 2:
+ dev_priv->display.queue_flip = intel_gen2_queue_flip;
+ break;
+
+ case 3:
+ dev_priv->display.queue_flip = intel_gen3_queue_flip;
+ break;
+
+ case 4:
+ case 5:
+ dev_priv->display.queue_flip = intel_gen4_queue_flip;
+ break;
+
+ case 6:
+ dev_priv->display.queue_flip = intel_gen6_queue_flip;
+ break;
+ case 7:
+ dev_priv->display.queue_flip = intel_gen7_queue_flip;
+ break;
+ }
}
/*
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index a670c006982e..9e2959bc91cd 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -1409,6 +1409,11 @@ void intel_setup_overlay(struct drm_device *dev)
overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
if (!overlay)
return;
+
+ mutex_lock(&dev->struct_mutex);
+ if (WARN_ON(dev_priv->overlay))
+ goto out_free;
+
overlay->dev = dev;
reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
@@ -1448,7 +1453,7 @@ void intel_setup_overlay(struct drm_device *dev)
regs = intel_overlay_map_regs(overlay);
if (!regs)
- goto out_free_bo;
+ goto out_unpin_bo;
memset(regs, 0, sizeof(struct overlay_registers));
update_polyphase_filter(regs);
@@ -1457,14 +1462,17 @@ void intel_setup_overlay(struct drm_device *dev)
intel_overlay_unmap_regs(overlay, regs);
dev_priv->overlay = overlay;
+ mutex_unlock(&dev->struct_mutex);
DRM_INFO("initialized overlay support\n");
return;
out_unpin_bo:
- i915_gem_object_unpin(reg_bo);
+ if (!OVERLAY_NEEDS_PHYSICAL(dev))
+ i915_gem_object_unpin(reg_bo);
out_free_bo:
drm_gem_object_unreference(&reg_bo->base);
out_free:
+ mutex_unlock(&dev->struct_mutex);
kfree(overlay);
return;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 144f79a350ae..731acea865b5 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -371,7 +371,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->vram.flags_valid = nv50_vram_flags_valid;
break;
case 0xC0:
- case 0xD0:
engine->instmem.init = nvc0_instmem_init;
engine->instmem.takedown = nvc0_instmem_takedown;
engine->instmem.suspend = nvc0_instmem_suspend;
@@ -923,7 +922,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
dev_priv->card_type = NV_50;
break;
case 0xc0:
- case 0xd0:
dev_priv->card_type = NV_C0;
break;
default:
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 12d2fdc52414..e8a5ffb0124d 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2248,7 +2248,10 @@ int evergreen_mc_init(struct radeon_device *rdev)
/* Get VRAM informations */
rdev->mc.vram_is_ddr = true;
- tmp = RREG32(MC_ARB_RAMCFG);
+ if (rdev->flags & RADEON_IS_IGP)
+ tmp = RREG32(FUS_MC_ARB_RAMCFG);
+ else
+ tmp = RREG32(MC_ARB_RAMCFG);
if (tmp & CHANSIZE_OVERRIDE) {
chansize = 16;
} else if (tmp & CHANSIZE_MASK) {
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
index 9736746da2d6..4672869cdb26 100644
--- a/drivers/gpu/drm/radeon/nid.h
+++ b/drivers/gpu/drm/radeon/nid.h
@@ -320,7 +320,7 @@
#define CGTS_USER_TCC_DISABLE 0x914C
#define TCC_DISABLE_MASK 0xFFFF0000
#define TCC_DISABLE_SHIFT 16
-#define CGTS_SM_CTRL_REG 0x915C
+#define CGTS_SM_CTRL_REG 0x9150
#define OVERRIDE (1 << 21)
#define TA_CNTL_AUX 0x9508
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 1aba85cad1a8..3fc5fa1aefd0 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -104,7 +104,7 @@ static bool radeon_read_bios(struct radeon_device *rdev)
static bool radeon_atrm_get_bios(struct radeon_device *rdev)
{
int ret;
- int size = 64 * 1024;
+ int size = 256 * 1024;
int i;
if (!radeon_atrm_supported(rdev->pdev))
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 6f508ffd1035..8bb347d23ca6 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -575,6 +575,12 @@ static void rv770_program_channel_remap(struct radeon_device *rdev)
else
tcp_chan_steer = 0x00fac688;
+ /* RV770 CE has special chremap setup */
+ if (rdev->pdev->device == 0x944e) {
+ tcp_chan_steer = 0x00b08b08;
+ mc_shared_chremap = 0x00b08b08;
+ }
+
WREG32(TCP_CHAN_STEER, tcp_chan_steer);
WREG32(MC_SHARED_CHREMAP, mc_shared_chremap);
}
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index 90e23e0bfadb..58c271ebc0f7 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -31,6 +31,7 @@
#include <linux/sched.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
+#include <linux/shmem_fs.h>
#include <linux/file.h>
#include <linux/swap.h>
#include <linux/slab.h>
@@ -484,7 +485,7 @@ static int ttm_tt_swapin(struct ttm_tt *ttm)
swap_space = swap_storage->f_path.dentry->d_inode->i_mapping;
for (i = 0; i < ttm->num_pages; ++i) {
- from_page = read_mapping_page(swap_space, i, NULL);
+ from_page = shmem_read_mapping_page(swap_space, i);
if (IS_ERR(from_page)) {
ret = PTR_ERR(from_page);
goto out_err;
@@ -557,7 +558,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage)
from_page = ttm->pages[i];
if (unlikely(from_page == NULL))
continue;
- to_page = read_mapping_page(swap_space, i, NULL);
+ to_page = shmem_read_mapping_page(swap_space, i);
if (unlikely(IS_ERR(to_page))) {
ret = PTR_ERR(to_page);
goto out_err;
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index f7440e8ce3e7..6f3289a57888 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1423,6 +1423,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH_DUAL) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index aecb5a4b8d6d..a756ee6c7df5 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -449,6 +449,7 @@
#define USB_VENDOR_ID_LUMIO 0x202e
#define USB_DEVICE_ID_CRYSTALTOUCH 0x0006
+#define USB_DEVICE_ID_CRYSTALTOUCH_DUAL 0x0007
#define USB_VENDOR_ID_MCC 0x09db
#define USB_DEVICE_ID_MCC_PMD1024LS 0x0076
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 0b2dcd0ee591..62cac4dc3b62 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -271,6 +271,8 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
}
return 1;
case HID_DG_CONTACTID:
+ if (!td->maxcontacts)
+ td->maxcontacts = MT_DEFAULT_MAXCONTACT;
input_mt_init_slots(hi->input, td->maxcontacts);
td->last_slot_field = usage->hid;
td->last_field_index = field->index;
@@ -547,9 +549,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (ret)
goto fail;
- if (!td->maxcontacts)
- td->maxcontacts = MT_DEFAULT_MAXCONTACT;
-
td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),
GFP_KERNEL);
if (!td->slots) {
@@ -677,6 +676,9 @@ static const struct hid_device_id mt_devices[] = {
{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
USB_DEVICE_ID_CRYSTALTOUCH) },
+ { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
+ HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
+ USB_DEVICE_ID_CRYSTALTOUCH_DUAL) },
/* MosArt panels */
{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
@@ -707,10 +709,10 @@ static const struct hid_device_id mt_devices[] = {
HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
USB_DEVICE_ID_MTP)},
{ .driver_data = MT_CLS_CONFIDENCE,
- HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
+ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,
USB_DEVICE_ID_MTP_STM)},
{ .driver_data = MT_CLS_CONFIDENCE,
- HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
+ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX,
USB_DEVICE_ID_MTP_SITRONIX)},
/* Touch International panels */
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 16db83c83c8b..5f888f7e7dcb 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -333,7 +333,7 @@ config SENSORS_F71882FG
F71858FG
F71862FG
F71863FG
- F71869F/E
+ F71869F/E/A
F71882FG
F71883FG
F71889FG/ED/A
diff --git a/drivers/hwmon/adm1275.c b/drivers/hwmon/adm1275.c
index c2ee2048ab91..b9b7caf4a1d2 100644
--- a/drivers/hwmon/adm1275.c
+++ b/drivers/hwmon/adm1275.c
@@ -32,6 +32,7 @@ static int adm1275_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int config;
+ int ret;
struct pmbus_driver_info *info;
if (!i2c_check_functionality(client->adapter,
@@ -43,8 +44,10 @@ static int adm1275_probe(struct i2c_client *client,
return -ENOMEM;
config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG);
- if (config < 0)
- return config;
+ if (config < 0) {
+ ret = config;
+ goto err_mem;
+ }
info->pages = 1;
info->direct[PSC_VOLTAGE_IN] = true;
@@ -76,7 +79,14 @@ static int adm1275_probe(struct i2c_client *client,
else
info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT;
- return pmbus_do_probe(client, id, info);
+ ret = pmbus_do_probe(client, id, info);
+ if (ret)
+ goto err_mem;
+ return 0;
+
+err_mem:
+ kfree(info);
+ return ret;
}
static int adm1275_remove(struct i2c_client *client)
diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c
index e0ef32378ac6..0064432f361f 100644
--- a/drivers/hwmon/emc6w201.c
+++ b/drivers/hwmon/emc6w201.c
@@ -78,8 +78,9 @@ static u16 emc6w201_read16(struct i2c_client *client, u8 reg)
lsb = i2c_smbus_read_byte_data(client, reg);
msb = i2c_smbus_read_byte_data(client, reg + 1);
- if (lsb < 0 || msb < 0) {
- dev_err(&client->dev, "16-bit read failed at 0x%02x\n", reg);
+ if (unlikely(lsb < 0 || msb < 0)) {
+ dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+ 16, "read", reg);
return 0xFFFF; /* Arbitrary value */
}
@@ -95,10 +96,39 @@ static int emc6w201_write16(struct i2c_client *client, u8 reg, u16 val)
int err;
err = i2c_smbus_write_byte_data(client, reg, val & 0xff);
- if (!err)
+ if (likely(!err))
err = i2c_smbus_write_byte_data(client, reg + 1, val >> 8);
- if (err < 0)
- dev_err(&client->dev, "16-bit write failed at 0x%02x\n", reg);
+ if (unlikely(err < 0))
+ dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+ 16, "write", reg);
+
+ return err;
+}
+
+/* Read 8-bit value from register */
+static u8 emc6w201_read8(struct i2c_client *client, u8 reg)
+{
+ int val;
+
+ val = i2c_smbus_read_byte_data(client, reg);
+ if (unlikely(val < 0)) {
+ dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+ 8, "read", reg);
+ return 0x00; /* Arbitrary value */
+ }
+
+ return val;
+}
+
+/* Write 8-bit value to register */
+static int emc6w201_write8(struct i2c_client *client, u8 reg, u8 val)
+{
+ int err;
+
+ err = i2c_smbus_write_byte_data(client, reg, val);
+ if (unlikely(err < 0))
+ dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+ 8, "write", reg);
return err;
}
@@ -114,25 +144,25 @@ static struct emc6w201_data *emc6w201_update_device(struct device *dev)
if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
for (nr = 0; nr < 6; nr++) {
data->in[input][nr] =
- i2c_smbus_read_byte_data(client,
+ emc6w201_read8(client,
EMC6W201_REG_IN(nr));
data->in[min][nr] =
- i2c_smbus_read_byte_data(client,
+ emc6w201_read8(client,
EMC6W201_REG_IN_LOW(nr));
data->in[max][nr] =
- i2c_smbus_read_byte_data(client,
+ emc6w201_read8(client,
EMC6W201_REG_IN_HIGH(nr));
}
for (nr = 0; nr < 6; nr++) {
data->temp[input][nr] =
- i2c_smbus_read_byte_data(client,
+ emc6w201_read8(client,
EMC6W201_REG_TEMP(nr));
data->temp[min][nr] =
- i2c_smbus_read_byte_data(client,
+ emc6w201_read8(client,
EMC6W201_REG_TEMP_LOW(nr));
data->temp[max][nr] =
- i2c_smbus_read_byte_data(client,
+ emc6w201_read8(client,
EMC6W201_REG_TEMP_HIGH(nr));
}
@@ -192,7 +222,7 @@ static ssize_t set_in(struct device *dev, struct device_attribute *devattr,
mutex_lock(&data->update_lock);
data->in[sf][nr] = SENSORS_LIMIT(val, 0, 255);
- err = i2c_smbus_write_byte_data(client, reg, data->in[sf][nr]);
+ err = emc6w201_write8(client, reg, data->in[sf][nr]);
mutex_unlock(&data->update_lock);
return err < 0 ? err : count;
@@ -229,7 +259,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
mutex_lock(&data->update_lock);
data->temp[sf][nr] = SENSORS_LIMIT(val, -127, 128);
- err = i2c_smbus_write_byte_data(client, reg, data->temp[sf][nr]);
+ err = emc6w201_write8(client, reg, data->temp[sf][nr]);
mutex_unlock(&data->update_lock);
return err < 0 ? err : count;
@@ -444,7 +474,7 @@ static int emc6w201_detect(struct i2c_client *client,
/* Check configuration */
config = i2c_smbus_read_byte_data(client, EMC6W201_REG_CONFIG);
- if ((config & 0xF4) != 0x04)
+ if (config < 0 || (config & 0xF4) != 0x04)
return -ENODEV;
if (!(config & 0x01)) {
dev_err(&client->dev, "Monitoring not enabled\n");
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index a4a94a096c90..2d96ed2bf8ed 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -52,6 +52,7 @@
#define SIO_F71858_ID 0x0507 /* Chipset ID */
#define SIO_F71862_ID 0x0601 /* Chipset ID */
#define SIO_F71869_ID 0x0814 /* Chipset ID */
+#define SIO_F71869A_ID 0x1007 /* Chipset ID */
#define SIO_F71882_ID 0x0541 /* Chipset ID */
#define SIO_F71889_ID 0x0723 /* Chipset ID */
#define SIO_F71889E_ID 0x0909 /* Chipset ID */
@@ -108,8 +109,8 @@ static unsigned short force_id;
module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
-enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71882fg, f71889fg,
- f71889ed, f71889a, f8000, f81865f };
+enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71869a, f71882fg,
+ f71889fg, f71889ed, f71889a, f8000, f81865f };
static const char *f71882fg_names[] = {
"f71808e",
@@ -117,6 +118,7 @@ static const char *f71882fg_names[] = {
"f71858fg",
"f71862fg",
"f71869", /* Both f71869f and f71869e, reg. compatible and same id */
+ "f71869a",
"f71882fg",
"f71889fg", /* f81801u too, same id */
"f71889ed",
@@ -131,6 +133,7 @@ static const char f71882fg_has_in[][F71882FG_MAX_INS] = {
[f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
[f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ [f71869a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71882fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71889fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71889ed] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
@@ -145,6 +148,7 @@ static const char f71882fg_has_in1_alarm[] = {
[f71858fg] = 0,
[f71862fg] = 0,
[f71869] = 0,
+ [f71869a] = 0,
[f71882fg] = 1,
[f71889fg] = 1,
[f71889ed] = 1,
@@ -159,6 +163,7 @@ static const char f71882fg_fan_has_beep[] = {
[f71858fg] = 0,
[f71862fg] = 1,
[f71869] = 1,
+ [f71869a] = 1,
[f71882fg] = 1,
[f71889fg] = 1,
[f71889ed] = 1,
@@ -173,6 +178,7 @@ static const char f71882fg_nr_fans[] = {
[f71858fg] = 3,
[f71862fg] = 3,
[f71869] = 3,
+ [f71869a] = 3,
[f71882fg] = 4,
[f71889fg] = 3,
[f71889ed] = 3,
@@ -187,6 +193,7 @@ static const char f71882fg_temp_has_beep[] = {
[f71858fg] = 0,
[f71862fg] = 1,
[f71869] = 1,
+ [f71869a] = 1,
[f71882fg] = 1,
[f71889fg] = 1,
[f71889ed] = 1,
@@ -201,6 +208,7 @@ static const char f71882fg_nr_temps[] = {
[f71858fg] = 3,
[f71862fg] = 3,
[f71869] = 3,
+ [f71869a] = 3,
[f71882fg] = 3,
[f71889fg] = 3,
[f71889ed] = 3,
@@ -2243,6 +2251,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
case f71808e:
case f71808a:
case f71869:
+ case f71869a:
/* These always have signed auto point temps */
data->auto_point_temp_signed = 1;
/* Fall through to select correct fan/pwm reg bank! */
@@ -2305,6 +2314,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
case f71808e:
case f71808a:
case f71869:
+ case f71869a:
case f71889fg:
case f71889ed:
case f71889a:
@@ -2528,6 +2538,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
case SIO_F71869_ID:
sio_data->type = f71869;
break;
+ case SIO_F71869A_ID:
+ sio_data->type = f71869a;
+ break;
case SIO_F71882_ID:
sio_data->type = f71882fg;
break;
@@ -2662,7 +2675,7 @@ static void __exit f71882fg_exit(void)
}
MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
-MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
+MODULE_AUTHOR("Hans Edgington, Hans de Goede <hdegoede@redhat.com>");
MODULE_LICENSE("GPL");
module_init(f71882fg_init);
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index 2582bfef6ccb..c8195a077da3 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -202,7 +202,7 @@ static struct vrm_model vrm_models[] = {
{X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */
{X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */
- {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nemiah */
+ {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nehemiah */
{X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */
{X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */
{X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7, Esther */
diff --git a/drivers/hwmon/pmbus.c b/drivers/hwmon/pmbus.c
index 98e2e28899e2..931d940923ae 100644
--- a/drivers/hwmon/pmbus.c
+++ b/drivers/hwmon/pmbus.c
@@ -47,12 +47,14 @@ static void pmbus_find_sensor_groups(struct i2c_client *client,
if (info->func[0]
&& pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT))
info->func[0] |= PMBUS_HAVE_STATUS_INPUT;
- if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
+ if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) &&
+ pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
info->func[0] |= PMBUS_HAVE_FAN12;
if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12))
info->func[0] |= PMBUS_HAVE_STATUS_FAN12;
}
- if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
+ if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) &&
+ pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
info->func[0] |= PMBUS_HAVE_FAN34;
if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34))
info->func[0] |= PMBUS_HAVE_STATUS_FAN34;
@@ -63,6 +65,10 @@ static void pmbus_find_sensor_groups(struct i2c_client *client,
PMBUS_STATUS_TEMPERATURE))
info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
}
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2))
+ info->func[0] |= PMBUS_HAVE_TEMP2;
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3))
+ info->func[0] |= PMBUS_HAVE_TEMP3;
/* Sensors detected on all pages */
for (page = 0; page < info->pages; page++) {
diff --git a/drivers/hwmon/pmbus_core.c b/drivers/hwmon/pmbus_core.c
index 354770ed3186..744672c1f26d 100644
--- a/drivers/hwmon/pmbus_core.c
+++ b/drivers/hwmon/pmbus_core.c
@@ -1430,14 +1430,9 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
- /*
- * Bail out if status register or PMBus revision register
- * does not exist.
- */
- if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0
- || i2c_smbus_read_byte_data(client, PMBUS_REVISION) < 0) {
- dev_err(&client->dev,
- "Status or revision register not found\n");
+ /* Bail out if PMBus status register does not exist. */
+ if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0) {
+ dev_err(&client->dev, "PMBus status register not found\n");
ret = -ENODEV;
goto out_data;
}
diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c
index 020c87273ea1..3494a4cce414 100644
--- a/drivers/hwmon/sch5627.c
+++ b/drivers/hwmon/sch5627.c
@@ -887,7 +887,7 @@ static void __exit sch5627_exit(void)
}
MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver");
-MODULE_AUTHOR("Hans de Goede (hdegoede@redhat.com)");
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_LICENSE("GPL");
module_init(sch5627_init);
diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c
index dd39c1eb03ed..26c352a09298 100644
--- a/drivers/i2c/busses/i2c-taos-evm.c
+++ b/drivers/i2c/busses/i2c-taos-evm.c
@@ -234,7 +234,7 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv)
if (taos->state != TAOS_STATE_IDLE) {
err = -ENODEV;
- dev_dbg(&serio->dev, "TAOS EVM reset failed (state=%d, "
+ dev_err(&serio->dev, "TAOS EVM reset failed (state=%d, "
"pos=%d)\n", taos->state, taos->pos);
goto exit_close;
}
@@ -255,7 +255,7 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv)
msecs_to_jiffies(250));
if (taos->state != TAOS_STATE_IDLE) {
err = -ENODEV;
- dev_err(&adapter->dev, "Echo off failed "
+ dev_err(&serio->dev, "TAOS EVM echo off failed "
"(state=%d)\n", taos->state);
goto exit_close;
}
@@ -263,7 +263,7 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv)
err = i2c_add_adapter(adapter);
if (err)
goto exit_close;
- dev_dbg(&serio->dev, "Connected to TAOS EVM\n");
+ dev_info(&serio->dev, "Connected to TAOS EVM\n");
taos->client = taos_instantiate_device(adapter);
return 0;
@@ -288,7 +288,7 @@ static void taos_disconnect(struct serio *serio)
serio_set_drvdata(serio, NULL);
kfree(taos);
- dev_dbg(&serio->dev, "Disconnected from TAOS EVM\n");
+ dev_info(&serio->dev, "Disconnected from TAOS EVM\n");
}
static struct serio_device_id taos_serio_ids[] = {
diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c
index 54e1ce73534b..6f8953664636 100644
--- a/drivers/i2c/muxes/pca954x.c
+++ b/drivers/i2c/muxes/pca954x.c
@@ -201,10 +201,11 @@ static int pca954x_probe(struct i2c_client *client,
i2c_set_clientdata(client, data);
- /* Read the mux register at addr to verify
- * that the mux is in fact present.
+ /* Write the mux register at addr to verify
+ * that the mux is in fact present. This also
+ * initializes the mux to disconnected state.
*/
- if (i2c_smbus_read_byte(client) < 0) {
+ if (i2c_smbus_write_byte(client, 0) < 0) {
dev_warn(&client->dev, "probe failed\n");
goto exit_free;
}
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index f62f52fb9ece..fc0f2bd9ca82 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -3641,7 +3641,8 @@ static struct kobj_type cm_port_obj_type = {
static char *cm_devnode(struct device *dev, mode_t *mode)
{
- *mode = 0666;
+ if (mode)
+ *mode = 0666;
return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
}
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index e49a85f8a44d..56898b6578a4 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -826,7 +826,8 @@ static void ib_uverbs_remove_one(struct ib_device *device)
static char *uverbs_devnode(struct device *dev, mode_t *mode)
{
- *mode = 0666;
+ if (mode)
+ *mode = 0666;
return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
}
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c
index c0cff64a1ae6..cc1dc4817fac 100644
--- a/drivers/leds/leds-lp5521.c
+++ b/drivers/leds/leds-lp5521.c
@@ -593,7 +593,7 @@ static void lp5521_unregister_sysfs(struct i2c_client *client)
&lp5521_led_attribute_group);
}
-static int __init lp5521_init_led(struct lp5521_led *led,
+static int __devinit lp5521_init_led(struct lp5521_led *led,
struct i2c_client *client,
int chan, struct lp5521_platform_data *pdata)
{
@@ -637,7 +637,7 @@ static int __init lp5521_init_led(struct lp5521_led *led,
return 0;
}
-static int lp5521_probe(struct i2c_client *client,
+static int __devinit lp5521_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lp5521_chip *chip;
diff --git a/drivers/leds/leds-lp5523.c b/drivers/leds/leds-lp5523.c
index e19fed25f137..5971e309b234 100644
--- a/drivers/leds/leds-lp5523.c
+++ b/drivers/leds/leds-lp5523.c
@@ -826,7 +826,7 @@ static int __init lp5523_init_engine(struct lp5523_engine *engine, int id)
return 0;
}
-static int __init lp5523_init_led(struct lp5523_led *led, struct device *dev,
+static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev,
int chan, struct lp5523_platform_data *pdata)
{
char name[32];
@@ -872,7 +872,7 @@ static int __init lp5523_init_led(struct lp5523_led *led, struct device *dev,
static struct i2c_driver lp5523_driver;
-static int lp5523_probe(struct i2c_client *client,
+static int __devinit lp5523_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct lp5523_chip *chip;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 4332fc2f25d4..91e31e260b4a 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -7088,6 +7088,7 @@ static int remove_and_add_spares(mddev_t *mddev)
list_for_each_entry(rdev, &mddev->disks, same_set) {
if (rdev->raid_disk >= 0 &&
!test_bit(In_sync, &rdev->flags) &&
+ !test_bit(Faulty, &rdev->flags) &&
!test_bit(Blocked, &rdev->flags))
spares++;
if (rdev->raid_disk < 0
diff --git a/drivers/misc/cb710/sgbuf2.c b/drivers/misc/cb710/sgbuf2.c
index d019746551f3..2a40d0efdff5 100644
--- a/drivers/misc/cb710/sgbuf2.c
+++ b/drivers/misc/cb710/sgbuf2.c
@@ -47,7 +47,7 @@ static uint32_t sg_dwiter_read_buffer(struct sg_mapping_iter *miter)
static inline bool needs_unaligned_copy(const void *ptr)
{
-#ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
return false;
#else
return ((ptr - NULL) & 3) != 0;
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c
index 668d41e594a9..df03dd3bd0e2 100644
--- a/drivers/misc/ioc4.c
+++ b/drivers/misc/ioc4.c
@@ -270,7 +270,7 @@ ioc4_variant(struct ioc4_driver_data *idd)
return IOC4_VARIANT_PCI_RT;
}
-static void __devinit
+static void
ioc4_load_modules(struct work_struct *work)
{
request_module("sgiioc4");
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index 81d7fa4ec0db..150cd7061b80 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -120,6 +120,7 @@ static int recur_count = REC_NUM_DEFAULT;
static enum cname cpoint = CN_INVALID;
static enum ctype cptype = CT_NONE;
static int count = DEFAULT_COUNT;
+static DEFINE_SPINLOCK(count_lock);
module_param(recur_count, int, 0644);
MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\
@@ -230,11 +231,14 @@ static const char *cp_name_to_str(enum cname name)
static int lkdtm_parse_commandline(void)
{
int i;
+ unsigned long flags;
if (cpoint_count < 1 || recur_count < 1)
return -EINVAL;
+ spin_lock_irqsave(&count_lock, flags);
count = cpoint_count;
+ spin_unlock_irqrestore(&count_lock, flags);
/* No special parameters */
if (!cpoint_type && !cpoint_name)
@@ -349,6 +353,9 @@ static void lkdtm_do_action(enum ctype which)
static void lkdtm_handler(void)
{
+ unsigned long flags;
+
+ spin_lock_irqsave(&count_lock, flags);
count--;
printk(KERN_INFO "lkdtm: Crash point %s of type %s hit, trigger in %d rounds\n",
cp_name_to_str(cpoint), cp_type_to_str(cptype), count);
@@ -357,6 +364,7 @@ static void lkdtm_handler(void)
lkdtm_do_action(cptype);
count = cpoint_count;
}
+ spin_unlock_irqrestore(&count_lock, flags);
}
static int lkdtm_register_cpoint(enum cname which)
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c
index bb6f9255c17c..374dfcfccd07 100644
--- a/drivers/misc/pti.c
+++ b/drivers/misc/pti.c
@@ -317,7 +317,8 @@ EXPORT_SYMBOL_GPL(pti_request_masterchannel);
* a master, channel ID address
* used to write to PTI HW.
*
- * @mc: master, channel apeture ID address to be released.
+ * @mc: master, channel apeture ID address to be released. This
+ * will de-allocate the structure via kfree().
*/
void pti_release_masterchannel(struct pti_masterchannel *mc)
{
@@ -475,8 +476,10 @@ static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty)
else
pti_tty_data->mc = pti_request_masterchannel(2);
- if (pti_tty_data->mc == NULL)
+ if (pti_tty_data->mc == NULL) {
+ kfree(pti_tty_data);
return -ENXIO;
+ }
tty->driver_data = pti_tty_data;
}
@@ -495,7 +498,7 @@ static void pti_tty_cleanup(struct tty_struct *tty)
if (pti_tty_data == NULL)
return;
pti_release_masterchannel(pti_tty_data->mc);
- kfree(tty->driver_data);
+ kfree(pti_tty_data);
tty->driver_data = NULL;
}
@@ -581,7 +584,7 @@ static int pti_char_open(struct inode *inode, struct file *filp)
static int pti_char_release(struct inode *inode, struct file *filp)
{
pti_release_masterchannel(filp->private_data);
- kfree(filp->private_data);
+ filp->private_data = NULL;
return 0;
}
diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c
index f91f82eabda7..54c91ffe4a91 100644
--- a/drivers/misc/ti-st/st_core.c
+++ b/drivers/misc/ti-st/st_core.c
@@ -605,7 +605,7 @@ long st_unregister(struct st_proto_s *proto)
pr_debug("%s: %d ", __func__, proto->chnl_id);
st_kim_ref(&st_gdata, 0);
- if (proto->chnl_id >= ST_MAX_CHANNELS) {
+ if (!st_gdata || proto->chnl_id >= ST_MAX_CHANNELS) {
pr_err(" chnl_id %d not supported", proto->chnl_id);
return -EPROTONOSUPPORT;
}
diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c
index 5da93ee6f6be..38fd2f04c07e 100644
--- a/drivers/misc/ti-st/st_kim.c
+++ b/drivers/misc/ti-st/st_kim.c
@@ -245,9 +245,9 @@ void skip_change_remote_baud(unsigned char **ptr, long *len)
pr_err("invalid action after change remote baud command");
} else {
*ptr = *ptr + sizeof(struct bts_action) +
- ((struct bts_action *)nxt_action)->size;
+ ((struct bts_action *)cur_action)->size;
*len = *len - (sizeof(struct bts_action) +
- ((struct bts_action *)nxt_action)->size);
+ ((struct bts_action *)cur_action)->size);
/* warn user on not commenting these in firmware */
pr_warn("skipping the wait event of change remote baud");
}
@@ -604,6 +604,10 @@ void st_kim_ref(struct st_data_s **core_data, int id)
struct kim_data_s *kim_gdata;
/* get kim_gdata reference from platform device */
pdev = st_get_plat_device(id);
+ if (!pdev) {
+ *core_data = NULL;
+ return;
+ }
kim_gdata = dev_get_drvdata(&pdev->dev);
*core_data = kim_gdata->core_data;
}
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 71da5641e258..f85e42224559 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1024,7 +1024,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
INIT_LIST_HEAD(&md->part);
md->usage = 1;
- ret = mmc_init_queue(&md->queue, card, &md->lock);
+ ret = mmc_init_queue(&md->queue, card, &md->lock, subname);
if (ret)
goto err_putdisk;
@@ -1297,6 +1297,9 @@ static void mmc_blk_remove(struct mmc_card *card)
struct mmc_blk_data *md = mmc_get_drvdata(card);
mmc_blk_remove_parts(card, md);
+ mmc_claim_host(card->host);
+ mmc_blk_part_switch(card, md);
+ mmc_release_host(card->host);
mmc_blk_remove_req(md);
mmc_set_drvdata(card, NULL);
}
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index c07322c2658c..6413afa318d2 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -106,10 +106,12 @@ static void mmc_request(struct request_queue *q)
* @mq: mmc queue
* @card: mmc card to attach this queue
* @lock: queue lock
+ * @subname: partition subname
*
* Initialise a MMC card request queue.
*/
-int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock)
+int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
+ spinlock_t *lock, const char *subname)
{
struct mmc_host *host = card->host;
u64 limit = BLK_BOUNCE_HIGH;
@@ -133,12 +135,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
mq->queue->limits.max_discard_sectors = UINT_MAX;
if (card->erased_byte == 0)
mq->queue->limits.discard_zeroes_data = 1;
- if (!mmc_can_trim(card) && is_power_of_2(card->erase_size)) {
- mq->queue->limits.discard_granularity =
- card->erase_size << 9;
- mq->queue->limits.discard_alignment =
- card->erase_size << 9;
- }
+ mq->queue->limits.discard_granularity = card->pref_erase << 9;
if (mmc_can_secure_erase_trim(card))
queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD,
mq->queue);
@@ -209,8 +206,8 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
sema_init(&mq->thread_sem, 1);
- mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd/%d",
- host->index);
+ mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd/%d%s",
+ host->index, subname ? subname : "");
if (IS_ERR(mq->thread)) {
ret = PTR_ERR(mq->thread);
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index 64e66e0d4994..6223ef8dc9cd 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -19,7 +19,8 @@ struct mmc_queue {
unsigned int bounce_sg_len;
};
-extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);
+extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *,
+ const char *);
extern void mmc_cleanup_queue(struct mmc_queue *);
extern void mmc_queue_suspend(struct mmc_queue *);
extern void mmc_queue_resume(struct mmc_queue *);
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 68091dda3f31..7843efe22359 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -1245,7 +1245,7 @@ static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
*/
timeout_clks <<= 1;
timeout_us += (timeout_clks * 1000) /
- (card->host->ios.clock / 1000);
+ (mmc_host_clk_rate(card->host) / 1000);
erase_timeout = timeout_us / 1000;
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 4d0c15bfa514..262fff019177 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -691,15 +691,54 @@ static int mmc_sdio_resume(struct mmc_host *host)
static int mmc_sdio_power_restore(struct mmc_host *host)
{
int ret;
+ u32 ocr;
BUG_ON(!host);
BUG_ON(!host->card);
mmc_claim_host(host);
+
+ /*
+ * Reset the card by performing the same steps that are taken by
+ * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe.
+ *
+ * sdio_reset() is technically not needed. Having just powered up the
+ * hardware, it should already be in reset state. However, some
+ * platforms (such as SD8686 on OLPC) do not instantly cut power,
+ * meaning that a reset is required when restoring power soon after
+ * powering off. It is harmless in other cases.
+ *
+ * The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec,
+ * is not necessary for non-removable cards. However, it is required
+ * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and
+ * harmless in other situations.
+ *
+ * With these steps taken, mmc_select_voltage() is also required to
+ * restore the correct voltage setting of the card.
+ */
+ sdio_reset(host);
+ mmc_go_idle(host);
+ mmc_send_if_cond(host, host->ocr_avail);
+
+ ret = mmc_send_io_op_cond(host, 0, &ocr);
+ if (ret)
+ goto out;
+
+ if (host->ocr_avail_sdio)
+ host->ocr_avail = host->ocr_avail_sdio;
+
+ host->ocr = mmc_select_voltage(host, ocr & ~0x7F);
+ if (!host->ocr) {
+ ret = -EINVAL;
+ goto out;
+ }
+
ret = mmc_sdio_init_card(host, host->ocr, host->card,
mmc_card_keep_power(host));
if (!ret && host->sdio_irqs)
mmc_signal_sdio_irq(host);
+
+out:
mmc_release_host(host);
return ret;
diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c
index d29b9c36919a..d2565df8a7fb 100644
--- a/drivers/mmc/core/sdio_bus.c
+++ b/drivers/mmc/core/sdio_bus.c
@@ -189,7 +189,7 @@ static int sdio_bus_remove(struct device *dev)
/* Then undo the runtime PM settings in sdio_bus_probe() */
if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
- pm_runtime_put_noidle(dev);
+ pm_runtime_put_sync(dev);
out:
return ret;
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c
index e2aecb7f1d5c..ab66f2454dc4 100644
--- a/drivers/mmc/host/of_mmc_spi.c
+++ b/drivers/mmc/host/of_mmc_spi.c
@@ -25,6 +25,11 @@
#include <linux/mmc/core.h>
#include <linux/mmc/host.h>
+/* For archs that don't support NO_IRQ (such as mips), provide a dummy value */
+#ifndef NO_IRQ
+#define NO_IRQ 0
+#endif
+
MODULE_LICENSE("GPL");
enum {
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 5b2e2155b413..dedf3dab8a3b 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -429,7 +429,6 @@ static int omap_hsmmc_reg_get(struct omap_hsmmc_host *host)
return -EINVAL;
}
}
- mmc_slot(host).ocr_mask = mmc_regulator_get_ocrmask(reg);
/* Allow an aux regulator */
reg = regulator_get(host->dev, "vmmc_aux");
@@ -962,7 +961,8 @@ static void omap_hsmmc_dma_cleanup(struct omap_hsmmc_host *host, int errno)
spin_unlock(&host->irq_lock);
if (host->use_dma && dma_ch != -1) {
- dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,
+ dma_unmap_sg(mmc_dev(host->mmc), host->data->sg,
+ host->data->sg_len,
omap_hsmmc_get_dma_dir(host, host->data));
omap_free_dma(dma_ch);
}
@@ -1346,7 +1346,7 @@ static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data)
return;
}
- dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
omap_hsmmc_get_dma_dir(host, data));
req_in_progress = host->req_in_progress;
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index b3654293017b..ce500f03df85 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -92,7 +92,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
mmc_data->ocr_mask = p->tmio_ocr_mask;
mmc_data->capabilities |= p->tmio_caps;
- if (p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) {
+ if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
priv->param_tx.slave_id = p->dma_slave_tx;
priv->param_rx.slave_id = p->dma_slave_rx;
priv->dma_priv.chan_priv_tx = &priv->param_tx;
@@ -165,13 +165,14 @@ static int sh_mobile_sdhi_remove(struct platform_device *pdev)
p->pdata = NULL;
+ tmio_mmc_host_remove(host);
+
for (i = 0; i < 3; i++) {
irq = platform_get_irq(pdev, i);
if (irq >= 0)
free_irq(irq, host);
}
- tmio_mmc_host_remove(host);
clk_disable(priv->clk);
clk_put(priv->clk);
kfree(priv);
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index ad6347bb02dd..0b09e8239aa0 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -824,8 +824,8 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc)
struct tmio_mmc_host *host = mmc_priv(mmc);
struct tmio_mmc_data *pdata = host->pdata;
- return ((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
- !(sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
+ return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
+ (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
}
static int tmio_mmc_get_cd(struct mmc_host *mmc)
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
index cbb03305b77b..d4455ffbefd8 100644
--- a/drivers/mmc/host/vub300.c
+++ b/drivers/mmc/host/vub300.c
@@ -2096,7 +2096,7 @@ static struct mmc_host_ops vub300_mmc_ops = {
static int vub300_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{ /* NOT irq */
- struct vub300_mmc_host *vub300 = NULL;
+ struct vub300_mmc_host *vub300;
struct usb_host_interface *iface_desc;
struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface));
int i;
@@ -2118,23 +2118,20 @@ static int vub300_probe(struct usb_interface *interface,
command_out_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!command_out_urb) {
retval = -ENOMEM;
- dev_err(&vub300->udev->dev,
- "not enough memory for the command_out_urb\n");
+ dev_err(&udev->dev, "not enough memory for command_out_urb\n");
goto error0;
}
command_res_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!command_res_urb) {
retval = -ENOMEM;
- dev_err(&vub300->udev->dev,
- "not enough memory for the command_res_urb\n");
+ dev_err(&udev->dev, "not enough memory for command_res_urb\n");
goto error1;
}
/* this also allocates memory for our VUB300 mmc host device */
mmc = mmc_alloc_host(sizeof(struct vub300_mmc_host), &udev->dev);
if (!mmc) {
retval = -ENOMEM;
- dev_err(&vub300->udev->dev,
- "not enough memory for the mmc_host\n");
+ dev_err(&udev->dev, "not enough memory for the mmc_host\n");
goto error4;
}
/* MMC core transfer sizes tunable parameters */
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c
index 0bb254c7d2b1..33d8aad8bba5 100644
--- a/drivers/mtd/nand/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/fsl_elbc_nand.c
@@ -339,9 +339,9 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command,
(FIR_OP_UA << FIR_OP1_SHIFT) |
(FIR_OP_RBW << FIR_OP2_SHIFT));
out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT);
- /* 5 bytes for manuf, device and exts */
- out_be32(&lbc->fbcr, 5);
- elbc_fcm_ctrl->read_bytes = 5;
+ /* nand_get_flash_type() reads 8 bytes of entire ID string */
+ out_be32(&lbc->fbcr, 8);
+ elbc_fcm_ctrl->read_bytes = 8;
elbc_fcm_ctrl->use_mdr = 1;
elbc_fcm_ctrl->mdr = 0;
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 19f04a34783a..93359fab240e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -3416,7 +3416,8 @@ config NETCONSOLE
config NETCONSOLE_DYNAMIC
bool "Dynamic reconfiguration of logging targets"
- depends on NETCONSOLE && SYSFS && CONFIGFS_FS
+ depends on NETCONSOLE && SYSFS && CONFIGFS_FS && \
+ !(NETCONSOLE=y && CONFIGFS_FS=m)
help
This option enables the ability to dynamically reconfigure target
parameters (interface, IP addresses, port numbers, MAC addresses)
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index 4b70311a11ef..74be989f51c5 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -49,6 +49,7 @@
#include <linux/zlib.h>
#include <linux/io.h>
#include <linux/stringify.h>
+#include <linux/vmalloc.h>
#define BNX2X_MAIN
#include "bnx2x.h"
@@ -4537,8 +4538,7 @@ static int bnx2x_gunzip_init(struct bnx2x *bp)
if (bp->strm == NULL)
goto gunzip_nomem2;
- bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(),
- GFP_KERNEL);
+ bp->strm->workspace = vmalloc(zlib_inflate_workspacesize());
if (bp->strm->workspace == NULL)
goto gunzip_nomem3;
@@ -4562,7 +4562,7 @@ gunzip_nomem1:
static void bnx2x_gunzip_end(struct bnx2x *bp)
{
if (bp->strm) {
- kfree(bp->strm->workspace);
+ vfree(bp->strm->workspace);
kfree(bp->strm);
bp->strm = NULL;
}
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 1d699e3df547..754df5ef1729 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -36,7 +36,7 @@ config CAN_SLCAN
config CAN_DEV
tristate "Platform CAN drivers with Netlink support"
depends on CAN
- default Y
+ default y
---help---
Enables the common framework for platform CAN drivers with Netlink
support. This is the standard library for CAN drivers.
@@ -45,7 +45,7 @@ config CAN_DEV
config CAN_CALC_BITTIMING
bool "CAN bit-timing calculation"
depends on CAN_DEV
- default Y
+ default y
---help---
If enabled, CAN bit-timing parameters will be calculated for the
bit-rate specified via Netlink argument "bitrate" when the device
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 3f562ba2f0c9..76bf5892b962 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -2026,7 +2026,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
skb->ip_summed = CHECKSUM_UNNECESSARY;
} else
skb_checksum_none_assert(skb);
- skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
+ skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]);
if (unlikely(p->vlan_valid)) {
struct vlan_group *grp = pi->vlan_grp;
@@ -2145,7 +2145,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
if (!complete)
return;
- skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
+ skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]);
if (unlikely(cpl->vlan_valid)) {
struct vlan_group *grp = pi->vlan_grp;
diff --git a/drivers/net/ppp_deflate.c b/drivers/net/ppp_deflate.c
index 31e9407a0739..1dbdf82a6dfd 100644
--- a/drivers/net/ppp_deflate.c
+++ b/drivers/net/ppp_deflate.c
@@ -305,7 +305,7 @@ static void z_decomp_free(void *arg)
if (state) {
zlib_inflateEnd(&state->strm);
- kfree(state->strm.workspace);
+ vfree(state->strm.workspace);
kfree(state);
}
}
@@ -345,8 +345,7 @@ static void *z_decomp_alloc(unsigned char *options, int opt_len)
state->w_size = w_size;
state->strm.next_out = NULL;
- state->strm.workspace = kmalloc(zlib_inflate_workspacesize(),
- GFP_KERNEL|__GFP_REPEAT);
+ state->strm.workspace = vmalloc(zlib_inflate_workspacesize());
if (state->strm.workspace == NULL)
goto out_free;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 05d81780d1fd..5990621fb5cd 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -742,7 +742,7 @@ static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd)
msleep(2);
for (i = 0; i < 5; i++) {
udelay(100);
- if (!(RTL_R32(ERIDR) & ERIAR_FLAG))
+ if (!(RTL_R32(ERIAR) & ERIAR_FLAG))
break;
}
diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c
index 77c5092a6a40..5d3436d47edd 100644
--- a/drivers/net/rionet.c
+++ b/drivers/net/rionet.c
@@ -378,7 +378,7 @@ static int rionet_close(struct net_device *ndev)
static void rionet_remove(struct rio_dev *rdev)
{
- struct net_device *ndev = NULL;
+ struct net_device *ndev = rio_get_drvdata(rdev);
struct rionet_peer *peer, *tmp;
free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
@@ -433,22 +433,12 @@ static const struct net_device_ops rionet_netdev_ops = {
.ndo_set_mac_address = eth_mac_addr,
};
-static int rionet_setup_netdev(struct rio_mport *mport)
+static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
{
int rc = 0;
- struct net_device *ndev = NULL;
struct rionet_private *rnet;
u16 device_id;
- /* Allocate our net_device structure */
- ndev = alloc_etherdev(sizeof(struct rionet_private));
- if (ndev == NULL) {
- printk(KERN_INFO "%s: could not allocate ethernet device.\n",
- DRV_NAME);
- rc = -ENOMEM;
- goto out;
- }
-
rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
mport->sys_size ? __fls(sizeof(void *)) + 4 : 0);
if (!rionet_active) {
@@ -504,11 +494,21 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
int rc = -ENODEV;
u32 lpef, lsrc_ops, ldst_ops;
struct rionet_peer *peer;
+ struct net_device *ndev = NULL;
/* If local device is not rionet capable, give up quickly */
if (!rionet_capable)
goto out;
+ /* Allocate our net_device structure */
+ ndev = alloc_etherdev(sizeof(struct rionet_private));
+ if (ndev == NULL) {
+ printk(KERN_INFO "%s: could not allocate ethernet device.\n",
+ DRV_NAME);
+ rc = -ENOMEM;
+ goto out;
+ }
+
/*
* First time through, make sure local device is rionet
* capable, setup netdev, and set flags so this is skipped
@@ -529,7 +529,7 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
goto out;
}
- rc = rionet_setup_netdev(rdev->net->hport);
+ rc = rionet_setup_netdev(rdev->net->hport, ndev);
rionet_check = 1;
}
@@ -546,6 +546,8 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
list_add_tail(&peer->node, &rionet_peers);
}
+ rio_set_drvdata(rdev, ndev);
+
out:
return rc;
}
diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c
index d965fb1e013e..a9b6c63d54e4 100644
--- a/drivers/net/usb/kalmia.c
+++ b/drivers/net/usb/kalmia.c
@@ -100,34 +100,42 @@ kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len,
static int
kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr)
{
- char init_msg_1[] =
+ const static char init_msg_1[] =
{ 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
0x00, 0x00 };
- char init_msg_2[] =
+ const static char init_msg_2[] =
{ 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf4,
0x00, 0x00 };
- char receive_buf[28];
+ const static int buflen = 28;
+ char *usb_buf;
int status;
- status = kalmia_send_init_packet(dev, init_msg_1, sizeof(init_msg_1)
- / sizeof(init_msg_1[0]), receive_buf, 24);
+ usb_buf = kmalloc(buflen, GFP_DMA | GFP_KERNEL);
+ if (!usb_buf)
+ return -ENOMEM;
+
+ memcpy(usb_buf, init_msg_1, 12);
+ status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_1)
+ / sizeof(init_msg_1[0]), usb_buf, 24);
if (status != 0)
return status;
- status = kalmia_send_init_packet(dev, init_msg_2, sizeof(init_msg_2)
- / sizeof(init_msg_2[0]), receive_buf, 28);
+ memcpy(usb_buf, init_msg_2, 12);
+ status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_2)
+ / sizeof(init_msg_2[0]), usb_buf, 28);
if (status != 0)
return status;
- memcpy(ethernet_addr, receive_buf + 10, ETH_ALEN);
+ memcpy(ethernet_addr, usb_buf + 10, ETH_ALEN);
+ kfree(usb_buf);
return status;
}
static int
kalmia_bind(struct usbnet *dev, struct usb_interface *intf)
{
- u8 status;
+ int status;
u8 ethernet_addr[ETH_ALEN];
/* Don't bind to AT command interface */
@@ -190,7 +198,8 @@ kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
dev_kfree_skb_any(skb);
skb = skb2;
- done: header_start = skb_push(skb, KALMIA_HEADER_LENGTH);
+done:
+ header_start = skb_push(skb, KALMIA_HEADER_LENGTH);
ether_type_1 = header_start[KALMIA_HEADER_LENGTH + 12];
ether_type_2 = header_start[KALMIA_HEADER_LENGTH + 13];
@@ -201,9 +210,8 @@ kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
header_start[0] = 0x57;
header_start[1] = 0x44;
content_len = skb->len - KALMIA_HEADER_LENGTH;
- header_start[2] = (content_len & 0xff); /* low byte */
- header_start[3] = (content_len >> 8); /* high byte */
+ put_unaligned_le16(content_len, &header_start[2]);
header_start[4] = ether_type_1;
header_start[5] = ether_type_2;
@@ -231,13 +239,13 @@ kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
* Our task here is to strip off framing, leaving skb with one
* data frame for the usbnet framework code to process.
*/
- const u8 HEADER_END_OF_USB_PACKET[] =
+ const static u8 HEADER_END_OF_USB_PACKET[] =
{ 0x57, 0x5a, 0x00, 0x00, 0x08, 0x00 };
- const u8 EXPECTED_UNKNOWN_HEADER_1[] =
+ const static u8 EXPECTED_UNKNOWN_HEADER_1[] =
{ 0x57, 0x43, 0x1e, 0x00, 0x15, 0x02 };
- const u8 EXPECTED_UNKNOWN_HEADER_2[] =
+ const static u8 EXPECTED_UNKNOWN_HEADER_2[] =
{ 0x57, 0x50, 0x0e, 0x00, 0x00, 0x00 };
- u8 i = 0;
+ int i = 0;
/* incomplete header? */
if (skb->len < KALMIA_HEADER_LENGTH)
@@ -285,7 +293,7 @@ kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
/* subtract start header and end header */
usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH);
- ether_packet_length = header_start[2] + (header_start[3] << 8);
+ ether_packet_length = get_unaligned_le16(&header_start[2]);
skb_pull(skb, KALMIA_HEADER_LENGTH);
/* Some small packets misses end marker */
diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c
index 241756e0e86f..1a2234c20514 100644
--- a/drivers/net/usb/zaurus.c
+++ b/drivers/net/usb/zaurus.c
@@ -331,17 +331,7 @@ static const struct usb_device_id products [] = {
ZAURUS_MASTER_INTERFACE,
.driver_info = ZAURUS_PXA_INFO,
},
-
-
-/* At least some of the newest PXA units have very different lies about
- * their standards support: they claim to be cell phones offering
- * direct access to their radios! (No, they don't conform to CDC MDLM.)
- */
{
- USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
- USB_CDC_PROTO_NONE),
- .driver_info = (unsigned long) &bogus_mdlm_info,
-}, {
/* Motorola MOTOMAGX phones */
USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM,
USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 9f8ccae93317..254b64ba4bf6 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1624,6 +1624,16 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
pci_read_config_byte(pdev, 0x8, &revisionid);
pci_read_config_word(pdev, 0x3C, &irqline);
+ /* PCI ID 0x10ec:0x8192 occurs for both RTL8192E, which uses
+ * r8192e_pci, and RTL8192SE, which uses this driver. If the
+ * revision ID is RTL_PCI_REVISION_ID_8192PCIE (0x01), then
+ * the correct driver is r8192e_pci, thus this routine should
+ * return false.
+ */
+ if (deviceid == RTL_PCI_8192SE_DID &&
+ revisionid == RTL_PCI_REVISION_ID_8192PCIE)
+ return false;
+
if (deviceid == RTL_PCI_8192_DID ||
deviceid == RTL_PCI_0044_DID ||
deviceid == RTL_PCI_0047_DID ||
@@ -1856,7 +1866,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
pci_write_config_byte(pdev, 0x04, 0x07);
/* find adapter */
- _rtl_pci_find_adapter(pdev, hw);
+ if (!_rtl_pci_find_adapter(pdev, hw))
+ goto fail3;
/* Init IO handler */
_rtl_pci_io_handler_init(&pdev->dev, hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index bee7c1480f63..092e342c19df 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -53,6 +53,8 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
+ const struct firmware *firmware;
+ int err;
rtlpriv->dm.dm_initialgain_enable = 1;
rtlpriv->dm.dm_flag = 0;
@@ -64,6 +66,24 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
("Can't alloc buffer for fw.\n"));
return 1;
}
+ /* request fw */
+ err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
+ rtlpriv->io.dev);
+ if (err) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Failed to request firmware!\n"));
+ return 1;
+ }
+ if (firmware->size > 0x4000) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Firmware is too big!\n"));
+ release_firmware(firmware);
+ return 1;
+ }
+ memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
+ rtlpriv->rtlhal.fwsize = firmware->size;
+ release_firmware(firmware);
+
return 0;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index e8a140669f90..02145e9697a9 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2761,6 +2761,8 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832);
#endif /*CONFIG_MMC_RICOH_MMC*/
#if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP)
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 4724ba3acf1a..b2005b44e4f7 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -149,6 +149,7 @@ static const struct i2c_device_id ds1307_id[] = {
{ "ds1340", ds_1340 },
{ "ds3231", ds_3231 },
{ "m41t00", m41t00 },
+ { "pt7c4338", ds_1307 },
{ "rx8025", rx_8025 },
{ }
};
diff --git a/drivers/rtc/rtc-vt8500.c b/drivers/rtc/rtc-vt8500.c
index b8bc862903ae..efd6066b5cd2 100644
--- a/drivers/rtc/rtc-vt8500.c
+++ b/drivers/rtc/rtc-vt8500.c
@@ -78,7 +78,6 @@ struct vt8500_rtc {
void __iomem *regbase;
struct resource *res;
int irq_alarm;
- int irq_hz;
struct rtc_device *rtc;
spinlock_t lock; /* Protects this structure */
};
@@ -100,10 +99,6 @@ static irqreturn_t vt8500_rtc_irq(int irq, void *dev_id)
if (isr & 1)
events |= RTC_AF | RTC_IRQF;
- /* Only second/minute interrupts are supported */
- if (isr & 2)
- events |= RTC_UF | RTC_IRQF;
-
rtc_update_irq(vt8500_rtc->rtc, 1, events);
return IRQ_HANDLED;
@@ -199,27 +194,12 @@ static int vt8500_alarm_irq_enable(struct device *dev, unsigned int enabled)
return 0;
}
-static int vt8500_update_irq_enable(struct device *dev, unsigned int enabled)
-{
- struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev);
- unsigned long tmp = readl(vt8500_rtc->regbase + VT8500_RTC_CR);
-
- if (enabled)
- tmp |= VT8500_RTC_CR_SM_SEC | VT8500_RTC_CR_SM_ENABLE;
- else
- tmp &= ~VT8500_RTC_CR_SM_ENABLE;
-
- writel(tmp, vt8500_rtc->regbase + VT8500_RTC_CR);
- return 0;
-}
-
static const struct rtc_class_ops vt8500_rtc_ops = {
.read_time = vt8500_rtc_read_time,
.set_time = vt8500_rtc_set_time,
.read_alarm = vt8500_rtc_read_alarm,
.set_alarm = vt8500_rtc_set_alarm,
.alarm_irq_enable = vt8500_alarm_irq_enable,
- .update_irq_enable = vt8500_update_irq_enable,
};
static int __devinit vt8500_rtc_probe(struct platform_device *pdev)
@@ -248,13 +228,6 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev)
goto err_free;
}
- vt8500_rtc->irq_hz = platform_get_irq(pdev, 1);
- if (vt8500_rtc->irq_hz < 0) {
- dev_err(&pdev->dev, "No 1Hz IRQ resource defined\n");
- ret = -ENXIO;
- goto err_free;
- }
-
vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start,
resource_size(vt8500_rtc->res),
"vt8500-rtc");
@@ -272,9 +245,8 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev)
goto err_release;
}
- /* Enable the second/minute interrupt generation and enable RTC */
- writel(VT8500_RTC_CR_ENABLE | VT8500_RTC_CR_24H
- | VT8500_RTC_CR_SM_ENABLE | VT8500_RTC_CR_SM_SEC,
+ /* Enable RTC and set it to 24-hour mode */
+ writel(VT8500_RTC_CR_ENABLE | VT8500_RTC_CR_24H,
vt8500_rtc->regbase + VT8500_RTC_CR);
vt8500_rtc->rtc = rtc_device_register("vt8500-rtc", &pdev->dev,
@@ -286,26 +258,16 @@ static int __devinit vt8500_rtc_probe(struct platform_device *pdev)
goto err_unmap;
}
- ret = request_irq(vt8500_rtc->irq_hz, vt8500_rtc_irq, 0,
- "rtc 1Hz", vt8500_rtc);
- if (ret < 0) {
- dev_err(&pdev->dev, "can't get irq %i, err %d\n",
- vt8500_rtc->irq_hz, ret);
- goto err_unreg;
- }
-
ret = request_irq(vt8500_rtc->irq_alarm, vt8500_rtc_irq, 0,
"rtc alarm", vt8500_rtc);
if (ret < 0) {
dev_err(&pdev->dev, "can't get irq %i, err %d\n",
vt8500_rtc->irq_alarm, ret);
- goto err_free_hz;
+ goto err_unreg;
}
return 0;
-err_free_hz:
- free_irq(vt8500_rtc->irq_hz, vt8500_rtc);
err_unreg:
rtc_device_unregister(vt8500_rtc->rtc);
err_unmap:
@@ -323,7 +285,6 @@ static int __devexit vt8500_rtc_remove(struct platform_device *pdev)
struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev);
free_irq(vt8500_rtc->irq_alarm, vt8500_rtc);
- free_irq(vt8500_rtc->irq_hz, vt8500_rtc);
rtc_device_unregister(vt8500_rtc->rtc);
diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig
index f4cf9b23481e..379cf16e89f7 100644
--- a/drivers/staging/brcm80211/Kconfig
+++ b/drivers/staging/brcm80211/Kconfig
@@ -7,6 +7,7 @@ config BRCMSMAC
default n
depends on PCI
depends on WLAN && MAC80211
+ depends on X86 || MIPS
select BRCMUTIL
select FW_LOADER
select CRC_CCITT
@@ -20,6 +21,7 @@ config BRCMFMAC
default n
depends on MMC
depends on WLAN && CFG80211
+ depends on X86 || MIPS
select BRCMUTIL
select FW_LOADER
select WIRELESS_EXT
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index 1502d80f6f78..20008a4376e8 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -2,6 +2,7 @@ config COMEDI
tristate "Data acquisition support (comedi)"
default N
depends on m
+ depends on BROKEN || FRV || M32R || MN10300 || SUPERH || TILE || X86
---help---
Enable support a wide range of data acquisition devices
for Linux.
@@ -160,6 +161,7 @@ config COMEDI_PCL730
config COMEDI_PCL812
tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink
@@ -171,6 +173,7 @@ config COMEDI_PCL812
config COMEDI_PCL816
tristate "Advantech PCL-814 and PCL-816 ISA card support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for Advantech PCL-814 and PCL-816 ISA cards
@@ -180,6 +183,7 @@ config COMEDI_PCL816
config COMEDI_PCL818
tristate "Advantech PCL-718 and PCL-818 ISA card support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for Advantech PCL-818 ISA cards
@@ -269,6 +273,7 @@ config COMEDI_DAS800
config COMEDI_DAS1800
tristate "DAS1800 and compatible ISA card support"
+ depends on VIRT_TO_BUS
select COMEDI_FC
default N
---help---
@@ -340,6 +345,7 @@ config COMEDI_DT2817
config COMEDI_DT282X
tristate "Data Translation DT2821 series and DT-EZ ISA card support"
select COMEDI_FC
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for Data Translation DT2821 series including DT-EZ
@@ -419,6 +425,7 @@ config COMEDI_ADQ12B
config COMEDI_NI_AT_A2150
tristate "NI AT-A2150 ISA card support"
depends on COMEDI_NI_COMMON
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for National Instruments AT-A2150 cards
@@ -536,6 +543,7 @@ if COMEDI_PCI_DRIVERS && PCI
config COMEDI_ADDI_APCI_035
tristate "ADDI-DATA APCI_035 support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for ADDI-DATA APCI_035 cards
@@ -545,6 +553,7 @@ config COMEDI_ADDI_APCI_035
config COMEDI_ADDI_APCI_1032
tristate "ADDI-DATA APCI_1032 support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for ADDI-DATA APCI_1032 cards
@@ -554,6 +563,7 @@ config COMEDI_ADDI_APCI_1032
config COMEDI_ADDI_APCI_1500
tristate "ADDI-DATA APCI_1500 support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for ADDI-DATA APCI_1500 cards
@@ -563,6 +573,7 @@ config COMEDI_ADDI_APCI_1500
config COMEDI_ADDI_APCI_1516
tristate "ADDI-DATA APCI_1516 support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for ADDI-DATA APCI_1516 cards
@@ -572,6 +583,7 @@ config COMEDI_ADDI_APCI_1516
config COMEDI_ADDI_APCI_1564
tristate "ADDI-DATA APCI_1564 support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for ADDI-DATA APCI_1564 cards
@@ -581,6 +593,7 @@ config COMEDI_ADDI_APCI_1564
config COMEDI_ADDI_APCI_16XX
tristate "ADDI-DATA APCI_16xx support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for ADDI-DATA APCI_16xx cards
@@ -590,6 +603,7 @@ config COMEDI_ADDI_APCI_16XX
config COMEDI_ADDI_APCI_2016
tristate "ADDI-DATA APCI_2016 support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for ADDI-DATA APCI_2016 cards
@@ -599,6 +613,7 @@ config COMEDI_ADDI_APCI_2016
config COMEDI_ADDI_APCI_2032
tristate "ADDI-DATA APCI_2032 support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for ADDI-DATA APCI_2032 cards
@@ -608,6 +623,7 @@ config COMEDI_ADDI_APCI_2032
config COMEDI_ADDI_APCI_2200
tristate "ADDI-DATA APCI_2200 support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for ADDI-DATA APCI_2200 cards
@@ -617,6 +633,7 @@ config COMEDI_ADDI_APCI_2200
config COMEDI_ADDI_APCI_3001
tristate "ADDI-DATA APCI_3001 support"
+ depends on VIRT_TO_BUS
select COMEDI_FC
default N
---help---
@@ -627,6 +644,7 @@ config COMEDI_ADDI_APCI_3001
config COMEDI_ADDI_APCI_3120
tristate "ADDI-DATA APCI_3520 support"
+ depends on VIRT_TO_BUS
select COMEDI_FC
default N
---help---
@@ -637,6 +655,7 @@ config COMEDI_ADDI_APCI_3120
config COMEDI_ADDI_APCI_3501
tristate "ADDI-DATA APCI_3501 support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for ADDI-DATA APCI_3501 cards
@@ -646,6 +665,7 @@ config COMEDI_ADDI_APCI_3501
config COMEDI_ADDI_APCI_3XXX
tristate "ADDI-DATA APCI_3xxx support"
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for ADDI-DATA APCI_3xxx cards
@@ -712,6 +732,7 @@ config COMEDI_ADL_PCI9111
config COMEDI_ADL_PCI9118
tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support"
select COMEDI_FC
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for ADlink PCI-9118DG, PCI-9118HG, PCI-9118HR cards
@@ -1287,6 +1308,7 @@ config COMEDI_NI_LABPC
depends on COMEDI_MITE
select COMEDI_8255
select COMEDI_FC
+ depends on VIRT_TO_BUS
default N
---help---
Enable support for National Instruments Lab-PC and compatibles
diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig
index f96d5b5d5141..d329635fb5c4 100644
--- a/drivers/staging/iio/Kconfig
+++ b/drivers/staging/iio/Kconfig
@@ -4,7 +4,7 @@
menuconfig IIO
tristate "Industrial I/O support"
- depends on !S390
+ depends on GENERIC_HARDIRQS
help
The industrial I/O subsystem provides a unified framework for
drivers for many different types of embedded sensors using a
diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h
index 5310a4297688..1690c0d15690 100644
--- a/drivers/staging/iio/accel/adis16204.h
+++ b/drivers/staging/iio/accel/adis16204.h
@@ -84,7 +84,6 @@ struct adis16204_state {
int adis16204_set_irq(struct iio_dev *indio_dev, bool enable);
-#ifdef CONFIG_IIO_RING_BUFFER
enum adis16204_scan {
ADIS16204_SCAN_SUPPLY,
ADIS16204_SCAN_ACC_X,
@@ -93,6 +92,7 @@ enum adis16204_scan {
ADIS16204_SCAN_TEMP,
};
+#ifdef CONFIG_IIO_RING_BUFFER
void adis16204_remove_trigger(struct iio_dev *indio_dev);
int adis16204_probe_trigger(struct iio_dev *indio_dev);
diff --git a/drivers/staging/iio/accel/adis16209.h b/drivers/staging/iio/accel/adis16209.h
index 58d08db6f9b5..3153cbee0957 100644
--- a/drivers/staging/iio/accel/adis16209.h
+++ b/drivers/staging/iio/accel/adis16209.h
@@ -121,8 +121,6 @@ struct adis16209_state {
int adis16209_set_irq(struct iio_dev *indio_dev, bool enable);
-#ifdef CONFIG_IIO_RING_BUFFER
-
#define ADIS16209_SCAN_SUPPLY 0
#define ADIS16209_SCAN_ACC_X 1
#define ADIS16209_SCAN_ACC_Y 2
@@ -132,6 +130,8 @@ int adis16209_set_irq(struct iio_dev *indio_dev, bool enable);
#define ADIS16209_SCAN_INCLI_Y 6
#define ADIS16209_SCAN_ROT 7
+#ifdef CONFIG_IIO_RING_BUFFER
+
void adis16209_remove_trigger(struct iio_dev *indio_dev);
int adis16209_probe_trigger(struct iio_dev *indio_dev);
diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h
index 702dc982f62f..24bf70e4b29b 100644
--- a/drivers/staging/iio/gyro/adis16260.h
+++ b/drivers/staging/iio/gyro/adis16260.h
@@ -104,7 +104,6 @@ struct adis16260_state {
int adis16260_set_irq(struct iio_dev *indio_dev, bool enable);
-#ifdef CONFIG_IIO_RING_BUFFER
/* At the moment triggers are only used for ring buffer
* filling. This may change!
*/
@@ -115,6 +114,7 @@ int adis16260_set_irq(struct iio_dev *indio_dev, bool enable);
#define ADIS16260_SCAN_TEMP 3
#define ADIS16260_SCAN_ANGL 4
+#ifdef CONFIG_IIO_RING_BUFFER
void adis16260_remove_trigger(struct iio_dev *indio_dev);
int adis16260_probe_trigger(struct iio_dev *indio_dev);
diff --git a/drivers/staging/iio/imu/adis16400.h b/drivers/staging/iio/imu/adis16400.h
index db184d11dfc0..e87715b9acc6 100644
--- a/drivers/staging/iio/imu/adis16400.h
+++ b/drivers/staging/iio/imu/adis16400.h
@@ -158,7 +158,6 @@ struct adis16400_state {
int adis16400_set_irq(struct iio_dev *indio_dev, bool enable);
-#ifdef CONFIG_IIO_RING_BUFFER
/* At the moment triggers are only used for ring buffer
* filling. This may change!
*/
@@ -182,6 +181,7 @@ int adis16400_set_irq(struct iio_dev *indio_dev, bool enable);
#define ADIS16300_SCAN_INCLI_X 12
#define ADIS16300_SCAN_INCLI_Y 13
+#ifdef CONFIG_IIO_RING_BUFFER
void adis16400_remove_trigger(struct iio_dev *indio_dev);
int adis16400_probe_trigger(struct iio_dev *indio_dev);
diff --git a/drivers/staging/mei/init.c b/drivers/staging/mei/init.c
index d1ffa32cd141..685fcf639644 100644
--- a/drivers/staging/mei/init.c
+++ b/drivers/staging/mei/init.c
@@ -189,7 +189,7 @@ int mei_hw_init(struct mei_device *dev)
mutex_lock(&dev->device_lock);
}
- if (!err && !dev->recvd_msg) {
+ if (err <= 0 && !dev->recvd_msg) {
dev->mei_state = MEI_DISABLED;
dev_dbg(&dev->pdev->dev,
"wait_event_interruptible_timeout failed"
diff --git a/drivers/staging/mei/wd.c b/drivers/staging/mei/wd.c
index 2564b038636a..fff53d0b5c6e 100644
--- a/drivers/staging/mei/wd.c
+++ b/drivers/staging/mei/wd.c
@@ -169,10 +169,15 @@ int mei_wd_stop(struct mei_device *dev, bool preserve)
ret = wait_event_interruptible_timeout(dev->wait_stop_wd,
dev->wd_stopped, 10 * HZ);
mutex_lock(&dev->device_lock);
- if (!dev->wd_stopped)
- dev_dbg(&dev->pdev->dev, "stop wd failed to complete.\n");
- else
- dev_dbg(&dev->pdev->dev, "stop wd complete.\n");
+ if (dev->wd_stopped) {
+ dev_dbg(&dev->pdev->dev, "stop wd complete ret=%d.\n", ret);
+ ret = 0;
+ } else {
+ if (!ret)
+ ret = -ETIMEDOUT;
+ dev_warn(&dev->pdev->dev,
+ "stop wd failed to complete ret=%d.\n", ret);
+ }
if (preserve)
dev->wd_timeout = wd_timeout;
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 09e8c7d53af3..19b4ae052af8 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -875,7 +875,8 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
*dp++ = last << 7 | first << 6 | 1; /* EA */
len--;
}
- memcpy(dp, skb_pull(dlci->skb, len), len);
+ memcpy(dp, dlci->skb->data, len);
+ skb_pull(dlci->skb, len);
__gsm_data_queue(dlci, msg);
if (last)
dlci->skb = NULL;
@@ -984,10 +985,22 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, u8 *data,
*/
static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
- u32 modem)
+ u32 modem, int clen)
{
int mlines = 0;
- u8 brk = modem >> 6;
+ u8 brk = 0;
+
+ /* The modem status command can either contain one octet (v.24 signals)
+ or two octets (v.24 signals + break signals). The length field will
+ either be 2 or 3 respectively. This is specified in section
+ 5.4.6.3.7 of the 27.010 mux spec. */
+
+ if (clen == 2)
+ modem = modem & 0x7f;
+ else {
+ brk = modem & 0x7f;
+ modem = (modem >> 7) & 0x7f;
+ };
/* Flow control/ready to communicate */
if (modem & MDM_FC) {
@@ -1061,7 +1074,7 @@ static void gsm_control_modem(struct gsm_mux *gsm, u8 *data, int clen)
return;
}
tty = tty_port_tty_get(&dlci->port);
- gsm_process_modem(tty, dlci, modem);
+ gsm_process_modem(tty, dlci, modem, clen);
if (tty) {
tty_wakeup(tty);
tty_kref_put(tty);
@@ -1482,12 +1495,13 @@ static void gsm_dlci_begin_close(struct gsm_dlci *dlci)
* open we shovel the bits down it, if not we drop them.
*/
-static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len)
+static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int clen)
{
/* krefs .. */
struct tty_port *port = &dlci->port;
struct tty_struct *tty = tty_port_tty_get(port);
unsigned int modem = 0;
+ int len = clen;
if (debug & 16)
pr_debug("%d bytes for tty %p\n", len, tty);
@@ -1507,7 +1521,7 @@ static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len)
if (len == 0)
return;
}
- gsm_process_modem(tty, dlci, modem);
+ gsm_process_modem(tty, dlci, modem, clen);
/* Line state will go via DLCI 0 controls only */
case 1:
default:
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 0ad32888091c..c3954fbf6ac4 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -1815,6 +1815,7 @@ do_it_again:
/* FIXME: does n_tty_set_room need locking ? */
n_tty_set_room(tty);
timeout = schedule_timeout(timeout);
+ BUG_ON(!tty->read_buf);
continue;
}
__set_current_state(TASK_RUNNING);
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index b40f7b90c81d..b4129f53fb1b 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -3318,6 +3318,7 @@ void serial8250_unregister_port(int line)
uart->port.flags &= ~UPF_BOOT_AUTOCONF;
uart->port.type = PORT_UNKNOWN;
uart->port.dev = &serial8250_isa_devs->dev;
+ uart->capabilities = uart_config[uart->port.type].flags;
uart_add_one_port(&serial8250_reg, &uart->port);
} else {
uart->port.dev = NULL;
diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c
index 4b4968a294b2..f41b4259ecdd 100644
--- a/drivers/tty/serial/8250_pci.c
+++ b/drivers/tty/serial/8250_pci.c
@@ -973,7 +973,7 @@ ce4100_serial_setup(struct serial_private *priv,
static int
pci_omegapci_setup(struct serial_private *priv,
- struct pciserial_board *board,
+ const struct pciserial_board *board,
struct uart_port *port, int idx)
{
return setup_port(priv, port, 2, idx * 8, 0);
@@ -994,6 +994,15 @@ static int skip_tx_en_setup(struct serial_private *priv,
return pci_default_setup(priv, board, port, idx);
}
+static int pci_eg20t_init(struct pci_dev *dev)
+{
+#if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE)
+ return -ENODEV;
+#else
+ return 0;
+#endif
+}
+
/* This should be in linux/pci_ids.h */
#define PCI_VENDOR_ID_SBSMODULARIO 0x124B
#define PCI_SUBVENDOR_ID_SBSMODULARIO 0x124B
@@ -1446,6 +1455,56 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.init = pci_oxsemi_tornado_init,
.setup = pci_default_setup,
},
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x8811,
+ .init = pci_eg20t_init,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x8812,
+ .init = pci_eg20t_init,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x8813,
+ .init = pci_eg20t_init,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = 0x8814,
+ .init = pci_eg20t_init,
+ },
+ {
+ .vendor = 0x10DB,
+ .device = 0x8027,
+ .init = pci_eg20t_init,
+ },
+ {
+ .vendor = 0x10DB,
+ .device = 0x8028,
+ .init = pci_eg20t_init,
+ },
+ {
+ .vendor = 0x10DB,
+ .device = 0x8029,
+ .init = pci_eg20t_init,
+ },
+ {
+ .vendor = 0x10DB,
+ .device = 0x800C,
+ .init = pci_eg20t_init,
+ },
+ {
+ .vendor = 0x10DB,
+ .device = 0x800D,
+ .init = pci_eg20t_init,
+ },
+ {
+ .vendor = 0x10DB,
+ .device = 0x800D,
+ .init = pci_eg20t_init,
+ },
/*
* Cronyx Omega PCI (PLX-chip based)
*/
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index 8dc0541feecc..f5f6831b0a64 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -50,6 +50,7 @@
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
+#include <linux/delay.h>
#include <asm/io.h>
#include <asm/sizes.h>
@@ -65,6 +66,30 @@
#define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
#define UART_DUMMY_DR_RX (1 << 16)
+
+#define UART_WA_SAVE_NR 14
+
+static void pl011_lockup_wa(unsigned long data);
+static const u32 uart_wa_reg[UART_WA_SAVE_NR] = {
+ ST_UART011_DMAWM,
+ ST_UART011_TIMEOUT,
+ ST_UART011_LCRH_RX,
+ UART011_IBRD,
+ UART011_FBRD,
+ ST_UART011_LCRH_TX,
+ UART011_IFLS,
+ ST_UART011_XFCR,
+ ST_UART011_XON1,
+ ST_UART011_XON2,
+ ST_UART011_XOFF1,
+ ST_UART011_XOFF2,
+ UART011_CR,
+ UART011_IMSC
+};
+
+static u32 uart_wa_regdata[UART_WA_SAVE_NR];
+static DECLARE_TASKLET(pl011_lockup_tlet, pl011_lockup_wa, 0);
+
/* There is by now at least one vendor with differing details, so handle it */
struct vendor_data {
unsigned int ifls;
@@ -72,6 +97,7 @@ struct vendor_data {
unsigned int lcrh_tx;
unsigned int lcrh_rx;
bool oversampling;
+ bool interrupt_may_hang; /* vendor-specific */
bool dma_threshold;
};
@@ -90,9 +116,12 @@ static struct vendor_data vendor_st = {
.lcrh_tx = ST_UART011_LCRH_TX,
.lcrh_rx = ST_UART011_LCRH_RX,
.oversampling = true,
+ .interrupt_may_hang = true,
.dma_threshold = true,
};
+static struct uart_amba_port *amba_ports[UART_NR];
+
/* Deals with DMA transactions */
struct pl011_sgbuf {
@@ -132,6 +161,7 @@ struct uart_amba_port {
unsigned int lcrh_rx; /* vendor-specific */
bool autorts;
char type[12];
+ bool interrupt_may_hang; /* vendor-specific */
#ifdef CONFIG_DMA_ENGINE
/* DMA stuff */
bool using_tx_dma;
@@ -1008,6 +1038,68 @@ static inline bool pl011_dma_rx_running(struct uart_amba_port *uap)
#endif
+/*
+ * pl011_lockup_wa
+ * This workaround aims to break the deadlock situation
+ * when after long transfer over uart in hardware flow
+ * control, uart interrupt registers cannot be cleared.
+ * Hence uart transfer gets blocked.
+ *
+ * It is seen that during such deadlock condition ICR
+ * don't get cleared even on multiple write. This leads
+ * pass_counter to decrease and finally reach zero. This
+ * can be taken as trigger point to run this UART_BT_WA.
+ *
+ */
+static void pl011_lockup_wa(unsigned long data)
+{
+ struct uart_amba_port *uap = amba_ports[0];
+ void __iomem *base = uap->port.membase;
+ struct circ_buf *xmit = &uap->port.state->xmit;
+ struct tty_struct *tty = uap->port.state->port.tty;
+ int buf_empty_retries = 200;
+ int loop;
+
+ /* Stop HCI layer from submitting data for tx */
+ tty->hw_stopped = 1;
+ while (!uart_circ_empty(xmit)) {
+ if (buf_empty_retries-- == 0)
+ break;
+ udelay(100);
+ }
+
+ /* Backup registers */
+ for (loop = 0; loop < UART_WA_SAVE_NR; loop++)
+ uart_wa_regdata[loop] = readl(base + uart_wa_reg[loop]);
+
+ /* Disable UART so that FIFO data is flushed out */
+ writew(0x00, uap->port.membase + UART011_CR);
+
+ /* Soft reset UART module */
+ if (uap->port.dev->platform_data) {
+ struct amba_pl011_data *plat;
+
+ plat = uap->port.dev->platform_data;
+ if (plat->reset)
+ plat->reset();
+ }
+
+ /* Restore registers */
+ for (loop = 0; loop < UART_WA_SAVE_NR; loop++)
+ writew(uart_wa_regdata[loop] ,
+ uap->port.membase + uart_wa_reg[loop]);
+
+ /* Initialise the old status of the modem signals */
+ uap->old_status = readw(uap->port.membase + UART01x_FR) &
+ UART01x_FR_MODEM_ANY;
+
+ if (readl(base + UART011_MIS) & 0x2)
+ printk(KERN_EMERG "UART_BT_WA: ***FAILED***\n");
+
+ /* Start Tx/Rx */
+ tty->hw_stopped = 0;
+}
+
static void pl011_stop_tx(struct uart_port *port)
{
struct uart_amba_port *uap = (struct uart_amba_port *)port;
@@ -1158,8 +1250,11 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
if (status & UART011_TXIS)
pl011_tx_chars(uap);
- if (pass_counter-- == 0)
+ if (pass_counter-- == 0) {
+ if (uap->interrupt_may_hang)
+ tasklet_schedule(&pl011_lockup_tlet);
break;
+ }
status = readw(uap->port.membase + UART011_MIS);
} while (status != 0);
@@ -1339,6 +1434,14 @@ static int pl011_startup(struct uart_port *port)
writew(uap->im, uap->port.membase + UART011_IMSC);
spin_unlock_irq(&uap->port.lock);
+ if (uap->port.dev->platform_data) {
+ struct amba_pl011_data *plat;
+
+ plat = uap->port.dev->platform_data;
+ if (plat->init)
+ plat->init();
+ }
+
return 0;
clk_dis:
@@ -1394,6 +1497,15 @@ static void pl011_shutdown(struct uart_port *port)
* Shut down the clock producer
*/
clk_disable(uap->clk);
+
+ if (uap->port.dev->platform_data) {
+ struct amba_pl011_data *plat;
+
+ plat = uap->port.dev->platform_data;
+ if (plat->exit)
+ plat->exit();
+ }
+
}
static void
@@ -1700,6 +1812,14 @@ static int __init pl011_console_setup(struct console *co, char *options)
if (!uap)
return -ENODEV;
+ if (uap->port.dev->platform_data) {
+ struct amba_pl011_data *plat;
+
+ plat = uap->port.dev->platform_data;
+ if (plat->init)
+ plat->init();
+ }
+
uap->port.uartclk = clk_get_rate(uap->clk);
if (options)
@@ -1774,6 +1894,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
uap->lcrh_rx = vendor->lcrh_rx;
uap->lcrh_tx = vendor->lcrh_tx;
uap->fifosize = vendor->fifosize;
+ uap->interrupt_may_hang = vendor->interrupt_may_hang;
uap->port.dev = &dev->dev;
uap->port.mapbase = dev->res.start;
uap->port.membase = base;
diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c
index a1a0e55d0807..c0b68b9cad91 100644
--- a/drivers/tty/serial/bcm63xx_uart.c
+++ b/drivers/tty/serial/bcm63xx_uart.c
@@ -250,6 +250,20 @@ static void bcm_uart_do_rx(struct uart_port *port)
/* get overrun/fifo empty information from ier
* register */
iestat = bcm_uart_readl(port, UART_IR_REG);
+
+ if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) {
+ unsigned int val;
+
+ /* fifo reset is required to clear
+ * interrupt */
+ val = bcm_uart_readl(port, UART_CTL_REG);
+ val |= UART_CTL_RSTRXFIFO_MASK;
+ bcm_uart_writel(port, val, UART_CTL_REG);
+
+ port->icount.overrun++;
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+ }
+
if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
break;
@@ -284,10 +298,6 @@ static void bcm_uart_do_rx(struct uart_port *port)
if (uart_handle_sysrq_char(port, c))
continue;
- if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) {
- port->icount.overrun++;
- tty_insert_flip_char(tty, 0, TTY_OVERRUN);
- }
if ((cstat & port->ignore_status_mask) == 0)
tty_insert_flip_char(tty, c, flag);
diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c
index 18f548449c63..96da17868cf3 100644
--- a/drivers/tty/serial/jsm/jsm_driver.c
+++ b/drivers/tty/serial/jsm/jsm_driver.c
@@ -125,7 +125,7 @@ static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device
brd->bd_uart_offset = 0x200;
brd->bd_dividend = 921600;
- brd->re_map_membase = ioremap(brd->membase, 0x1000);
+ brd->re_map_membase = ioremap(brd->membase, pci_resource_len(pdev, 0));
if (!brd->re_map_membase) {
dev_err(&pdev->dev,
"card has no PCI Memory resources, "
diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c
index fb2619f93d84..dd194dc80ee9 100644
--- a/drivers/tty/serial/s5pv210.c
+++ b/drivers/tty/serial/s5pv210.c
@@ -30,7 +30,7 @@ static int s5pv210_serial_setsource(struct uart_port *port,
struct s3c2410_uartcfg *cfg = port->dev->platform_data;
unsigned long ucon = rd_regl(port, S3C2410_UCON);
- if ((cfg->clocks_size) == 1)
+ if (cfg->flags & NO_NEED_CHECK_CLKSRC)
return 0;
if (strcmp(clk->name, "pclk") == 0)
@@ -55,7 +55,7 @@ static int s5pv210_serial_getsource(struct uart_port *port,
clk->divisor = 1;
- if ((cfg->clocks_size) == 1)
+ if (cfg->flags & NO_NEED_CHECK_CLKSRC)
return 0;
switch (ucon & S5PV210_UCON_CLKMASK) {
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index 5d01d32e2cf0..ef925d581713 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -555,7 +555,7 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
static int tty_ldisc_wait_idle(struct tty_struct *tty)
{
int ret;
- ret = wait_event_interruptible_timeout(tty_ldisc_idle,
+ ret = wait_event_timeout(tty_ldisc_idle,
atomic_read(&tty->ldisc->users) == 1, 5 * HZ);
if (ret < 0)
return ret;
@@ -763,6 +763,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;
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index aa3cc465a601..34e3da5aa72a 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1187,13 +1187,22 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
for (i = n - 1; i >= 0; --i) {
intf = udev->actconfig->interface[i];
status = usb_suspend_interface(udev, intf, msg);
+
+ /* Ignore errors during system sleep transitions */
+ if (!(msg.event & PM_EVENT_AUTO))
+ status = 0;
if (status != 0)
break;
}
}
- if (status == 0)
+ if (status == 0) {
status = usb_suspend_device(udev, msg);
+ /* Again, ignore errors during system sleep transitions */
+ if (!(msg.event & PM_EVENT_AUTO))
+ status = 0;
+ }
+
/* If the suspend failed, resume interfaces that did get suspended */
if (status != 0) {
msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 90ae1753dda1..a428aa080a36 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1634,6 +1634,7 @@ void usb_disconnect(struct usb_device **pdev)
{
struct usb_device *udev = *pdev;
int i;
+ struct usb_hcd *hcd = bus_to_hcd(udev->bus);
if (!udev) {
pr_debug ("%s nodev\n", __func__);
@@ -1661,7 +1662,9 @@ void usb_disconnect(struct usb_device **pdev)
* so that the hardware is now fully quiesced.
*/
dev_dbg (&udev->dev, "unregistering device\n");
+ mutex_lock(hcd->bandwidth_mutex);
usb_disable_device(udev, 0);
+ mutex_unlock(hcd->bandwidth_mutex);
usb_hcd_synchronize_unlinks(udev);
usb_remove_ep_devs(&udev->ep0);
@@ -2362,6 +2365,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
USB_DEVICE_REMOTE_WAKEUP, 0,
NULL, 0,
USB_CTRL_SET_TIMEOUT);
+
+ /* System sleep transitions should never fail */
+ if (!(msg.event & PM_EVENT_AUTO))
+ status = 0;
} else {
/* device has up to 10 msec to fully suspend */
dev_dbg(&udev->dev, "usb %ssuspend\n",
@@ -2611,16 +2618,15 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
struct usb_device *hdev = hub->hdev;
unsigned port1;
- /* fail if children aren't already suspended */
+ /* Warn if children aren't already suspended */
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
struct usb_device *udev;
udev = hdev->children [port1-1];
if (udev && udev->can_submit) {
- if (!(msg.event & PM_EVENT_AUTO))
- dev_dbg(&intf->dev, "port %d nyet suspended\n",
- port1);
- return -EBUSY;
+ dev_warn(&intf->dev, "port %d nyet suspended\n", port1);
+ if (msg.event & PM_EVENT_AUTO)
+ return -EBUSY;
}
}
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 5701e857392b..64c7ab4702df 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1135,10 +1135,13 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,
* Deallocates hcd/hardware state for the endpoints (nuking all or most
* pending urbs) and usbcore state for the interfaces, so that usbcore
* must usb_set_configuration() before any interfaces could be used.
+ *
+ * Must be called with hcd->bandwidth_mutex held.
*/
void usb_disable_device(struct usb_device *dev, int skip_ep0)
{
int i;
+ struct usb_hcd *hcd = bus_to_hcd(dev->bus);
/* getting rid of interfaces will disconnect
* any drivers bound to them (a key side effect)
@@ -1172,6 +1175,16 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
skip_ep0 ? "non-ep0" : "all");
+ if (hcd->driver->check_bandwidth) {
+ /* First pass: Cancel URBs, leave endpoint pointers intact. */
+ for (i = skip_ep0; i < 16; ++i) {
+ usb_disable_endpoint(dev, i, false);
+ usb_disable_endpoint(dev, i + USB_DIR_IN, false);
+ }
+ /* Remove endpoints from the host controller internal state */
+ usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
+ /* Second pass: remove endpoint pointers */
+ }
for (i = skip_ep0; i < 16; ++i) {
usb_disable_endpoint(dev, i, true);
usb_disable_endpoint(dev, i + USB_DIR_IN, true);
@@ -1727,6 +1740,7 @@ free_interfaces:
/* if it's already configured, clear out old state first.
* getting rid of old interfaces means unbinding their drivers.
*/
+ mutex_lock(hcd->bandwidth_mutex);
if (dev->state != USB_STATE_ADDRESS)
usb_disable_device(dev, 1); /* Skip ep0 */
@@ -1739,7 +1753,6 @@ free_interfaces:
* host controller will not allow submissions to dropped endpoints. If
* this call fails, the device state is unchanged.
*/
- mutex_lock(hcd->bandwidth_mutex);
ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
if (ret < 0) {
mutex_unlock(hcd->bandwidth_mutex);
diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c
index 98cc8a13169c..aa248c2f2c60 100644
--- a/drivers/usb/host/ehci-ath79.c
+++ b/drivers/usb/host/ehci-ath79.c
@@ -44,7 +44,6 @@ static int ehci_ath79_init(struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
struct platform_device *pdev = to_platform_device(hcd->self.controller);
const struct platform_device_id *id;
- int hclength;
int ret;
id = platform_get_device_id(pdev);
@@ -53,20 +52,23 @@ static int ehci_ath79_init(struct usb_hcd *hcd)
return -EINVAL;
}
- hclength = HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
switch (id->driver_data) {
case EHCI_ATH79_IP_V1:
ehci->has_synopsys_hc_bug = 1;
ehci->caps = hcd->regs;
- ehci->regs = hcd->regs + hclength;
+ ehci->regs = hcd->regs +
+ HC_LENGTH(ehci,
+ ehci_readl(ehci, &ehci->caps->hc_capbase));
break;
case EHCI_ATH79_IP_V2:
hcd->has_tt = 1;
ehci->caps = hcd->regs + 0x100;
- ehci->regs = hcd->regs + 0x100 + hclength;
+ ehci->regs = hcd->regs + 0x100 +
+ HC_LENGTH(ehci,
+ ehci_readl(ehci, &ehci->caps->hc_capbase));
break;
default:
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index b435ed67dd5c..f8030ee928e8 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1,4 +1,8 @@
/*
+ * Enhanced Host Controller Interface (EHCI) driver for USB.
+ *
+ * Maintainer: Alan Stern <stern@rowland.harvard.edu>
+ *
* Copyright (c) 2000-2004 by David Brownell
*
* This program is free software; you can redistribute it and/or modify it
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index c9e6e454c625..55d3d5859ac5 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -1555,7 +1555,7 @@ static void kill_transfer(struct usb_hcd *hcd, struct urb *urb,
/* We need to forcefully reclaim the slot since some transfers never
return, e.g. interrupt transfers and NAKed bulk transfers. */
- if (usb_pipebulk(urb->pipe)) {
+ if (usb_pipecontrol(urb->pipe) || usb_pipebulk(urb->pipe)) {
skip_map = reg_read32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG);
skip_map |= (1 << qh->slot);
reg_write32(hcd->regs, HC_ATL_PTD_SKIPMAP_REG, skip_map);
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 9aa10bdf3918..f9cf3f04b742 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1,5 +1,7 @@
/*
- * OHCI HCD (Host Controller Driver) for USB.
+ * Open Host Controller Interface (OHCI) driver for USB.
+ *
+ * Maintainer: Alan Stern <stern@rowland.harvard.edu>
*
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
* (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c
index db6f8b9c19b6..4586369dda00 100644
--- a/drivers/usb/host/r8a66597-hcd.c
+++ b/drivers/usb/host/r8a66597-hcd.c
@@ -2517,6 +2517,7 @@ static int __devinit r8a66597_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&r8a66597->child_device);
hcd->rsrc_start = res->start;
+ hcd->has_tt = 1;
ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | irq_trigger);
if (ret != 0) {
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 0f8e1d29a858..fcb7f7efc86d 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1215,8 +1215,6 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet));
/* dig out max burst from ep companion desc */
max_packet = ep->ss_ep_comp.bMaxBurst;
- if (!max_packet)
- xhci_warn(xhci, "WARN no SS endpoint bMaxBurst\n");
ep_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(max_packet));
break;
case USB_SPEED_HIGH:
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 17541d09eabb..cb16de213f64 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -29,6 +29,9 @@
#define PCI_VENDOR_ID_FRESCO_LOGIC 0x1b73
#define PCI_DEVICE_ID_FRESCO_LOGIC_PDK 0x1000
+#define PCI_VENDOR_ID_ETRON 0x1b6f
+#define PCI_DEVICE_ID_ASROCK_P67 0x7023
+
static const char hcd_name[] = "xhci_hcd";
/* called after powerup, by probe or system-pm "wakeup" */
@@ -134,6 +137,11 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
xhci->quirks |= XHCI_EP_LIMIT_QUIRK;
xhci->limit_active_eps = 64;
}
+ if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
+ pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
+ xhci->quirks |= XHCI_RESET_ON_RESUME;
+ xhci_dbg(xhci, "QUIRK: Resetting on resume\n");
+ }
/* Make sure the HC is halted. */
retval = xhci_halt(xhci);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 800f417c7309..70cacbbe7fb9 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1733,6 +1733,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
frame->status = -EOVERFLOW;
skip_td = true;
break;
+ case COMP_DEV_ERR:
case COMP_STALL:
frame->status = -EPROTO;
skip_td = true;
@@ -1767,9 +1768,6 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
}
}
- if ((idx == urb_priv->length - 1) && *status == -EINPROGRESS)
- *status = 0;
-
return finish_td(xhci, td, event_trb, event, ep, status, false);
}
@@ -1787,8 +1785,7 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
idx = urb_priv->td_cnt;
frame = &td->urb->iso_frame_desc[idx];
- /* The transfer is partly done */
- *status = -EXDEV;
+ /* The transfer is partly done. */
frame->status = -EXDEV;
/* calc actual length */
@@ -2016,6 +2013,10 @@ static int handle_tx_event(struct xhci_hcd *xhci,
TRB_TO_SLOT_ID(le32_to_cpu(event->flags)),
ep_index);
goto cleanup;
+ case COMP_DEV_ERR:
+ xhci_warn(xhci, "WARN: detect an incompatible device");
+ status = -EPROTO;
+ break;
case COMP_MISSED_INT:
/*
* When encounter missed service error, one or more isoc tds
@@ -2063,6 +2064,20 @@ static int handle_tx_event(struct xhci_hcd *xhci,
/* Is this a TRB in the currently executing TD? */
event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue,
td->last_trb, event_dma);
+
+ /*
+ * Skip the Force Stopped Event. The event_trb(event_dma) of FSE
+ * is not in the current TD pointed by ep_ring->dequeue because
+ * that the hardware dequeue pointer still at the previous TRB
+ * of the current TD. The previous TRB maybe a Link TD or the
+ * last TRB of the previous TD. The command completion handle
+ * will take care the rest.
+ */
+ if (!event_seg && trb_comp_code == COMP_STOP_INVAL) {
+ ret = 0;
+ goto cleanup;
+ }
+
if (!event_seg) {
if (!ep->skip ||
!usb_endpoint_xfer_isoc(&td->urb->ep->desc)) {
@@ -2158,6 +2173,11 @@ cleanup:
urb->transfer_buffer_length,
status);
spin_unlock(&xhci->lock);
+ /* EHCI, UHCI, and OHCI always unconditionally set the
+ * urb->status of an isochronous endpoint to 0.
+ */
+ if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
+ status = 0;
usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status);
spin_lock(&xhci->lock);
}
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 06e7023258d0..f5fe1ac301ab 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -759,6 +759,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
msleep(100);
spin_lock_irq(&xhci->lock);
+ if (xhci->quirks & XHCI_RESET_ON_RESUME)
+ hibernated = true;
if (!hibernated) {
/* step 1: restore register */
@@ -1401,6 +1403,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
u32 added_ctxs;
unsigned int last_ctx;
u32 new_add_flags, new_drop_flags, new_slot_info;
+ struct xhci_virt_device *virt_dev;
int ret = 0;
ret = xhci_check_args(hcd, udev, ep, 1, true, __func__);
@@ -1425,11 +1428,25 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
return 0;
}
- in_ctx = xhci->devs[udev->slot_id]->in_ctx;
- out_ctx = xhci->devs[udev->slot_id]->out_ctx;
+ virt_dev = xhci->devs[udev->slot_id];
+ in_ctx = virt_dev->in_ctx;
+ out_ctx = virt_dev->out_ctx;
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
ep_index = xhci_get_endpoint_index(&ep->desc);
ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
+
+ /* If this endpoint is already in use, and the upper layers are trying
+ * to add it again without dropping it, reject the addition.
+ */
+ if (virt_dev->eps[ep_index].ring &&
+ !(le32_to_cpu(ctrl_ctx->drop_flags) &
+ xhci_get_endpoint_flag(&ep->desc))) {
+ xhci_warn(xhci, "Trying to add endpoint 0x%x "
+ "without dropping it.\n",
+ (unsigned int) ep->desc.bEndpointAddress);
+ return -EINVAL;
+ }
+
/* If the HCD has already noted the endpoint is enabled,
* ignore this request.
*/
@@ -1445,8 +1462,7 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
* process context, not interrupt context (or so documenation
* for usb_set_interface() and usb_set_configuration() claim).
*/
- if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id],
- udev, ep, GFP_NOIO) < 0) {
+ if (xhci_endpoint_init(xhci, virt_dev, udev, ep, GFP_NOIO) < 0) {
dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n",
__func__, ep->desc.bEndpointAddress);
return -ENOMEM;
@@ -1537,6 +1553,11 @@ static int xhci_configure_endpoint_result(struct xhci_hcd *xhci,
"and endpoint is not disabled.\n");
ret = -EINVAL;
break;
+ case COMP_DEV_ERR:
+ dev_warn(&udev->dev, "ERROR: Incompatible device for endpoint "
+ "configure command.\n");
+ ret = -ENODEV;
+ break;
case COMP_SUCCESS:
dev_dbg(&udev->dev, "Successful Endpoint Configure command\n");
ret = 0;
@@ -1571,6 +1592,11 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
xhci_dbg_ctx(xhci, virt_dev->out_ctx, 1);
ret = -EINVAL;
break;
+ case COMP_DEV_ERR:
+ dev_warn(&udev->dev, "ERROR: Incompatible device for evaluate "
+ "context command.\n");
+ ret = -ENODEV;
+ break;
case COMP_MEL_ERR:
/* Max Exit Latency too large error */
dev_warn(&udev->dev, "WARN: Max Exit Latency too large\n");
@@ -2853,6 +2879,11 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
dev_warn(&udev->dev, "Device not responding to set address.\n");
ret = -EPROTO;
break;
+ case COMP_DEV_ERR:
+ dev_warn(&udev->dev, "ERROR: Incompatible device for address "
+ "device command.\n");
+ ret = -ENODEV;
+ break;
case COMP_SUCCESS:
xhci_dbg(xhci, "Successful Address Device command\n");
break;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 7d1ea3bf5e1f..d8bbf5ccb10d 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -874,6 +874,8 @@ struct xhci_transfer_event {
#define COMP_PING_ERR 20
/* Event Ring is full */
#define COMP_ER_FULL 21
+/* Incompatible Device Error */
+#define COMP_DEV_ERR 22
/* Missed Service Error - HC couldn't service an isoc ep within interval */
#define COMP_MISSED_INT 23
/* Successfully stopped command ring */
@@ -1308,6 +1310,7 @@ struct xhci_hcd {
*/
#define XHCI_EP_LIMIT_QUIRK (1 << 5)
#define XHCI_BROKEN_MSI (1 << 6)
+#define XHCI_RESET_ON_RESUME (1 << 7)
unsigned int num_active_eps;
unsigned int limit_active_eps;
/* There are two roothubs to keep track of bus suspend info for */
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 0a50a35e1853..6aeb363e63e7 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -1524,6 +1524,12 @@ static void musb_gadget_fifo_flush(struct usb_ep *ep)
csr = musb_readw(epio, MUSB_TXCSR);
if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
csr |= MUSB_TXCSR_FLUSHFIFO | MUSB_TXCSR_P_WZC_BITS;
+ /*
+ * Setting both TXPKTRDY and FLUSHFIFO makes controller
+ * to interrupt current FIFO loading, but not flushing
+ * the already loaded ones.
+ */
+ csr &= ~MUSB_TXCSR_TXPKTRDY;
musb_writew(epio, MUSB_TXCSR, csr);
/* REVISIT may be inappropriate w/o FIFONOTEMPTY ... */
musb_writew(epio, MUSB_TXCSR, csr);
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 7295e316bdfc..8b2473fa0f47 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1575,7 +1575,7 @@ void musb_host_rx(struct musb *musb, u8 epnum)
/* even if there was an error, we did the dma
* for iso_frame_desc->length
*/
- if (d->status != EILSEQ && d->status != -EOVERFLOW)
+ if (d->status != -EILSEQ && d->status != -EOVERFLOW)
d->status = 0;
if (++qh->iso_idx >= urb->number_of_packets)
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 162728977553..2e06b90aa1f8 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -179,6 +179,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_4232H_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_232H_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
@@ -848,7 +849,8 @@ static const char *ftdi_chip_name[] = {
[FT2232C] = "FT2232C",
[FT232RL] = "FT232RL",
[FT2232H] = "FT2232H",
- [FT4232H] = "FT4232H"
+ [FT4232H] = "FT4232H",
+ [FT232H] = "FT232H"
};
@@ -1168,6 +1170,7 @@ static __u32 get_ftdi_divisor(struct tty_struct *tty,
break;
case FT2232H: /* FT2232H chip */
case FT4232H: /* FT4232H chip */
+ case FT232H: /* FT232H chip */
if ((baud <= 12000000) & (baud >= 1200)) {
div_value = ftdi_2232h_baud_to_divisor(baud);
} else if (baud < 1200) {
@@ -1429,9 +1432,12 @@ static void ftdi_determine_type(struct usb_serial_port *port)
} else if (version < 0x600) {
/* Assume it's an FT232BM (or FT245BM) */
priv->chip_type = FT232BM;
- } else {
- /* Assume it's an FT232R */
+ } else if (version < 0x900) {
+ /* Assume it's an FT232RL */
priv->chip_type = FT232RL;
+ } else {
+ /* Assume it's an FT232H */
+ priv->chip_type = FT232H;
}
dev_info(&udev->dev, "Detected %s\n", ftdi_chip_name[priv->chip_type]);
}
@@ -1559,7 +1565,8 @@ static int create_sysfs_attrs(struct usb_serial_port *port)
priv->chip_type == FT2232C ||
priv->chip_type == FT232RL ||
priv->chip_type == FT2232H ||
- priv->chip_type == FT4232H)) {
+ priv->chip_type == FT4232H ||
+ priv->chip_type == FT232H)) {
retval = device_create_file(&port->dev,
&dev_attr_latency_timer);
}
@@ -1580,7 +1587,8 @@ static void remove_sysfs_attrs(struct usb_serial_port *port)
priv->chip_type == FT2232C ||
priv->chip_type == FT232RL ||
priv->chip_type == FT2232H ||
- priv->chip_type == FT4232H) {
+ priv->chip_type == FT4232H ||
+ priv->chip_type == FT232H) {
device_remove_file(&port->dev, &dev_attr_latency_timer);
}
}
@@ -2212,6 +2220,7 @@ static int ftdi_tiocmget(struct tty_struct *tty)
case FT232RL:
case FT2232H:
case FT4232H:
+ case FT232H:
len = 2;
break;
default:
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 213fe3d61282..19584faa86f9 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -156,7 +156,8 @@ enum ftdi_chip_type {
FT2232C = 4,
FT232RL = 5,
FT2232H = 6,
- FT4232H = 7
+ FT4232H = 7,
+ FT232H = 8
};
enum ftdi_sio_baudrate {
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index ab1fcdf3c378..19156d1049fe 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -22,6 +22,7 @@
#define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
#define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */
+#define FTDI_232H_PID 0x6014 /* Single channel hi-speed device */
#define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */
#define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index c6d92a530086..ea8445689c85 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -1745,6 +1745,7 @@ static int ti_download_firmware(struct ti_device *tdev)
}
if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size);
+ release_firmware(fw_p);
return -ENOENT;
}
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 5fc983c5b92c..cf03ad067147 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -447,6 +447,8 @@ static int clcdfb_register(struct clcd_fb *fb)
goto out;
}
+ fb->fb.device = &fb->dev->dev;
+
fb->fb.fix.mmio_start = fb->dev->res.start;
fb->fb.fix.mmio_len = resource_size(&fb->dev->res);
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index bedf5be27f05..0acc7d65aeaa 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -555,8 +555,6 @@ static void adjust_aoi_size_position(struct fb_var_screeninfo *var,
static int fsl_diu_check_var(struct fb_var_screeninfo *var,
struct fb_info *info)
{
- unsigned long htotal, vtotal;
-
pr_debug("check_var xres: %d\n", var->xres);
pr_debug("check_var yres: %d\n", var->yres);
@@ -635,20 +633,6 @@ static int fsl_diu_check_var(struct fb_var_screeninfo *var,
break;
}
- /* If the pixclock is below the minimum spec'd value then set to
- * refresh rate for 60Hz since this is supported by most monitors.
- * Refer to Documentation/fb/ for calculations.
- */
- if ((var->pixclock < MIN_PIX_CLK) || (var->pixclock > MAX_PIX_CLK)) {
- htotal = var->xres + var->right_margin + var->hsync_len +
- var->left_margin;
- vtotal = var->yres + var->lower_margin + var->vsync_len +
- var->upper_margin;
- var->pixclock = (vtotal * htotal * 6UL) / 100UL;
- var->pixclock = KHZ2PICOS(var->pixclock);
- pr_debug("pixclock set for 60Hz refresh = %u ps\n",
- var->pixclock);
- }
var->height = -1;
var->width = -1;
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/geode/gx1fb_core.c
index c6b554f72c6d..5a5d0928df33 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/geode/gx1fb_core.c
@@ -29,7 +29,7 @@ static int crt_option = 1;
static char panel_option[32] = "";
/* Modes relevant to the GX1 (taken from modedb.c) */
-static const struct fb_videomode __initdata gx1_modedb[] = {
+static const struct fb_videomode __devinitdata gx1_modedb[] = {
/* 640x480-60 VESA */
{ NULL, 60, 640, 480, 39682, 48, 16, 33, 10, 96, 2,
0, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
@@ -195,7 +195,7 @@ static int gx1fb_blank(int blank_mode, struct fb_info *info)
return par->vid_ops->blank_display(info, blank_mode);
}
-static int __init gx1fb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
+static int __devinit gx1fb_map_video_memory(struct fb_info *info, struct pci_dev *dev)
{
struct geodefb_par *par = info->par;
unsigned gx_base;
@@ -268,7 +268,7 @@ static struct fb_ops gx1fb_ops = {
.fb_imageblit = cfb_imageblit,
};
-static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev)
+static struct fb_info * __devinit gx1fb_init_fbinfo(struct device *dev)
{
struct geodefb_par *par;
struct fb_info *info;
@@ -318,7 +318,7 @@ static struct fb_info * __init gx1fb_init_fbinfo(struct device *dev)
return info;
}
-static int __init gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int __devinit gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct geodefb_par *par;
struct fb_info *info;
@@ -382,7 +382,7 @@ static int __init gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *
return ret;
}
-static void gx1fb_remove(struct pci_dev *pdev)
+static void __devexit gx1fb_remove(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
struct geodefb_par *par = info->par;
@@ -441,7 +441,7 @@ static struct pci_driver gx1fb_driver = {
.name = "gx1fb",
.id_table = gx1fb_id_table,
.probe = gx1fb_probe,
- .remove = gx1fb_remove,
+ .remove = __devexit_p(gx1fb_remove),
};
static int __init gx1fb_init(void)
@@ -456,7 +456,7 @@ static int __init gx1fb_init(void)
return pci_register_driver(&gx1fb_driver);
}
-static void __exit gx1fb_cleanup(void)
+static void __devexit gx1fb_cleanup(void)
{
pci_unregister_driver(&gx1fb_driver);
}
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
index fbef15f7a218..614251a9af91 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/hecubafb.c
@@ -233,7 +233,7 @@ static int __devinit hecubafb_probe(struct platform_device *dev)
videomemory = vzalloc(videomemorysize);
if (!videomemory)
- return retval;
+ goto err_videomem_alloc;
info = framebuffer_alloc(sizeof(struct hecubafb_par), &dev->dev);
if (!info)
@@ -275,6 +275,7 @@ err_fbreg:
framebuffer_release(info);
err_fballoc:
vfree(videomemory);
+err_videomem_alloc:
module_put(board->owner);
return retval;
}
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index 9170c82b495c..cc7d7329dc15 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -218,7 +218,7 @@ static inline void meram_get_next_icb_addr(struct sh_mobile_meram_info *pdata,
icb_offset = 0xc0000000 | (cfg->current_reg << 23);
*icb_addr_y = icb_offset | (cfg->icb[0].marker_icb << 24);
- if ((*icb_addr_c) && is_nvcolor(cfg->pixelformat))
+ if (is_nvcolor(cfg->pixelformat))
*icb_addr_c = icb_offset | (cfg->icb[1].marker_icb << 24);
}
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index 87f0be1e78b5..6294dca95500 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -1664,7 +1664,7 @@ static void sm501fb_stop(struct sm501fb_info *info)
resource_size(info->regs_res));
}
-static int sm501fb_init_fb(struct fb_info *fb,
+static int __devinit sm501fb_init_fb(struct fb_info *fb,
enum sm501_controller head,
const char *fbname)
{
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index 52b0f3e8ccac..816a4fda04f5 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -1233,8 +1233,12 @@ static int dlfb_setup_modes(struct dlfb_data *dev,
if (dlfb_is_valid_mode(&info->monspecs.modedb[i], info))
fb_add_videomode(&info->monspecs.modedb[i],
&info->modelist);
- else /* if we've removed top/best mode */
- info->monspecs.misc &= ~FB_MISC_1ST_DETAIL;
+ else {
+ if (i == 0)
+ /* if we've removed top/best mode */
+ info->monspecs.misc
+ &= ~FB_MISC_1ST_DETAIL;
+ }
}
default_vmode = fb_find_best_display(&info->monspecs,
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index a99bbe86db13..501b3406c6d5 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -175,6 +175,7 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
static void vesafb_destroy(struct fb_info *info)
{
+ fb_dealloc_cmap(&info->cmap);
if (info->screen_base)
iounmap(info->screen_base);
release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size);
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 022f9eb0b7bf..9536d386bb38 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -535,8 +535,7 @@ config I6300ESB_WDT
config INTEL_SCU_WATCHDOG
bool "Intel SCU Watchdog for Mobile Platforms"
- depends on WATCHDOG
- depends on INTEL_SCU_IPC
+ depends on X86_MRST
---help---
Hardware driver for the watchdog time built into the Intel SCU
for Intel Mobile Platforms.
diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c
index 750bc5281d79..4ca5d40304b2 100644
--- a/drivers/watchdog/at32ap700x_wdt.c
+++ b/drivers/watchdog/at32ap700x_wdt.c
@@ -448,7 +448,7 @@ static void __exit at32_wdt_exit(void)
}
module_exit(at32_wdt_exit);
-MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
+MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
MODULE_DESCRIPTION("Watchdog driver for Atmel AT32AP700X");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c
index 29a7cd4b90c8..b146082bd85a 100644
--- a/drivers/watchdog/gef_wdt.c
+++ b/drivers/watchdog/gef_wdt.c
@@ -329,4 +329,4 @@ MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
MODULE_DESCRIPTION("GE watchdog driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
-MODULE_ALIAS("platform: gef_wdt");
+MODULE_ALIAS("platform:gef_wdt");
diff --git a/drivers/watchdog/intel_scu_watchdog.c b/drivers/watchdog/intel_scu_watchdog.c
index 919bdd16136f..ba4386066a42 100644
--- a/drivers/watchdog/intel_scu_watchdog.c
+++ b/drivers/watchdog/intel_scu_watchdog.c
@@ -42,7 +42,6 @@
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/sfi.h>
-#include <linux/types.h>
#include <asm/irq.h>
#include <asm/atomic.h>
#include <asm/intel_scu_ipc.h>
diff --git a/drivers/watchdog/mtx-1_wdt.c b/drivers/watchdog/mtx-1_wdt.c
index 1479dc4d6129..0430e093b1a0 100644
--- a/drivers/watchdog/mtx-1_wdt.c
+++ b/drivers/watchdog/mtx-1_wdt.c
@@ -66,23 +66,18 @@ static struct {
int default_ticks;
unsigned long inuse;
unsigned gpio;
- int gstate;
+ unsigned int gstate;
} mtx1_wdt_device;
static void mtx1_wdt_trigger(unsigned long unused)
{
- u32 tmp;
-
spin_lock(&mtx1_wdt_device.lock);
if (mtx1_wdt_device.running)
ticks--;
/* toggle wdt gpio */
- mtx1_wdt_device.gstate = ~mtx1_wdt_device.gstate;
- if (mtx1_wdt_device.gstate)
- gpio_direction_output(mtx1_wdt_device.gpio, 1);
- else
- gpio_direction_input(mtx1_wdt_device.gpio);
+ mtx1_wdt_device.gstate = !mtx1_wdt_device.gstate;
+ gpio_set_value(mtx1_wdt_device.gpio, mtx1_wdt_device.gstate);
if (mtx1_wdt_device.queue && ticks)
mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL);
@@ -105,7 +100,7 @@ static void mtx1_wdt_start(void)
if (!mtx1_wdt_device.queue) {
mtx1_wdt_device.queue = 1;
mtx1_wdt_device.gstate = 1;
- gpio_direction_output(mtx1_wdt_device.gpio, 1);
+ gpio_set_value(mtx1_wdt_device.gpio, 1);
mod_timer(&mtx1_wdt_device.timer, jiffies + MTX1_WDT_INTERVAL);
}
mtx1_wdt_device.running++;
@@ -120,7 +115,7 @@ static int mtx1_wdt_stop(void)
if (mtx1_wdt_device.queue) {
mtx1_wdt_device.queue = 0;
mtx1_wdt_device.gstate = 0;
- gpio_direction_output(mtx1_wdt_device.gpio, 0);
+ gpio_set_value(mtx1_wdt_device.gpio, 0);
}
ticks = mtx1_wdt_device.default_ticks;
spin_unlock_irqrestore(&mtx1_wdt_device.lock, flags);
@@ -214,6 +209,12 @@ static int __devinit mtx1_wdt_probe(struct platform_device *pdev)
int ret;
mtx1_wdt_device.gpio = pdev->resource[0].start;
+ ret = gpio_request_one(mtx1_wdt_device.gpio,
+ GPIOF_OUT_INIT_HIGH, "mtx1-wdt");
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to request gpio");
+ return ret;
+ }
spin_lock_init(&mtx1_wdt_device.lock);
init_completion(&mtx1_wdt_device.stop);
@@ -239,11 +240,13 @@ static int __devexit mtx1_wdt_remove(struct platform_device *pdev)
mtx1_wdt_device.queue = 0;
wait_for_completion(&mtx1_wdt_device.stop);
}
+
+ gpio_free(mtx1_wdt_device.gpio);
misc_deregister(&mtx1_wdt_misc);
return 0;
}
-static struct platform_driver mtx1_wdt = {
+static struct platform_driver mtx1_wdt_driver = {
.probe = mtx1_wdt_probe,
.remove = __devexit_p(mtx1_wdt_remove),
.driver.name = "mtx1-wdt",
@@ -252,12 +255,12 @@ static struct platform_driver mtx1_wdt = {
static int __init mtx1_wdt_init(void)
{
- return platform_driver_register(&mtx1_wdt);
+ return platform_driver_register(&mtx1_wdt_driver);
}
static void __exit mtx1_wdt_exit(void)
{
- platform_driver_unregister(&mtx1_wdt);
+ platform_driver_unregister(&mtx1_wdt_driver);
}
module_init(mtx1_wdt_init);
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c
index 8c4b2d5bb7da..871caea4e1c6 100644
--- a/drivers/watchdog/wm831x_wdt.c
+++ b/drivers/watchdog/wm831x_wdt.c
@@ -320,6 +320,11 @@ static int __devinit wm831x_wdt_probe(struct platform_device *pdev)
struct wm831x_watchdog_pdata *pdata;
int reg, ret;
+ if (wm831x) {
+ dev_err(&pdev->dev, "wm831x watchdog already registered\n");
+ return -EBUSY;
+ }
+
wm831x = dev_get_drvdata(pdev->dev.parent);
ret = wm831x_reg_read(wm831x, WM831X_WATCHDOG);