diff options
Diffstat (limited to 'drivers')
91 files changed, 844 insertions, 477 deletions
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 0ed85cac323..615996a36be 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c @@ -95,18 +95,6 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) return_ACPI_STATUS(status); } - if (sleep_state != ACPI_STATE_S5) { - /* - * Disable BM arbitration. This feature is contained within an - * optional register (PM2 Control), so ignore a BAD_ADDRESS - * exception. - */ - status = acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1); - if (ACPI_FAILURE(status) && (status != AE_BAD_ADDRESS)) { - return_ACPI_STATUS(status); - } - } - /* * 1) Disable/Clear all GPEs * 2) Enable all wakeup GPEs @@ -364,16 +352,6 @@ acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags) [ACPI_EVENT_POWER_BUTTON]. status_register_id, ACPI_CLEAR_STATUS); - /* - * Enable BM arbitration. This feature is contained within an - * optional register (PM2 Control), so ignore a BAD_ADDRESS - * exception. - */ - status = acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0); - if (ACPI_FAILURE(status) && (status != AE_BAD_ADDRESS)) { - return_ACPI_STATUS(status); - } - acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 23ce0968641..fe662603549 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -638,7 +638,7 @@ acpi_ns_check_package(struct acpi_predefined_data *data, /* Create the new outer package and populate it */ status = - acpi_ns_wrap_with_package(data, *elements, + acpi_ns_wrap_with_package(data, return_object, return_object_ptr); if (ACPI_FAILURE(status)) { return (status); diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index c850de4c9a1..eff722278ff 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -189,10 +189,12 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) * Processor (CPU3, 0x03, 0x00000410, 0x06) {} * } * - * Ignores apic_id and always return 0 for CPU0's handle. + * Ignores apic_id and always returns 0 for the processor + * handle with acpi id 0 if nr_cpu_ids is 1. + * This should be the case if SMP tables are not found. * Return -1 for other CPU's handle. */ - if (acpi_id == 0) + if (nr_cpu_ids <= 1 && acpi_id == 0) return acpi_id; else return apic_id; diff --git a/drivers/block/loop.c b/drivers/block/loop.c index bbca966f8f6..3bba65510d2 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1597,14 +1597,12 @@ static int loop_add(struct loop_device **l, int i) struct gendisk *disk; int err; + err = -ENOMEM; lo = kzalloc(sizeof(*lo), GFP_KERNEL); - if (!lo) { - err = -ENOMEM; + if (!lo) goto out; - } - err = idr_pre_get(&loop_index_idr, GFP_KERNEL); - if (err < 0) + if (!idr_pre_get(&loop_index_idr, GFP_KERNEL)) goto out_free_dev; if (i >= 0) { diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c4067d0141f..542f0c04b69 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -136,7 +136,7 @@ config GPIO_MPC8XXX config GPIO_MSM_V1 tristate "Qualcomm MSM GPIO v1" - depends on GPIOLIB && ARCH_MSM + depends on GPIOLIB && ARCH_MSM && (ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50) help Say yes here to support the GPIO interface on ARM v6 based Qualcomm MSM chips. Most of the pins on the MSM can be diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index 9e9947cb86a..1077754f828 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -98,6 +98,7 @@ int devm_gpio_request_one(struct device *dev, unsigned gpio, return 0; } +EXPORT_SYMBOL(devm_gpio_request_one); /** * devm_gpio_free - free an interrupt diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index c337143b18f..c89c4c1e668 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -398,10 +398,12 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) writel(~0, port->base + GPIO_ISR); if (mxc_gpio_hwtype == IMX21_GPIO) { - /* setup one handler for all GPIO interrupts */ - if (pdev->id == 0) - irq_set_chained_handler(port->irq, - mx2_gpio_irq_handler); + /* + * Setup one handler for all GPIO interrupts. Actually setting + * the handler is needed only once, but doing it for every port + * is more robust and easier. + */ + irq_set_chained_handler(port->irq, mx2_gpio_irq_handler); } else { /* setup one handler for each entry */ irq_set_chained_handler(port->irq, mx3_gpio_irq_handler); diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index c4ed1722734..4fbc208c32c 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -174,12 +174,22 @@ static inline void _gpio_dbck_enable(struct gpio_bank *bank) if (bank->dbck_enable_mask && !bank->dbck_enabled) { clk_enable(bank->dbck); bank->dbck_enabled = true; + + __raw_writel(bank->dbck_enable_mask, + bank->base + bank->regs->debounce_en); } } static inline void _gpio_dbck_disable(struct gpio_bank *bank) { if (bank->dbck_enable_mask && bank->dbck_enabled) { + /* + * Disable debounce before cutting it's clock. If debounce is + * enabled but the clock is not, GPIO module seems to be unable + * to detect events and generate interrupts at least on OMAP3. + */ + __raw_writel(0, bank->base + bank->regs->debounce_en); + clk_disable(bank->dbck); bank->dbck_enabled = false; } @@ -1081,7 +1091,6 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) bank->is_mpuio = pdata->is_mpuio; bank->non_wakeup_gpios = pdata->non_wakeup_gpios; bank->loses_context = pdata->loses_context; - bank->get_context_loss_count = pdata->get_context_loss_count; bank->regs = pdata->regs; #ifdef CONFIG_OF_GPIO bank->chip.of_node = of_node_get(node); @@ -1135,6 +1144,9 @@ static int __devinit omap_gpio_probe(struct platform_device *pdev) omap_gpio_chip_init(bank); omap_gpio_show_rev(bank); + if (bank->loses_context) + bank->get_context_loss_count = pdata->get_context_loss_count; + pm_runtime_put(bank->dev); list_add_tail(&bank->node, &omap_gpio_list); diff --git a/drivers/gpio/gpio-sta2x11.c b/drivers/gpio/gpio-sta2x11.c index 38416be8ba1..6064fb376e1 100644 --- a/drivers/gpio/gpio-sta2x11.c +++ b/drivers/gpio/gpio-sta2x11.c @@ -383,8 +383,9 @@ static int __devinit gsta_probe(struct platform_device *dev) } spin_lock_init(&chip->lock); gsta_gpio_setup(chip); - for (i = 0; i < GSTA_NR_GPIO; i++) - gsta_set_config(chip, i, gpio_pdata->pinconfig[i]); + if (gpio_pdata) + for (i = 0; i < GSTA_NR_GPIO; i++) + gsta_set_config(chip, i, gpio_pdata->pinconfig[i]); /* 384 was used in previous code: be compatible for other drivers */ err = irq_alloc_descs(-1, 384, GSTA_NR_GPIO, NUMA_NO_NODE); diff --git a/drivers/gpio/gpio-tps65910.c b/drivers/gpio/gpio-tps65910.c index c1ad2884f2e..11f29c82253 100644 --- a/drivers/gpio/gpio-tps65910.c +++ b/drivers/gpio/gpio-tps65910.c @@ -149,6 +149,9 @@ static int __devinit tps65910_gpio_probe(struct platform_device *pdev) tps65910_gpio->gpio_chip.set = tps65910_gpio_set; tps65910_gpio->gpio_chip.get = tps65910_gpio_get; tps65910_gpio->gpio_chip.dev = &pdev->dev; +#ifdef CONFIG_OF_GPIO + tps65910_gpio->gpio_chip.of_node = tps65910->dev->of_node; +#endif if (pdata && pdata->gpio_base) tps65910_gpio->gpio_chip.base = pdata->gpio_base; else diff --git a/drivers/gpio/gpio-wm8994.c b/drivers/gpio/gpio-wm8994.c index 92ea5350dfe..aa61ad2fcaa 100644 --- a/drivers/gpio/gpio-wm8994.c +++ b/drivers/gpio/gpio-wm8994.c @@ -89,8 +89,11 @@ static int wm8994_gpio_direction_out(struct gpio_chip *chip, struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); struct wm8994 *wm8994 = wm8994_gpio->wm8994; + if (value) + value = WM8994_GPN_LVL; + return wm8994_set_bits(wm8994, WM8994_GPIO_1 + offset, - WM8994_GPN_DIR, 0); + WM8994_GPN_DIR | WM8994_GPN_LVL, value); } static void wm8994_gpio_set(struct gpio_chip *chip, unsigned offset, int value) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index fa10f847f7d..585344b6d33 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -517,6 +517,12 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS), .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), + .driver_data = APPLE_HAS_FN }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), + .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 6ac0286b537..4c87276c8dd 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1503,6 +1503,9 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, @@ -1995,6 +1998,7 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MCT) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HYBRID) }, { HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HEATCONTROL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_BEATPAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) }, { HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) }, @@ -2089,6 +2093,9 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING7_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { } diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index d1cdd2d2840..875ff451842 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -125,6 +125,9 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c #define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d #define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e +#define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 +#define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 +#define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b @@ -518,6 +521,9 @@ #define USB_DEVICE_ID_CRYSTALTOUCH 0x0006 #define USB_DEVICE_ID_CRYSTALTOUCH_DUAL 0x0007 +#define USB_VENDOR_ID_MADCATZ 0x0738 +#define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 + #define USB_VENDOR_ID_MCC 0x09db #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index e7701d99f8e..f1de3979181 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -2341,7 +2341,7 @@ static void __devinit it87_init_device(struct platform_device *pdev) /* Start monitoring */ it87_write_value(data, IT87_REG_CONFIG, - (it87_read_value(data, IT87_REG_CONFIG) & 0x36) + (it87_read_value(data, IT87_REG_CONFIG) & 0x3e) | (update_vbat ? 0x41 : 0x01)); } diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index 61c9cf15fa5..1201a15784c 100644 --- a/drivers/hwspinlock/hwspinlock_core.c +++ b/drivers/hwspinlock/hwspinlock_core.c @@ -345,7 +345,7 @@ int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev, spin_lock_init(&hwlock->lock); hwlock->bank = bank; - ret = hwspin_lock_register_single(hwlock, i); + ret = hwspin_lock_register_single(hwlock, base_id + i); if (ret) goto reg_failed; } @@ -354,7 +354,7 @@ int hwspin_lock_register(struct hwspinlock_device *bank, struct device *dev, reg_failed: while (--i >= 0) - hwspin_lock_unregister_single(i); + hwspin_lock_unregister_single(base_id + i); return ret; } EXPORT_SYMBOL_GPL(hwspin_lock_register); diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index ee16fb67b7a..83811e45d63 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -142,6 +142,7 @@ static const struct xpad_device { { 0x0c12, 0x880a, "Pelican Eclipse PL-2023", 0, XTYPE_XBOX }, { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, + { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, { 0x0e6f, 0x0003, "Logic3 Freebird wireless Controller", 0, XTYPE_XBOX }, @@ -164,6 +165,7 @@ static const struct xpad_device { { 0x1bad, 0x0003, "Harmonix Rock Band Drumkit", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, { 0x0f0d, 0x0016, "Hori Real Arcade Pro.EX", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, { 0x0f0d, 0x000d, "Hori Fighting Stick EX2", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX360 }, + { 0x1689, 0xfd00, "Razer Onza Tournament Edition", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX360 }, { 0xffff, 0xffff, "Chinese-made Xbox Controller", 0, XTYPE_XBOX }, { 0x0000, 0x0000, "Generic X-Box pad", 0, XTYPE_UNKNOWN } }; @@ -238,12 +240,14 @@ static struct usb_device_id xpad_table [] = { XPAD_XBOX360_VENDOR(0x045e), /* Microsoft X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x046d), /* Logitech X-Box 360 style controllers */ XPAD_XBOX360_VENDOR(0x0738), /* Mad Catz X-Box 360 controllers */ + { USB_DEVICE(0x0738, 0x4540) }, /* Mad Catz Beat Pad */ XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */ XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */ XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */ XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */ - XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ + XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */ + XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */ { } }; diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 2cf681d98c0..d528c23e194 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -79,6 +79,10 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253 #define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254 +/* MacbookPro10,1 (unibody, June 2012) */ +#define USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI 0x0262 +#define USB_DEVICE_ID_APPLE_WELLSPRING7_ISO 0x0263 +#define USB_DEVICE_ID_APPLE_WELLSPRING7_JIS 0x0264 #define BCM5974_DEVICE(prod) { \ .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ @@ -128,6 +132,10 @@ static const struct usb_device_id bcm5974_table[] = { BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS), + /* MacbookPro10,1 */ + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_ISO), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING7_JIS), /* Terminating entry */ {} }; @@ -354,6 +362,18 @@ static const struct bcm5974_config bcm5974_config_table[] = { { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } }, + { + USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI, + USB_DEVICE_ID_APPLE_WELLSPRING7_ISO, + USB_DEVICE_ID_APPLE_WELLSPRING7_JIS, + HAS_INTEGRATED_BUTTON, + 0x84, sizeof(struct bt_data), + 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, + { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, + { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, + { DIM_X, DIM_X / SN_COORD, -4750, 5280 }, + { DIM_Y, DIM_Y / SN_COORD, -150, 6730 } + }, {} }; diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index a2e418cba0f..625626391f2 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -83,6 +83,8 @@ static struct iommu_ops amd_iommu_ops; static ATOMIC_NOTIFIER_HEAD(ppr_notifier); int amd_iommu_max_glx_val = -1; +static struct dma_map_ops amd_iommu_dma_ops; + /* * general struct to manage commands send to an IOMMU */ @@ -402,7 +404,7 @@ static void amd_iommu_stats_init(void) return; de_fflush = debugfs_create_bool("fullflush", 0444, stats_dir, - (u32 *)&amd_iommu_unmap_flush); + &amd_iommu_unmap_flush); amd_iommu_stats_add(&compl_wait); amd_iommu_stats_add(&cnt_map_single); @@ -2267,6 +2269,13 @@ static int device_change_notifier(struct notifier_block *nb, list_add_tail(&dma_domain->list, &iommu_pd_list); spin_unlock_irqrestore(&iommu_pd_list_lock, flags); + dev_data = get_dev_data(dev); + + if (!dev_data->passthrough) + dev->archdata.dma_ops = &amd_iommu_dma_ops; + else + dev->archdata.dma_ops = &nommu_dma_ops; + break; case BUS_NOTIFY_DEL_DEVICE: diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 542024ba6db..a33612f3206 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -129,7 +129,7 @@ u16 amd_iommu_last_bdf; /* largest PCI device id we have to handle */ LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings we find in ACPI */ -bool amd_iommu_unmap_flush; /* if true, flush on every unmap */ +u32 amd_iommu_unmap_flush; /* if true, flush on every unmap */ LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the system */ @@ -1641,6 +1641,8 @@ static int __init amd_iommu_init(void) amd_iommu_init_api(); + x86_platform.iommu_shutdown = disable_iommus; + if (iommu_pass_through) goto out; @@ -1649,8 +1651,6 @@ static int __init amd_iommu_init(void) else printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n"); - x86_platform.iommu_shutdown = disable_iommus; - out: return ret; diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index 24355559a2a..c1b1d489817 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -652,7 +652,7 @@ extern unsigned long *amd_iommu_pd_alloc_bitmap; * If true, the addresses will be flushed on unmap time, not when * they are reused */ -extern bool amd_iommu_unmap_flush; +extern u32 amd_iommu_unmap_flush; /* Smallest number of PASIDs supported by any IOMMU in the system */ extern u32 amd_iommu_max_pasids; diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index ecd679043d7..3f3d09d560e 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -550,13 +550,13 @@ static int alloc_pdir(struct smmu_as *as) return 0; as->pte_count = devm_kzalloc(smmu->dev, - sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL); + sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_ATOMIC); if (!as->pte_count) { dev_err(smmu->dev, "failed to allocate smmu_device PTE cunters\n"); return -ENOMEM; } - as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA); + as->pdir_page = alloc_page(GFP_ATOMIC | __GFP_DMA); if (!as->pdir_page) { dev_err(smmu->dev, "failed to allocate smmu_device page directory\n"); diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 8c2754f835e..240ff312504 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2485,9 +2485,10 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipp */ if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { atomic_set(&r1_bio->remaining, read_targets); - for (i = 0; i < conf->raid_disks * 2; i++) { + for (i = 0; i < conf->raid_disks * 2 && read_targets; i++) { bio = r1_bio->bios[i]; if (bio->bi_end_io == end_sync_read) { + read_targets--; md_sync_acct(bio->bi_bdev, nr_sectors); generic_make_request(bio); } diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 00a67326c19..39eab73b01a 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c @@ -243,6 +243,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, if (minor == MAX_DVB_MINORS) { kfree(dvbdevfops); kfree(dvbdev); + up_write(&minor_rwsem); mutex_unlock(&dvbdev_register_lock); return -EINVAL; } diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 342c2c8c1dd..54ee34872d1 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -232,7 +232,7 @@ MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver"); static bool txandrx; /* default = 0 */ module_param(txandrx, bool, 0444); -MODULE_PARM_DESC(invert, "Allow simultaneous TX and RX"); +MODULE_PARM_DESC(txandrx, "Allow simultaneous TX and RX"); static unsigned int wake_sc = 0x800F040C; module_param(wake_sc, uint, 0644); @@ -1032,6 +1032,8 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) data->dev->tx_ir = wbcir_tx; data->dev->priv = data; data->dev->dev.parent = &device->dev; + data->dev->timeout = MS_TO_NS(100); + data->dev->allowed_protos = RC_TYPE_ALL; if (!request_region(data->wbase, WAKEUP_IOMEM_LEN, DRVNAME)) { dev_err(dev, "Region 0x%lx-0x%lx already in use!\n", diff --git a/drivers/media/video/cx231xx/cx231xx-audio.c b/drivers/media/video/cx231xx/cx231xx-audio.c index 068f78dc5d1..b4c99c7270c 100644 --- a/drivers/media/video/cx231xx/cx231xx-audio.c +++ b/drivers/media/video/cx231xx/cx231xx-audio.c @@ -307,7 +307,7 @@ static int cx231xx_init_audio_isoc(struct cx231xx *dev) urb->context = dev; urb->pipe = usb_rcvisocpipe(dev->udev, dev->adev.end_point_addr); - urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; + urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = dev->adev.transfer_buffer[i]; urb->interval = 1; urb->complete = cx231xx_audio_isocirq; @@ -368,7 +368,7 @@ static int cx231xx_init_audio_bulk(struct cx231xx *dev) urb->context = dev; urb->pipe = usb_rcvbulkpipe(dev->udev, dev->adev.end_point_addr); - urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; + urb->transfer_flags = 0; urb->transfer_buffer = dev->adev.transfer_buffer[i]; urb->complete = cx231xx_audio_bulkirq; urb->transfer_buffer_length = sb_size; diff --git a/drivers/media/video/cx231xx/cx231xx-vbi.c b/drivers/media/video/cx231xx/cx231xx-vbi.c index 3d15314e1f8..ac7db52f404 100644 --- a/drivers/media/video/cx231xx/cx231xx-vbi.c +++ b/drivers/media/video/cx231xx/cx231xx-vbi.c @@ -448,7 +448,7 @@ int cx231xx_init_vbi_isoc(struct cx231xx *dev, int max_packets, return -ENOMEM; } dev->vbi_mode.bulk_ctl.urb[i] = urb; - urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP; + urb->transfer_flags = 0; dev->vbi_mode.bulk_ctl.transfer_buffer[i] = kzalloc(sb_size, GFP_KERNEL); diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c index 13739e002a6..080e11157e5 100644 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ b/drivers/media/video/cx23885/cx23885-cards.c @@ -127,22 +127,37 @@ struct cx23885_board cx23885_boards[] = { }, [CX23885_BOARD_HAUPPAUGE_HVR1250] = { .name = "Hauppauge WinTV-HVR1250", + .porta = CX23885_ANALOG_VIDEO, .portc = CX23885_MPEG_DVB, +#ifdef MT2131_NO_ANALOG_SUPPORT_YET + .tuner_type = TUNER_PHILIPS_TDA8290, + .tuner_addr = 0x42, /* 0x84 >> 1 */ + .tuner_bus = 1, +#endif + .force_bff = 1, .input = {{ +#ifdef MT2131_NO_ANALOG_SUPPORT_YET .type = CX23885_VMUX_TELEVISION, - .vmux = 0, + .vmux = CX25840_VIN7_CH3 | + CX25840_VIN5_CH2 | + CX25840_VIN2_CH1, + .amux = CX25840_AUDIO8, .gpio0 = 0xff00, }, { - .type = CX23885_VMUX_DEBUG, - .vmux = 0, - .gpio0 = 0xff01, - }, { +#endif .type = CX23885_VMUX_COMPOSITE1, - .vmux = 1, + .vmux = CX25840_VIN7_CH3 | + CX25840_VIN4_CH2 | + CX25840_VIN6_CH1, + .amux = CX25840_AUDIO7, .gpio0 = 0xff02, }, { .type = CX23885_VMUX_SVIDEO, - .vmux = 2, + .vmux = CX25840_VIN7_CH3 | + CX25840_VIN4_CH2 | + CX25840_VIN8_CH1 | + CX25840_SVIDEO_ON, + .amux = CX25840_AUDIO7, .gpio0 = 0xff02, } }, }, @@ -267,7 +282,55 @@ struct cx23885_board cx23885_boards[] = { }, [CX23885_BOARD_HAUPPAUGE_HVR1255] = { .name = "Hauppauge WinTV-HVR1255", + .porta = CX23885_ANALOG_VIDEO, + .portc = CX23885_MPEG_DVB, + .tuner_type = TUNER_ABSENT, + .tuner_addr = 0x42, /* 0x84 >> 1 */ + .force_bff = 1, + .input = {{ + .type = CX23885_VMUX_TELEVISION, + .vmux = CX25840_VIN7_CH3 | + CX25840_VIN5_CH2 | + CX25840_VIN2_CH1 | + CX25840_DIF_ON, + .amux = CX25840_AUDIO8, + }, { + .type = CX23885_VMUX_COMPOSITE1, + .vmux = CX25840_VIN7_CH3 | + CX25840_VIN4_CH2 | + CX25840_VIN6_CH1, + .amux = CX25840_AUDIO7, + }, { + .type = CX23885_VMUX_SVIDEO, + .vmux = CX25840_VIN7_CH3 | + CX25840_VIN4_CH2 | + CX25840_VIN8_CH1 | + CX25840_SVIDEO_ON, + .amux = CX25840_AUDIO7, + } }, + }, + [CX23885_BOARD_HAUPPAUGE_HVR1255_22111] = { + .name = "Hauppauge WinTV-HVR1255", + .porta = CX23885_ANALOG_VIDEO, .portc = CX23885_MPEG_DVB, + .tuner_type = TUNER_ABSENT, + .tuner_addr = 0x42, /* 0x84 >> 1 */ + .force_bff = 1, + .input = {{ + .type = CX23885_VMUX_TELEVISION, + .vmux = CX25840_VIN7_CH3 | + CX25840_VIN5_CH2 | + CX25840_VIN2_CH1 | + CX25840_DIF_ON, + .amux = CX25840_AUDIO8, + }, { + .type = CX23885_VMUX_SVIDEO, + .vmux = CX25840_VIN7_CH3 | + CX25840_VIN4_CH2 | + CX25840_VIN8_CH1 | + CX25840_SVIDEO_ON, + .amux = CX25840_AUDIO7, + } }, }, [CX23885_BOARD_HAUPPAUGE_HVR1210] = { .name = "Hauppauge WinTV-HVR1210", @@ -624,7 +687,7 @@ struct cx23885_subid cx23885_subids[] = { }, { .subvendor = 0x0070, .subdevice = 0x2259, - .card = CX23885_BOARD_HAUPPAUGE_HVR1255, + .card = CX23885_BOARD_HAUPPAUGE_HVR1255_22111, }, { .subvendor = 0x0070, .subdevice = 0x2291, @@ -900,7 +963,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg) struct cx23885_dev *dev = port->dev; u32 bitmask = 0; - if (command == XC2028_RESET_CLK) + if ((command == XC2028_RESET_CLK) || (command == XC2028_I2C_FLUSH)) return 0; if (command != 0) { @@ -1130,6 +1193,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: + case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1210: /* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */ /* GPIO-6 I2C Gate which can isolate the demod from the bus */ @@ -1267,6 +1331,7 @@ int cx23885_ir_init(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1400: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: + case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1210: /* FIXME: Implement me */ break; @@ -1424,6 +1489,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: + case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1210: case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_HAUPPAUGE_HVR1290: @@ -1511,6 +1577,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1275: case CX23885_BOARD_HAUPPAUGE_HVR1255: + case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1210: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: case CX23885_BOARD_HAUPPAUGE_HVR1290: @@ -1526,10 +1593,10 @@ void cx23885_card_setup(struct cx23885_dev *dev) */ switch (dev->board) { case CX23885_BOARD_TEVII_S470: - case CX23885_BOARD_HAUPPAUGE_HVR1250: /* Currently only enabled for the integrated IR controller */ if (!enable_885_ir) break; + case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1800: case CX23885_BOARD_HAUPPAUGE_HVR1800lp: case CX23885_BOARD_HAUPPAUGE_HVR1700: @@ -1539,6 +1606,8 @@ void cx23885_card_setup(struct cx23885_dev *dev) case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: case CX23885_BOARD_COMPRO_VIDEOMATE_E800: + case CX23885_BOARD_HAUPPAUGE_HVR1255: + case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1270: case CX23885_BOARD_HAUPPAUGE_HVR1850: case CX23885_BOARD_MYGICA_X8506: diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index a80a92c4745..cd542684ba0 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -712,6 +712,7 @@ static int dvb_register(struct cx23885_tsport *port) } break; case CX23885_BOARD_HAUPPAUGE_HVR1255: + case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: i2c_bus = &dev->i2c_bus[0]; fe0->dvb.frontend = dvb_attach(s5h1411_attach, &hcw_s5h1411_config, @@ -721,6 +722,11 @@ static int dvb_register(struct cx23885_tsport *port) 0x60, &dev->i2c_bus[1].i2c_adap, &hauppauge_tda18271_config); } + + tda18271_attach(&dev->ts1.analog_fe, + 0x60, &dev->i2c_bus[1].i2c_adap, + &hauppauge_tda18271_config); + break; case CX23885_BOARD_HAUPPAUGE_HVR1800: i2c_bus = &dev->i2c_bus[0]; diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c index c654bdc7ccb..22f8e7fbd66 100644 --- a/drivers/media/video/cx23885/cx23885-video.c +++ b/drivers/media/video/cx23885/cx23885-video.c @@ -505,6 +505,9 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1800) || (dev->board == CX23885_BOARD_MPX885) || + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1250) || + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850)) { /* Configure audio routing */ v4l2_subdev_call(dev->sd_cx25840, audio, s_routing, @@ -1578,7 +1581,9 @@ static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, fe = vfe->dvb.frontend; - if (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) + if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || + (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111)) fe = &dev->ts1.analog_fe; if (fe && fe->ops.tuner_ops.set_analog_params) { @@ -1608,6 +1613,8 @@ int cx23885_set_frequency(struct file *file, void *priv, int ret; switch (dev->board) { + case CX23885_BOARD_HAUPPAUGE_HVR1255: + case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: case CX23885_BOARD_HAUPPAUGE_HVR1850: ret = cx23885_set_freq_via_ops(dev, f); break; diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h index d884784a1c8..13c37ec07ae 100644 --- a/drivers/media/video/cx23885/cx23885.h +++ b/drivers/media/video/cx23885/cx23885.h @@ -90,6 +90,7 @@ #define CX23885_BOARD_MYGICA_X8507 33 #define CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL 34 #define CX23885_BOARD_TEVII_S471 35 +#define CX23885_BOARD_HAUPPAUGE_HVR1255_22111 36 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index fc1ff69cffd..d8eac3e30a7 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -84,7 +84,7 @@ MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]"); /* ----------------------------------------------------------------------- */ -static void cx23885_std_setup(struct i2c_client *client); +static void cx23888_std_setup(struct i2c_client *client); int cx25840_write(struct i2c_client *client, u16 addr, u8 value) { @@ -638,10 +638,13 @@ static void cx23885_initialize(struct i2c_client *client) finish_wait(&state->fw_wait, &wait); destroy_workqueue(q); - /* Call the cx23885 specific std setup func, we no longer rely on + /* Call the cx23888 specific std setup func, we no longer rely on * the generic cx24840 func. */ - cx23885_std_setup(client); + if (is_cx23888(state)) + cx23888_std_setup(client); + else + cx25840_std_setup(client); /* (re)set input */ set_input(client, state->vid_input, state->aud_input); @@ -1103,9 +1106,23 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp cx25840_write4(client, 0x410, 0xffff0dbf); cx25840_write4(client, 0x414, 0x00137d03); - cx25840_write4(client, 0x418, 0x01008080); + + /* on the 887, 0x418 is HSCALE_CTRL, on the 888 it is + CHROMA_CTRL */ + if (is_cx23888(state)) + cx25840_write4(client, 0x418, 0x01008080); + else + cx25840_write4(client, 0x418, 0x01000000); + cx25840_write4(client, 0x41c, 0x00000000); - cx25840_write4(client, 0x420, 0x001c3e0f); + + /* on the 887, 0x420 is CHROMA_CTRL, on the 888 it is + CRUSH_CTRL */ + if (is_cx23888(state)) + cx25840_write4(client, 0x420, 0x001c3e0f); + else + cx25840_write4(client, 0x420, 0x001c8282); + cx25840_write4(client, 0x42c, 0x42600000); cx25840_write4(client, 0x430, 0x0000039b); cx25840_write4(client, 0x438, 0x00000000); @@ -1233,7 +1250,7 @@ static int set_input(struct i2c_client *client, enum cx25840_video_input vid_inp cx25840_write4(client, 0x8d0, 0x1f063870); } - if (is_cx2388x(state)) { + if (is_cx23888(state)) { /* HVR1850 */ /* AUD_IO_CTRL - I2S Input, Parallel1*/ /* - Channel 1 src - Parallel1 (Merlin out) */ @@ -1298,8 +1315,8 @@ static int set_v4lstd(struct i2c_client *client) } cx25840_and_or(client, 0x400, ~0xf, fmt); cx25840_and_or(client, 0x403, ~0x3, pal_m); - if (is_cx2388x(state)) - cx23885_std_setup(client); + if (is_cx23888(state)) + cx23888_std_setup(client); else cx25840_std_setup(client); if (!is_cx2583x(state)) @@ -1312,6 +1329,7 @@ static int set_v4lstd(struct i2c_client *client) static int cx25840_s_ctrl(struct v4l2_ctrl *ctrl) { struct v4l2_subdev *sd = to_sd(ctrl); + struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); switch (ctrl->id) { @@ -1324,12 +1342,20 @@ static int cx25840_s_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_SATURATION: - cx25840_write(client, 0x420, ctrl->val << 1); - cx25840_write(client, 0x421, ctrl->val << 1); + if (is_cx23888(state)) { + cx25840_write(client, 0x418, ctrl->val << 1); + cx25840_write(client, 0x419, ctrl->val << 1); + } else { + cx25840_write(client, 0x420, ctrl->val << 1); + cx25840_write(client, 0x421, ctrl->val << 1); + } break; case V4L2_CID_HUE: - cx25840_write(client, 0x422, ctrl->val); + if (is_cx23888(state)) + cx25840_write(client, 0x41a, ctrl->val); + else + cx25840_write(client, 0x422, ctrl->val); break; default: @@ -1354,11 +1380,21 @@ static int cx25840_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt fmt->field = V4L2_FIELD_INTERLACED; fmt->colorspace = V4L2_COLORSPACE_SMPTE170M; - Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4; - Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4; + if (is_cx23888(state)) { + Vsrc = (cx25840_read(client, 0x42a) & 0x3f) << 4; + Vsrc |= (cx25840_read(client, 0x429) & 0xf0) >> 4; + } else { + Vsrc = (cx25840_read(client, 0x476) & 0x3f) << 4; + Vsrc |= (cx25840_read(client, 0x475) & 0xf0) >> 4; + } - Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4; - Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; + if (is_cx23888(state)) { + Hsrc = (cx25840_read(client, 0x426) & 0x3f) << 4; + Hsrc |= (cx25840_read(client, 0x425) & 0xf0) >> 4; + } else { + Hsrc = (cx25840_read(client, 0x472) & 0x3f) << 4; + Hsrc |= (cx25840_read(client, 0x471) & 0xf0) >> 4; + } Vlines = fmt->height + (is_50Hz ? 4 : 7); @@ -1782,8 +1818,8 @@ static int cx25840_s_video_routing(struct v4l2_subdev *sd, struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (is_cx2388x(state)) - cx23885_std_setup(client); + if (is_cx23888(state)) + cx23888_std_setup(client); return set_input(client, input, state->aud_input); } @@ -1794,8 +1830,8 @@ static int cx25840_s_audio_routing(struct v4l2_subdev *sd, struct cx25840_state *state = to_state(sd); struct i2c_client *client = v4l2_get_subdevdata(sd); - if (is_cx2388x(state)) - cx23885_std_setup(client); + if (is_cx23888(state)) + cx23888_std_setup(client); return set_input(client, state->vid_input, input); } @@ -4939,7 +4975,7 @@ void cx23885_dif_setup(struct i2c_client *client, u32 ifHz) } } -static void cx23885_std_setup(struct i2c_client *client) +static void cx23888_std_setup(struct i2c_client *client) { struct cx25840_state *state = to_state(i2c_get_clientdata(client)); v4l2_std_id std = state->std; diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 92da7c28b6f..862c6575c55 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -2893,7 +2893,7 @@ static void request_module_async(struct work_struct *work) if (dev->board.has_dvb) request_module("em28xx-dvb"); - if (dev->board.has_ir_i2c && !disable_ir) + if (dev->board.ir_codes && !disable_ir) request_module("em28xx-rc"); } diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index 6c31e46a1fd..b9c6f17eabb 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c @@ -2070,10 +2070,13 @@ static int sd_start(struct gspca_dev *gspca_dev) set_gamma(gspca_dev, v4l2_ctrl_g_ctrl(sd->gamma)); set_redblue(gspca_dev, v4l2_ctrl_g_ctrl(sd->blue), v4l2_ctrl_g_ctrl(sd->red)); - set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain)); - set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure)); - set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), - v4l2_ctrl_g_ctrl(sd->vflip)); + if (sd->gain) + set_gain(gspca_dev, v4l2_ctrl_g_ctrl(sd->gain)); + if (sd->exposure) + set_exposure(gspca_dev, v4l2_ctrl_g_ctrl(sd->exposure)); + if (sd->hflip) + set_hvflip(gspca_dev, v4l2_ctrl_g_ctrl(sd->hflip), + v4l2_ctrl_g_ctrl(sd->vflip)); reg_w1(gspca_dev, 0x1007, 0x20); reg_w1(gspca_dev, 0x1061, 0x03); @@ -2176,7 +2179,7 @@ static void sd_dqcallback(struct gspca_dev *gspca_dev) struct sd *sd = (struct sd *) gspca_dev; int avg_lum; - if (!v4l2_ctrl_g_ctrl(sd->autogain)) + if (sd->autogain == NULL || !v4l2_ctrl_g_ctrl(sd->autogain)) return; avg_lum = atomic_read(&sd->avg_lum); diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 41f9a254b24..637bde8aca2 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c @@ -83,6 +83,7 @@ #define CSICR1_INV_DATA (1 << 3) #define CSICR1_INV_PCLK (1 << 2) #define CSICR1_REDGE (1 << 1) +#define CSICR1_FMT_MASK (CSICR1_PACK_DIR | CSICR1_SWAP16_EN) #define SHIFT_STATFF_LEVEL 22 #define SHIFT_RXFF_LEVEL 19 @@ -230,6 +231,7 @@ struct mx2_prp_cfg { u32 src_pixel; u32 ch1_pixel; u32 irq_flags; + u32 csicr1; }; /* prp resizing parameters */ @@ -330,6 +332,7 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = { .ch1_pixel = 0x2ca00565, /* RGB565 */ .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH1WERR | PRP_INTR_CH1FC | PRP_INTR_LBOVF, + .csicr1 = 0, } }, { @@ -343,6 +346,21 @@ static struct mx2_fmt_cfg mx27_emma_prp_table[] = { .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR | PRP_INTR_CH2FC | PRP_INTR_LBOVF | PRP_INTR_CH2OVF, + .csicr1 = CSICR1_PACK_DIR, + } + }, + { + .in_fmt = V4L2_MBUS_FMT_UYVY8_2X8, + .out_fmt = V4L2_PIX_FMT_YUV420, + .cfg = { + .channel = 2, + .in_fmt = PRP_CNTL_DATA_IN_YUV422, + .out_fmt = PRP_CNTL_CH2_OUT_YUV420, + .src_pixel = 0x22000888, /* YUV422 (YUYV) */ + .irq_flags = PRP_INTR_RDERR | PRP_INTR_CH2WERR | + PRP_INTR_CH2FC | PRP_INTR_LBOVF | + PRP_INTR_CH2OVF, + .csicr1 = CSICR1_SWAP16_EN, } }, }; @@ -1015,14 +1033,14 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) return ret; } + csicr1 = (csicr1 & ~CSICR1_FMT_MASK) | pcdev->emma_prp->cfg.csicr1; + if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) csicr1 |= CSICR1_REDGE; if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) csicr1 |= CSICR1_SOF_POL; if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) csicr1 |= CSICR1_HSYNC_POL; - if (pcdev->platform_flags & MX2_CAMERA_SWAP16) - csicr1 |= CSICR1_SWAP16_EN; if (pcdev->platform_flags & MX2_CAMERA_EXT_VSYNC) csicr1 |= CSICR1_EXT_VSYNC; if (pcdev->platform_flags & MX2_CAMERA_CCIR) @@ -1033,8 +1051,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) csicr1 |= CSICR1_GCLK_MODE; if (pcdev->platform_flags & MX2_CAMERA_INV_DATA) csicr1 |= CSICR1_INV_DATA; - if (pcdev->platform_flags & MX2_CAMERA_PACK_DIR_MSB) - csicr1 |= CSICR1_PACK_DIR; pcdev->csicr1 = csicr1; @@ -1109,7 +1125,8 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, return 0; } - if (code == V4L2_MBUS_FMT_YUYV8_2X8) { + if (code == V4L2_MBUS_FMT_YUYV8_2X8 || + code == V4L2_MBUS_FMT_UYVY8_2X8) { formats++; if (xlate) { /* diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c index 8a4935ecc65..dd91da26f1b 100644 --- a/drivers/media/video/omap3isp/isppreview.c +++ b/drivers/media/video/omap3isp/isppreview.c @@ -888,12 +888,12 @@ static const struct preview_update update_attrs[] = { preview_config_contrast, NULL, offsetof(struct prev_params, contrast), - 0, true, + 0, 0, true, }, /* OMAP3ISP_PREV_BRIGHTNESS */ { preview_config_brightness, NULL, offsetof(struct prev_params, brightness), - 0, true, + 0, 0, true, }, }; @@ -1102,7 +1102,7 @@ static void preview_config_input_size(struct isp_prev_device *prev, u32 active) unsigned int elv = prev->crop.top + prev->crop.height - 1; u32 features; - if (format->code == V4L2_MBUS_FMT_Y10_1X10) { + if (format->code != V4L2_MBUS_FMT_Y10_1X10) { sph -= 2; eph += 2; slv -= 2; diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index c370c2d87c1..b4c679b3fb0 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -26,6 +26,7 @@ #include <linux/fs.h> #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/slab.h> #include <linux/ioport.h> #include <linux/init.h> #include <linux/mutex.h> diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 35457459190..725812aa0c3 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -350,7 +350,8 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt, if (pixm) sizes[i] = max(size, pixm->plane_fmt[i].sizeimage); else - sizes[i] = size; + sizes[i] = max_t(u32, size, frame->payload[i]); + allocators[i] = ctx->fimc_dev->alloc_ctx; } @@ -479,37 +480,39 @@ static int fimc_capture_set_default_format(struct fimc_dev *fimc); static int fimc_capture_open(struct file *file) { struct fimc_dev *fimc = video_drvdata(file); - int ret = v4l2_fh_open(file); - - if (ret) - return ret; + int ret; dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); - /* Return if the corresponding video mem2mem node is already opened. */ if (fimc_m2m_active(fimc)) return -EBUSY; set_bit(ST_CAPT_BUSY, &fimc->state); - pm_runtime_get_sync(&fimc->pdev->dev); + ret = pm_runtime_get_sync(&fimc->pdev->dev); + if (ret < 0) + return ret; - if (++fimc->vid_cap.refcnt == 1) { - ret = fimc_pipeline_initialize(&fimc->pipeline, - &fimc->vid_cap.vfd->entity, true); - if (ret < 0) { - dev_err(&fimc->pdev->dev, - "Video pipeline initialization failed\n"); - pm_runtime_put_sync(&fimc->pdev->dev); - fimc->vid_cap.refcnt--; - v4l2_fh_release(file); - clear_bit(ST_CAPT_BUSY, &fimc->state); - return ret; - } - ret = fimc_capture_ctrls_create(fimc); + ret = v4l2_fh_open(file); + if (ret) + return ret; - if (!ret && !fimc->vid_cap.user_subdev_api) - ret = fimc_capture_set_default_format(fimc); + if (++fimc->vid_cap.refcnt != 1) + return 0; + + ret = fimc_pipeline_initialize(&fimc->pipeline, + &fimc->vid_cap.vfd->entity, true); + if (ret < 0) { + clear_bit(ST_CAPT_BUSY, &fimc->state); + pm_runtime_put_sync(&fimc->pdev->dev); + fimc->vid_cap.refcnt--; + v4l2_fh_release(file); + return ret; } + ret = fimc_capture_ctrls_create(fimc); + + if (!ret && !fimc->vid_cap.user_subdev_api) + ret = fimc_capture_set_default_format(fimc); + return ret; } @@ -818,9 +821,6 @@ static int fimc_cap_g_fmt_mplane(struct file *file, void *fh, struct fimc_dev *fimc = video_drvdata(file); struct fimc_ctx *ctx = fimc->vid_cap.ctx; - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - return -EINVAL; - return fimc_fill_format(&ctx->d_frame, f); } @@ -833,9 +833,6 @@ static int fimc_cap_try_fmt_mplane(struct file *file, void *fh, struct v4l2_mbus_framefmt mf; struct fimc_fmt *ffmt = NULL; - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - return -EINVAL; - if (pix->pixelformat == V4L2_PIX_FMT_JPEG) { fimc_capture_try_format(ctx, &pix->width, &pix->height, NULL, &pix->pixelformat, @@ -887,8 +884,6 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f) struct fimc_fmt *s_fmt = NULL; int ret, i; - if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - return -EINVAL; if (vb2_is_busy(&fimc->vid_cap.vbq)) return -EBUSY; @@ -924,10 +919,10 @@ static int fimc_capture_set_format(struct fimc_dev *fimc, struct v4l2_format *f) pix->width = mf->width; pix->height = mf->height; } + fimc_adjust_mplane_format(ff->fmt, pix->width, pix->height, pix); for (i = 0; i < ff->fmt->colplanes; i++) - ff->payload[i] = - (pix->width * pix->height * ff->fmt->depth[i]) / 8; + ff->payload[i] = pix->plane_fmt[i].sizeimage; set_frame_bounds(ff, pix->width, pix->height); /* Reset the composition rectangle if not yet configured */ @@ -1045,18 +1040,22 @@ static int fimc_cap_streamon(struct file *file, void *priv, { struct fimc_dev *fimc = video_drvdata(file); struct fimc_pipeline *p = &fimc->pipeline; + struct v4l2_subdev *sd = p->subdevs[IDX_SENSOR]; int ret; if (fimc_capture_active(fimc)) return -EBUSY; - media_entity_pipeline_start(&p->subdevs[IDX_SENSOR]->entity, - p->m_pipeline); + ret = media_entity_pipeline_start(&sd->entity, p->m_pipeline); + if (ret < 0) + return ret; if (fimc->vid_cap.user_subdev_api) { ret = fimc_pipeline_validate(fimc); - if (ret) + if (ret < 0) { + media_entity_pipeline_stop(&sd->entity); return ret; + } } return vb2_streamon(&fimc->vid_cap.vbq, type); } diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 92fc5a20fb7..a4646ca1d56 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -153,7 +153,7 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 2, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr", + .name = "YUV 4:2:0 non-contig. 2p, Y/CbCr", .fourcc = V4L2_PIX_FMT_NV12M, .color = FIMC_FMT_YCBCR420, .depth = { 8, 4 }, @@ -161,7 +161,7 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 2, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 non-contiguous 3-planar, Y/Cb/Cr", + .name = "YUV 4:2:0 non-contig. 3p, Y/Cb/Cr", .fourcc = V4L2_PIX_FMT_YUV420M, .color = FIMC_FMT_YCBCR420, .depth = { 8, 2, 2 }, @@ -169,7 +169,7 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 3, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr, tiled", + .name = "YUV 4:2:0 non-contig. 2p, tiled", .fourcc = V4L2_PIX_FMT_NV12MT, .color = FIMC_FMT_YCBCR420, .depth = { 8, 4 }, @@ -641,7 +641,7 @@ void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active) if (!ctrls->ready) return; - mutex_lock(&ctrls->handler.lock); + mutex_lock(ctrls->handler.lock); v4l2_ctrl_activate(ctrls->rotate, active); v4l2_ctrl_activate(ctrls->hflip, active); v4l2_ctrl_activate(ctrls->vflip, active); @@ -660,7 +660,7 @@ void fimc_ctrls_activate(struct fimc_ctx *ctx, bool active) ctx->hflip = 0; ctx->vflip = 0; } - mutex_unlock(&ctrls->handler.lock); + mutex_unlock(ctrls->handler.lock); } /* Update maximum value of the alpha color control */ @@ -741,8 +741,8 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, pix->width = width; for (i = 0; i < pix->num_planes; ++i) { - u32 bpl = pix->plane_fmt[i].bytesperline; - u32 *sizeimage = &pix->plane_fmt[i].sizeimage; + struct v4l2_plane_pix_format *plane_fmt = &pix->plane_fmt[i]; + u32 bpl = plane_fmt->bytesperline; if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width)) bpl = pix->width; /* Planar */ @@ -754,8 +754,9 @@ void fimc_adjust_mplane_format(struct fimc_fmt *fmt, u32 width, u32 height, if (i == 0) /* Same bytesperline for each plane. */ bytesperline = bpl; - pix->plane_fmt[i].bytesperline = bytesperline; - *sizeimage = (pix->width * pix->height * fmt->depth[i]) / 8; + plane_fmt->bytesperline = bytesperline; + plane_fmt->sizeimage = max((pix->width * pix->height * + fmt->depth[i]) / 8, plane_fmt->sizeimage); } } diff --git a/drivers/media/video/s5p-fimc/fimc-lite.c b/drivers/media/video/s5p-fimc/fimc-lite.c index 400d701aef0..74ff310db30 100644 --- a/drivers/media/video/s5p-fimc/fimc-lite.c +++ b/drivers/media/video/s5p-fimc/fimc-lite.c @@ -451,34 +451,44 @@ static void fimc_lite_clear_event_counters(struct fimc_lite *fimc) static int fimc_lite_open(struct file *file) { struct fimc_lite *fimc = video_drvdata(file); - int ret = v4l2_fh_open(file); + int ret; - if (ret) - return ret; + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; set_bit(ST_FLITE_IN_USE, &fimc->state); - pm_runtime_get_sync(&fimc->pdev->dev); + ret = pm_runtime_get_sync(&fimc->pdev->dev); + if (ret < 0) + goto done; - if (++fimc->ref_count != 1 || fimc->out_path != FIMC_IO_DMA) - return ret; + ret = v4l2_fh_open(file); + if (ret < 0) + goto done; - ret = fimc_pipeline_initialize(&fimc->pipeline, &fimc->vfd->entity, - true); - if (ret < 0) { - v4l2_err(fimc->vfd, "Video pipeline initialization failed\n"); - pm_runtime_put_sync(&fimc->pdev->dev); - fimc->ref_count--; - v4l2_fh_release(file); - clear_bit(ST_FLITE_IN_USE, &fimc->state); - } + if (++fimc->ref_count == 1 && fimc->out_path == FIMC_IO_DMA) { + ret = fimc_pipeline_initialize(&fimc->pipeline, + &fimc->vfd->entity, true); + if (ret < 0) { + pm_runtime_put_sync(&fimc->pdev->dev); + fimc->ref_count--; + v4l2_fh_release(file); + clear_bit(ST_FLITE_IN_USE, &fimc->state); + } - fimc_lite_clear_event_counters(fimc); + fimc_lite_clear_event_counters(fimc); + } +done: + mutex_unlock(&fimc->lock); return ret; } static int fimc_lite_close(struct file *file) { struct fimc_lite *fimc = video_drvdata(file); + int ret; + + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; if (--fimc->ref_count == 0 && fimc->out_path == FIMC_IO_DMA) { clear_bit(ST_FLITE_IN_USE, &fimc->state); @@ -492,20 +502,39 @@ static int fimc_lite_close(struct file *file) if (fimc->ref_count == 0) vb2_queue_release(&fimc->vb_queue); - return v4l2_fh_release(file); + ret = v4l2_fh_release(file); + + mutex_unlock(&fimc->lock); + return ret; } static unsigned int fimc_lite_poll(struct file *file, struct poll_table_struct *wait) { struct fimc_lite *fimc = video_drvdata(file); - return vb2_poll(&fimc->vb_queue, file, wait); + int ret; + + if (mutex_lock_interruptible(&fimc->lock)) + return POLL_ERR; + + ret = vb2_poll(&fimc->vb_queue, file, wait); + mutex_unlock(&fimc->lock); + + return ret; } static int fimc_lite_mmap(struct file *file, struct vm_area_struct *vma) { struct fimc_lite *fimc = video_drvdata(file); - return vb2_mmap(&fimc->vb_queue, vma); + int ret; + + if (mutex_lock_interruptible(&fimc->lock)) + return -ERESTARTSYS; + + ret = vb2_mmap(&fimc->vb_queue, vma); + mutex_unlock(&fimc->lock); + + return ret; } static const struct v4l2_file_operations fimc_lite_fops = { @@ -762,7 +791,9 @@ static int fimc_lite_streamon(struct file *file, void *priv, if (fimc_lite_active(fimc)) return -EBUSY; - media_entity_pipeline_start(&sensor->entity, p->m_pipeline); + ret = media_entity_pipeline_start(&sensor->entity, p->m_pipeline); + if (ret < 0) + return ret; ret = fimc_pipeline_validate(fimc); if (ret) { @@ -1508,7 +1539,7 @@ static int fimc_lite_suspend(struct device *dev) return 0; ret = fimc_lite_stop_capture(fimc, suspend); - if (ret) + if (ret < 0 || !fimc_lite_active(fimc)) return ret; return fimc_pipeline_shutdown(&fimc->pipeline); diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index 6753c45631b..52cef486542 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -193,9 +193,13 @@ int __fimc_pipeline_shutdown(struct fimc_pipeline *p) int fimc_pipeline_shutdown(struct fimc_pipeline *p) { - struct media_entity *me = &p->subdevs[IDX_SENSOR]->entity; + struct media_entity *me; int ret; + if (!p || !p->subdevs[IDX_SENSOR]) + return -EINVAL; + + me = &p->subdevs[IDX_SENSOR]->entity; mutex_lock(&me->parent->graph_mutex); ret = __fimc_pipeline_shutdown(p); mutex_unlock(&me->parent->graph_mutex); @@ -498,12 +502,12 @@ static void fimc_md_unregister_entities(struct fimc_md *fmd) * @source: the source entity to create links to all fimc entities from * @sensor: sensor subdev linked to FIMC[fimc_id] entity, may be null * @pad: the source entity pad index - * @fimc_id: index of the fimc device for which link should be enabled + * @link_mask: bitmask of the fimc devices for which link should be enabled */ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, struct media_entity *source, struct v4l2_subdev *sensor, - int pad, int fimc_id) + int pad, int link_mask) { struct fimc_sensor_info *s_info; struct media_entity *sink; @@ -520,7 +524,7 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, if (!fmd->fimc[i]->variant->has_cam_if) continue; - flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0; + flags = ((1 << i) & link_mask) ? MEDIA_LNK_FL_ENABLED : 0; sink = &fmd->fimc[i]->vid_cap.subdev.entity; ret = media_entity_create_link(source, pad, sink, @@ -552,7 +556,10 @@ static int __fimc_md_create_fimc_sink_links(struct fimc_md *fmd, if (!fmd->fimc_lite[i]) continue; - flags = (i == fimc_id) ? MEDIA_LNK_FL_ENABLED : 0; + if (link_mask & (1 << (i + FIMC_MAX_DEVS))) + flags = MEDIA_LNK_FL_ENABLED; + else + flags = 0; sink = &fmd->fimc_lite[i]->subdev.entity; ret = media_entity_create_link(source, pad, sink, @@ -614,9 +621,8 @@ static int fimc_md_create_links(struct fimc_md *fmd) struct s5p_fimc_isp_info *pdata; struct fimc_sensor_info *s_info; struct media_entity *source, *sink; - int i, pad, fimc_id = 0; - int ret = 0; - u32 flags; + int i, pad, fimc_id = 0, ret = 0; + u32 flags, link_mask = 0; for (i = 0; i < fmd->num_sensors; i++) { if (fmd->sensor[i].subdev == NULL) @@ -668,19 +674,20 @@ static int fimc_md_create_links(struct fimc_md *fmd) if (source == NULL) continue; + link_mask = 1 << fimc_id++; ret = __fimc_md_create_fimc_sink_links(fmd, source, sensor, - pad, fimc_id++); + pad, link_mask); } - fimc_id = 0; for (i = 0; i < ARRAY_SIZE(fmd->csis); i++) { if (fmd->csis[i].sd == NULL) continue; source = &fmd->csis[i].sd->entity; pad = CSIS_PAD_SOURCE; + link_mask = 1 << fimc_id++; ret = __fimc_md_create_fimc_sink_links(fmd, source, NULL, - pad, fimc_id++); + pad, link_mask); } /* Create immutable links between each FIMC's subdev and video node */ @@ -734,8 +741,8 @@ static void fimc_md_put_clocks(struct fimc_md *fmd) } static int __fimc_md_set_camclk(struct fimc_md *fmd, - struct fimc_sensor_info *s_info, - bool on) + struct fimc_sensor_info *s_info, + bool on) { struct s5p_fimc_isp_info *pdata = s_info->pdata; struct fimc_camclk_info *camclk; @@ -744,12 +751,10 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, if (WARN_ON(pdata->clk_id >= FIMC_MAX_CAMCLKS) || fmd == NULL) return -EINVAL; - if (s_info->clk_on == on) - return 0; camclk = &fmd->camclk[pdata->clk_id]; - dbg("camclk %d, f: %lu, clk: %p, on: %d", - pdata->clk_id, pdata->clk_frequency, camclk, on); + dbg("camclk %d, f: %lu, use_count: %d, on: %d", + pdata->clk_id, pdata->clk_frequency, camclk->use_count, on); if (on) { if (camclk->use_count > 0 && @@ -760,11 +765,9 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, clk_set_rate(camclk->clock, pdata->clk_frequency); camclk->frequency = pdata->clk_frequency; ret = clk_enable(camclk->clock); + dbg("Enabled camclk %d: f: %lu", pdata->clk_id, + clk_get_rate(camclk->clock)); } - s_info->clk_on = 1; - dbg("Enabled camclk %d: f: %lu", pdata->clk_id, - clk_get_rate(camclk->clock)); - return ret; } @@ -773,7 +776,6 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, if (--camclk->use_count == 0) { clk_disable(camclk->clock); - s_info->clk_on = 0; dbg("Disabled camclk %d", pdata->clk_id); } return ret; @@ -789,8 +791,6 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, * devices to which sensors can be attached, either directly or through * the MIPI CSI receiver. The clock is allowed here to be used by * multiple sensors concurrently if they use same frequency. - * The per sensor subdev clk_on attribute helps to synchronize accesses - * to the sclk_cam clocks from the video and media device nodes. * This function should only be called when the graph mutex is held. */ int fimc_md_set_camclk(struct v4l2_subdev *sd, bool on) diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.h b/drivers/media/video/s5p-fimc/fimc-mdevice.h index 3b8a3492a17..1f5dbaff544 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.h +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.h @@ -47,7 +47,6 @@ struct fimc_camclk_info { * @pdata: sensor's atrributes passed as media device's platform data * @subdev: image sensor v4l2 subdev * @host: fimc device the sensor is currently linked to - * @clk_on: sclk_cam clock's state associated with this subdev * * This data structure applies to image sensor and the writeback subdevs. */ @@ -55,7 +54,6 @@ struct fimc_sensor_info { struct s5p_fimc_isp_info *pdata; struct v4l2_subdev *subdev; struct fimc_dev *host; - bool clk_on; }; /** diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c index 4dd32fc8fd8..feea867f318 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c @@ -996,6 +996,7 @@ int s5p_mfc_dec_ctrls_setup(struct s5p_mfc_ctx *ctx) for (i = 0; i < NUM_CTRLS; i++) { if (IS_MFC51_PRIV(controls[i].id)) { + memset(&cfg, 0, sizeof(struct v4l2_ctrl_config)); cfg.ops = &s5p_mfc_dec_ctrl_ops; cfg.id = controls[i].id; cfg.min = controls[i].minimum; diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c index 03d83340e7f..158b78989b8 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c @@ -1773,6 +1773,7 @@ int s5p_mfc_enc_ctrls_setup(struct s5p_mfc_ctx *ctx) } for (i = 0; i < NUM_CTRLS; i++) { if (IS_MFC51_PRIV(controls[i].id)) { + memset(&cfg, 0, sizeof(struct v4l2_ctrl_config)); cfg.ops = &s5p_mfc_enc_ctrl_ops; cfg.id = controls[i].id; cfg.min = controls[i].minimum; diff --git a/drivers/media/video/smiapp/smiapp-core.c b/drivers/media/video/smiapp/smiapp-core.c index e8c93c89265..9cf5bda35fb 100644 --- a/drivers/media/video/smiapp/smiapp-core.c +++ b/drivers/media/video/smiapp/smiapp-core.c @@ -31,6 +31,7 @@ #include <linux/device.h> #include <linux/gpio.h> #include <linux/module.h> +#include <linux/slab.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/v4l2-mediabus.h> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index e129c820df7..92144ed1ad4 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -286,6 +286,7 @@ config TWL6040_CORE depends on I2C=y && GENERIC_HARDIRQS select MFD_CORE select REGMAP_I2C + select IRQ_DOMAIN default n help Say yes here if you want support for Texas Instruments TWL6040 audio diff --git a/drivers/mfd/ab5500-core.h b/drivers/mfd/ab5500-core.h deleted file mode 100644 index 63b30b17e4f..00000000000 --- a/drivers/mfd/ab5500-core.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2011 ST-Ericsson - * License terms: GNU General Public License (GPL) version 2 - * Shared definitions and data structures for the AB5500 MFD driver - */ - -/* Read/write operation values. */ -#define AB5500_PERM_RD (0x01) -#define AB5500_PERM_WR (0x02) - -/* Read/write permissions. */ -#define AB5500_PERM_RO (AB5500_PERM_RD) -#define AB5500_PERM_RW (AB5500_PERM_RD | AB5500_PERM_WR) - -#define AB5500_MASK_BASE (0x60) -#define AB5500_MASK_END (0x79) -#define AB5500_CHIP_ID (0x20) - -/** - * struct ab5500_reg_range - * @first: the first address of the range - * @last: the last address of the range - * @perm: access permissions for the range - */ -struct ab5500_reg_range { - u8 first; - u8 last; - u8 perm; -}; - -/** - * struct ab5500_i2c_ranges - * @count: the number of ranges in the list - * @range: the list of register ranges - */ -struct ab5500_i2c_ranges { - u8 nranges; - u8 bankid; - const struct ab5500_reg_range *range; -}; - -/** - * struct ab5500_i2c_banks - * @count: the number of ranges in the list - * @range: the list of register ranges - */ -struct ab5500_i2c_banks { - u8 nbanks; - const struct ab5500_i2c_ranges *bank; -}; - -/** - * struct ab5500_bank - * @slave_addr: I2C slave_addr found in AB5500 specification - * @name: Documentation name of the bank. For reference - */ -struct ab5500_bank { - u8 slave_addr; - const char *name; -}; - -static const struct ab5500_bank bankinfo[AB5500_NUM_BANKS] = { - [AB5500_BANK_VIT_IO_I2C_CLK_TST_OTP] = { - AB5500_ADDR_VIT_IO_I2C_CLK_TST_OTP, "VIT_IO_I2C_CLK_TST_OTP"}, - [AB5500_BANK_VDDDIG_IO_I2C_CLK_TST] = { - AB5500_ADDR_VDDDIG_IO_I2C_CLK_TST, "VDDDIG_IO_I2C_CLK_TST"}, - [AB5500_BANK_VDENC] = {AB5500_ADDR_VDENC, "VDENC"}, - [AB5500_BANK_SIM_USBSIM] = {AB5500_ADDR_SIM_USBSIM, "SIM_USBSIM"}, - [AB5500_BANK_LED] = {AB5500_ADDR_LED, "LED"}, - [AB5500_BANK_ADC] = {AB5500_ADDR_ADC, "ADC"}, - [AB5500_BANK_RTC] = {AB5500_ADDR_RTC, "RTC"}, - [AB5500_BANK_STARTUP] = {AB5500_ADDR_STARTUP, "STARTUP"}, - [AB5500_BANK_DBI_ECI] = {AB5500_ADDR_DBI_ECI, "DBI-ECI"}, - [AB5500_BANK_CHG] = {AB5500_ADDR_CHG, "CHG"}, - [AB5500_BANK_FG_BATTCOM_ACC] = { - AB5500_ADDR_FG_BATTCOM_ACC, "FG_BATCOM_ACC"}, - [AB5500_BANK_USB] = {AB5500_ADDR_USB, "USB"}, - [AB5500_BANK_IT] = {AB5500_ADDR_IT, "IT"}, - [AB5500_BANK_VIBRA] = {AB5500_ADDR_VIBRA, "VIBRA"}, - [AB5500_BANK_AUDIO_HEADSETUSB] = { - AB5500_ADDR_AUDIO_HEADSETUSB, "AUDIO_HEADSETUSB"}, -}; - -int ab5500_get_register_interruptible_raw(struct ab5500 *ab, u8 bank, u8 reg, - u8 *value); -int ab5500_mask_and_set_register_interruptible_raw(struct ab5500 *ab, u8 bank, - u8 reg, u8 bitmask, u8 bitvalues); diff --git a/drivers/mfd/mc13xxx-spi.c b/drivers/mfd/mc13xxx-spi.c index 3fcdab3eb8e..03df422feb7 100644 --- a/drivers/mfd/mc13xxx-spi.c +++ b/drivers/mfd/mc13xxx-spi.c @@ -49,10 +49,72 @@ static struct regmap_config mc13xxx_regmap_spi_config = { .reg_bits = 7, .pad_bits = 1, .val_bits = 24, + .write_flag_mask = 0x80, .max_register = MC13XXX_NUMREGS, .cache_type = REGCACHE_NONE, + .use_single_rw = 1, +}; + +static int mc13xxx_spi_read(void *context, const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + unsigned char w[4] = { *((unsigned char *) reg), 0, 0, 0}; + unsigned char r[4]; + unsigned char *p = val; + struct device *dev = context; + struct spi_device *spi = to_spi_device(dev); + struct spi_transfer t = { + .tx_buf = w, + .rx_buf = r, + .len = 4, + }; + + struct spi_message m; + int ret; + + if (val_size != 3 || reg_size != 1) + return -ENOTSUPP; + + spi_message_init(&m); + spi_message_add_tail(&t, &m); + ret = spi_sync(spi, &m); + + memcpy(p, &r[1], 3); + + return ret; +} + +static int mc13xxx_spi_write(void *context, const void *data, size_t count) +{ + struct device *dev = context; + struct spi_device *spi = to_spi_device(dev); + + if (count != 4) + return -ENOTSUPP; + + return spi_write(spi, data, count); +} + +/* + * We cannot use regmap-spi generic bus implementation here. + * The MC13783 chip will get corrupted if CS signal is deasserted + * and on i.Mx31 SoC (the target SoC for MC13783 PMIC) the SPI controller + * has the following errata (DSPhl22960): + * "The CSPI negates SS when the FIFO becomes empty with + * SSCTL= 0. Software cannot guarantee that the FIFO will not + * drain because of higher priority interrupts and the + * non-realtime characteristics of the operating system. As a + * result, the SS will negate before all of the data has been + * transferred to/from the peripheral." + * We workaround this by accessing the SPI controller with a + * single transfert. + */ + +static struct regmap_bus regmap_mc13xxx_bus = { + .write = mc13xxx_spi_write, + .read = mc13xxx_spi_read, }; static int mc13xxx_spi_probe(struct spi_device *spi) @@ -73,12 +135,13 @@ static int mc13xxx_spi_probe(struct spi_device *spi) dev_set_drvdata(&spi->dev, mc13xxx); spi->mode = SPI_MODE_0 | SPI_CS_HIGH; - spi->bits_per_word = 32; mc13xxx->dev = &spi->dev; mutex_init(&mc13xxx->lock); - mc13xxx->regmap = regmap_init_spi(spi, &mc13xxx_regmap_spi_config); + mc13xxx->regmap = regmap_init(&spi->dev, ®map_mc13xxx_bus, &spi->dev, + &mc13xxx_regmap_spi_config); + if (IS_ERR(mc13xxx->regmap)) { ret = PTR_ERR(mc13xxx->regmap); dev_err(mc13xxx->dev, "Failed to initialize register map: %d\n", diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 7e96bb22972..41088ecbb2a 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c @@ -25,6 +25,7 @@ #include <linux/clk.h> #include <linux/dma-mapping.h> #include <linux/spinlock.h> +#include <linux/gpio.h> #include <plat/cpu.h> #include <plat/usb.h> #include <linux/pm_runtime.h> @@ -500,8 +501,21 @@ static void omap_usbhs_init(struct device *dev) dev_dbg(dev, "starting TI HSUSB Controller\n"); pm_runtime_get_sync(dev); - spin_lock_irqsave(&omap->lock, flags); + if (pdata->ehci_data->phy_reset) { + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_request_one(pdata->ehci_data->reset_gpio_port[0], + GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_request_one(pdata->ehci_data->reset_gpio_port[1], + GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); + + /* Hold the PHY in RESET for enough time till DIR is high */ + udelay(10); + } + + spin_lock_irqsave(&omap->lock, flags); omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); @@ -581,9 +595,39 @@ static void omap_usbhs_init(struct device *dev) } spin_unlock_irqrestore(&omap->lock, flags); + + if (pdata->ehci_data->phy_reset) { + /* Hold the PHY in RESET for enough time till + * PHY is settled and ready + */ + udelay(10); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_set_value_cansleep + (pdata->ehci_data->reset_gpio_port[0], 1); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_set_value_cansleep + (pdata->ehci_data->reset_gpio_port[1], 1); + } + pm_runtime_put_sync(dev); } +static void omap_usbhs_deinit(struct device *dev) +{ + struct usbhs_hcd_omap *omap = dev_get_drvdata(dev); + struct usbhs_omap_platform_data *pdata = &omap->platdata; + + if (pdata->ehci_data->phy_reset) { + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) + gpio_free(pdata->ehci_data->reset_gpio_port[0]); + + if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) + gpio_free(pdata->ehci_data->reset_gpio_port[1]); + } +} + /** * usbhs_omap_probe - initialize TI-based HCDs @@ -767,6 +811,7 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev) goto end_probe; err_alloc: + omap_usbhs_deinit(&pdev->dev); iounmap(omap->tll_base); err_tll: @@ -818,6 +863,7 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev) { struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev); + omap_usbhs_deinit(&pdev->dev); iounmap(omap->tll_base); iounmap(omap->uhh_base); clk_put(omap->init_60m_fclk); diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index 00c0aba7eba..c4a69f193a1 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -356,7 +356,14 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c, } } - ret = regmap_add_irq_chip(palmas->regmap[1], palmas->irq, + /* Change IRQ into clear on read mode for efficiency */ + slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE); + addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL); + reg = PALMAS_INT_CTRL_INT_CLEAR; + + regmap_write(palmas->regmap[slave], addr, reg); + + ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq, IRQF_ONESHOT | IRQF_TRIGGER_LOW, -1, &palmas_irq_chip, &palmas->irq_data); if (ret < 0) @@ -441,6 +448,9 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c, goto err; } + children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata; + children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata); + ret = mfd_add_devices(palmas->dev, -1, children, ARRAY_SIZE(palmas_children), NULL, regmap_irq_chip_get_base(palmas->irq_data)); @@ -472,6 +482,7 @@ static const struct i2c_device_id palmas_i2c_id[] = { { "twl6035", }, { "twl6037", }, { "tps65913", }, + { /* end */ } }; MODULE_DEVICE_TABLE(i2c, palmas_i2c_id); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 7de13891e49..783fcd7365b 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -1147,7 +1147,7 @@ static int mei_pci_resume(struct device *device) err = request_threaded_irq(pdev->irq, NULL, mei_interrupt_thread_handler, - 0, mei_driver_name, dev); + IRQF_ONESHOT, mei_driver_name, dev); else err = request_threaded_irq(pdev->irq, mei_interrupt_quick_handler, diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index 17bbacb1b4b..87b251ab6ec 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c @@ -452,9 +452,9 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, if (msg->activate_gru_mq_desc_gpa != part_uv->activate_gru_mq_desc_gpa) { - spin_lock_irqsave(&part_uv->flags_lock, irq_flags); + spin_lock(&part_uv->flags_lock); part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV; - spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags); + spin_unlock(&part_uv->flags_lock); part_uv->activate_gru_mq_desc_gpa = msg->activate_gru_mq_desc_gpa; } diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c index f13e38decea..8f5dc08d659 100644 --- a/drivers/mmc/core/cd-gpio.c +++ b/drivers/mmc/core/cd-gpio.c @@ -50,8 +50,8 @@ int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio) goto egpioreq; ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - cd->label, host); + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, cd->label, host); if (ret < 0) goto eirqreq; diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 258b203397a..4f4489aa6ba 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -717,10 +717,6 @@ static int mmc_select_powerclass(struct mmc_card *card, card->ext_csd.generic_cmd6_time); } - if (err) - pr_err("%s: power class selection for ext_csd_bus_width %d" - " failed\n", mmc_hostname(card->host), bus_width); - return err; } @@ -1104,7 +1100,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4; err = mmc_select_powerclass(card, ext_csd_bits, ext_csd); if (err) - goto err; + pr_warning("%s: power class selection to bus width %d" + " failed\n", mmc_hostname(card->host), + 1 << bus_width); } /* @@ -1136,7 +1134,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_select_powerclass(card, ext_csd_bits[idx][0], ext_csd); if (err) - goto err; + pr_warning("%s: power class selection to " + "bus width %d failed\n", + mmc_hostname(card->host), + 1 << bus_width); err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, @@ -1164,7 +1165,10 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_select_powerclass(card, ext_csd_bits[idx][1], ext_csd); if (err) - goto err; + pr_warning("%s: power class selection to " + "bus width %d ddr %d failed\n", + mmc_hostname(card->host), + 1 << bus_width, ddr); err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index a05b7b444d4..a6cad5caba7 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -920,12 +920,12 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, */ memset(chip->oob_poi, ~0, mtd->oobsize); chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0]; - - read_page_swap_end(this, buf, mtd->writesize, - this->payload_virt, this->payload_phys, - nfc_geo->payload_size, - payload_virt, payload_phys); } + + read_page_swap_end(this, buf, mtd->writesize, + this->payload_virt, this->payload_phys, + nfc_geo->payload_size, + payload_virt, payload_phys); exit_nfc: return ret; } diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index c58e6a93f44..6acc790c2fb 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -273,6 +273,26 @@ static struct nand_ecclayout nandv2_hw_eccoob_4k = { static const char *part_probes[] = { "RedBoot", "cmdlinepart", "ofpart", NULL }; +static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) +{ + int i; + u32 *t = trg; + const __iomem u32 *s = src; + + for (i = 0; i < (size >> 2); i++) + *t++ = __raw_readl(s++); +} + +static void memcpy32_toio(void __iomem *trg, const void *src, int size) +{ + int i; + u32 __iomem *t = trg; + const u32 *s = src; + + for (i = 0; i < (size >> 2); i++) + __raw_writel(*s++, t++); +} + static int check_int_v3(struct mxc_nand_host *host) { uint32_t tmp; @@ -519,7 +539,7 @@ static void send_read_id_v3(struct mxc_nand_host *host) wait_op_done(host, true); - memcpy_fromio(host->data_buf, host->main_area0, 16); + memcpy32_fromio(host->data_buf, host->main_area0, 16); } /* Request the NANDFC to perform a read of the NAND device ID. */ @@ -535,7 +555,7 @@ static void send_read_id_v1_v2(struct mxc_nand_host *host) /* Wait for operation to complete */ wait_op_done(host, true); - memcpy_fromio(host->data_buf, host->main_area0, 16); + memcpy32_fromio(host->data_buf, host->main_area0, 16); if (this->options & NAND_BUSWIDTH_16) { /* compress the ID info */ @@ -797,16 +817,16 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom) if (bfrom) { for (i = 0; i < n - 1; i++) - memcpy_fromio(d + i * j, s + i * t, j); + memcpy32_fromio(d + i * j, s + i * t, j); /* the last section */ - memcpy_fromio(d + i * j, s + i * t, mtd->oobsize - i * j); + memcpy32_fromio(d + i * j, s + i * t, mtd->oobsize - i * j); } else { for (i = 0; i < n - 1; i++) - memcpy_toio(&s[i * t], &d[i * j], j); + memcpy32_toio(&s[i * t], &d[i * j], j); /* the last section */ - memcpy_toio(&s[i * t], &d[i * j], mtd->oobsize - i * j); + memcpy32_toio(&s[i * t], &d[i * j], mtd->oobsize - i * j); } } @@ -1070,7 +1090,8 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, host->devtype_data->send_page(mtd, NFC_OUTPUT); - memcpy_fromio(host->data_buf, host->main_area0, mtd->writesize); + memcpy32_fromio(host->data_buf, host->main_area0, + mtd->writesize); copy_spare(mtd, true); break; @@ -1086,7 +1107,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, break; case NAND_CMD_PAGEPROG: - memcpy_toio(host->main_area0, host->data_buf, mtd->writesize); + memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize); copy_spare(mtd, false); host->devtype_data->send_page(mtd, NFC_INPUT); host->devtype_data->send_cmd(host, command, true); diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 6cc8fbfabb8..cf0cd314681 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -28,7 +28,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/vmalloc.h> -#include <asm/div64.h> +#include <linux/math64.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/string.h> @@ -546,12 +546,6 @@ static char *get_partition_name(int i) return kstrdup(buf, GFP_KERNEL); } -static uint64_t divide(uint64_t n, uint32_t d) -{ - do_div(n, d); - return n; -} - /* * Initialize the nandsim structure. * @@ -580,7 +574,7 @@ static int init_nandsim(struct mtd_info *mtd) ns->geom.oobsz = mtd->oobsize; ns->geom.secsz = mtd->erasesize; ns->geom.pgszoob = ns->geom.pgsz + ns->geom.oobsz; - ns->geom.pgnum = divide(ns->geom.totsz, ns->geom.pgsz); + ns->geom.pgnum = div_u64(ns->geom.totsz, ns->geom.pgsz); ns->geom.totszoob = ns->geom.totsz + (uint64_t)ns->geom.pgnum * ns->geom.oobsz; ns->geom.secshift = ffs(ns->geom.secsz) - 1; ns->geom.pgshift = chip->page_shift; @@ -921,7 +915,7 @@ static int setup_wear_reporting(struct mtd_info *mtd) if (!rptwear) return 0; - wear_eb_count = divide(mtd->size, mtd->erasesize); + wear_eb_count = div_u64(mtd->size, mtd->erasesize); mem = wear_eb_count * sizeof(unsigned long); if (mem / sizeof(unsigned long) != wear_eb_count) { NS_ERR("Too many erase blocks for wear reporting\n"); diff --git a/drivers/of/base.c b/drivers/of/base.c index eada3f4ef80..d9bfd49b193 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -511,22 +511,6 @@ out: } EXPORT_SYMBOL(of_find_node_with_property); -static const struct of_device_id *of_match_compat(const struct of_device_id *matches, - const char *compat) -{ - while (matches->name[0] || matches->type[0] || matches->compatible[0]) { - const char *cp = matches->compatible; - int len = strlen(cp); - - if (len > 0 && of_compat_cmp(compat, cp, len) == 0) - return matches; - - matches++; - } - - return NULL; -} - /** * of_match_node - Tell if an device_node has a matching of_match structure * @matches: array of of device match structures to search in @@ -537,18 +521,9 @@ static const struct of_device_id *of_match_compat(const struct of_device_id *mat const struct of_device_id *of_match_node(const struct of_device_id *matches, const struct device_node *node) { - struct property *prop; - const char *cp; - if (!matches) return NULL; - of_property_for_each_string(node, "compatible", prop, cp) { - const struct of_device_id *match = of_match_compat(matches, cp); - if (match) - return match; - } - while (matches->name[0] || matches->type[0] || matches->compatible[0]) { int match = 1; if (matches->name[0]) @@ -557,7 +532,10 @@ const struct of_device_id *of_match_node(const struct of_device_id *matches, if (matches->type[0]) match &= node->type && !strcmp(matches->type, node->type); - if (match && !matches->compatible[0]) + if (matches->compatible[0]) + match &= of_device_is_compatible(node, + matches->compatible); + if (match) return matches; matches++; } diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 3132ea068d9..e44f8c2d239 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -317,10 +317,9 @@ static const struct of_dev_auxdata *of_dev_lookup(const struct of_dev_auxdata *l for(; lookup->compatible != NULL; lookup++) { if (!of_device_is_compatible(np, lookup->compatible)) continue; - if (of_address_to_resource(np, 0, &res)) - continue; - if (res.start != lookup->phys_addr) - continue; + if (!of_address_to_resource(np, 0, &res)) + if (res.start != lookup->phys_addr) + continue; pr_debug("%s: devname=%s\n", np->full_name, lookup->name); return lookup; } diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index bf0cee629b6..099f46cd8e8 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -748,6 +748,18 @@ static int pci_pm_suspend_noirq(struct device *dev) pci_pm_set_unknown_state(pci_dev); + /* + * Some BIOSes from ASUS have a bug: If a USB EHCI host controller's + * PCI COMMAND register isn't 0, the BIOS assumes that the controller + * hasn't been quiesced and tries to turn it off. If the controller + * is already in D3, this can hang or cause memory corruption. + * + * Since the value of the COMMAND register doesn't matter once the + * device has been suspended, we can safely set it to 0 here. + */ + if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) + pci_write_config_word(pci_dev, PCI_COMMAND, 0); + return 0; } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 77cb54a65cd..447e83472c0 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1744,11 +1744,6 @@ int pci_prepare_to_sleep(struct pci_dev *dev) if (target_state == PCI_POWER_ERROR) return -EIO; - /* Some devices mustn't be in D3 during system sleep */ - if (target_state == PCI_D3hot && - (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP)) - return 0; - pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); error = pci_set_power_state(dev, target_state); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 194b243a281..2a752167754 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -2929,32 +2929,6 @@ static void __devinit disable_igfx_irq(struct pci_dev *dev) DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); -/* - * The Intel 6 Series/C200 Series chipset's EHCI controllers on many - * ASUS motherboards will cause memory corruption or a system crash - * if they are in D3 while the system is put into S3 sleep. - */ -static void __devinit asus_ehci_no_d3(struct pci_dev *dev) -{ - const char *sys_info; - static const char good_Asus_board[] = "P8Z68-V"; - - if (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP) - return; - if (dev->subsystem_vendor != PCI_VENDOR_ID_ASUSTEK) - return; - sys_info = dmi_get_system_info(DMI_BOARD_NAME); - if (sys_info && memcmp(sys_info, good_Asus_board, - sizeof(good_Asus_board) - 1) == 0) - return; - - dev_info(&dev->dev, "broken D3 during system sleep on ASUS\n"); - dev->dev_flags |= PCI_DEV_FLAGS_NO_D3_DURING_SLEEP; - device_set_wakeup_capable(&dev->dev, false); -} -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c26, asus_ehci_no_d3); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c2d, asus_ehci_no_d3); - static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, struct pci_fixup *end) { diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 09a737c868b..8b4b3829d9e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2519,9 +2519,12 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) { struct regulator_dev *rdev = regulator->rdev; struct regulator *consumer; - int ret, output_uV, input_uV, total_uA_load = 0; + int ret, output_uV, input_uV = 0, total_uA_load = 0; unsigned int mode; + if (rdev->supply) + input_uV = regulator_get_voltage(rdev->supply); + mutex_lock(&rdev->mutex); /* @@ -2554,10 +2557,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) goto out; } - /* get input voltage */ - input_uV = 0; - if (rdev->supply) - input_uV = regulator_get_voltage(rdev->supply); + /* No supply? Use constraint voltage */ if (input_uV <= 0) input_uV = rdev->constraints->input_uV; if (input_uV <= 0) { diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 24d880e78ec..f8d818abf98 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -4,9 +4,11 @@ menu "Remoteproc drivers (EXPERIMENTAL)" config REMOTEPROC tristate depends on EXPERIMENTAL + select FW_CONFIG config OMAP_REMOTEPROC tristate "OMAP remoteproc support" + depends on EXPERIMENTAL depends on ARCH_OMAP4 depends on OMAP_IOMMU select REMOTEPROC diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 75506ec2840..39d3aa41add 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -188,6 +188,26 @@ static int rpmsg_uevent(struct device *dev, struct kobj_uevent_env *env) rpdev->id.name); } +/** + * __ept_release() - deallocate an rpmsg endpoint + * @kref: the ept's reference count + * + * This function deallocates an ept, and is invoked when its @kref refcount + * drops to zero. + * + * Never invoke this function directly! + */ +static void __ept_release(struct kref *kref) +{ + struct rpmsg_endpoint *ept = container_of(kref, struct rpmsg_endpoint, + refcount); + /* + * At this point no one holds a reference to ept anymore, + * so we can directly free it + */ + kfree(ept); +} + /* for more info, see below documentation of rpmsg_create_ept() */ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp, struct rpmsg_channel *rpdev, rpmsg_rx_cb_t cb, @@ -206,6 +226,9 @@ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp, return NULL; } + kref_init(&ept->refcount); + mutex_init(&ept->cb_lock); + ept->rpdev = rpdev; ept->cb = cb; ept->priv = priv; @@ -238,7 +261,7 @@ rem_idr: idr_remove(&vrp->endpoints, request); free_ept: mutex_unlock(&vrp->endpoints_lock); - kfree(ept); + kref_put(&ept->refcount, __ept_release); return NULL; } @@ -302,11 +325,17 @@ EXPORT_SYMBOL(rpmsg_create_ept); static void __rpmsg_destroy_ept(struct virtproc_info *vrp, struct rpmsg_endpoint *ept) { + /* make sure new inbound messages can't find this ept anymore */ mutex_lock(&vrp->endpoints_lock); idr_remove(&vrp->endpoints, ept->addr); mutex_unlock(&vrp->endpoints_lock); - kfree(ept); + /* make sure in-flight inbound messages won't invoke cb anymore */ + mutex_lock(&ept->cb_lock); + ept->cb = NULL; + mutex_unlock(&ept->cb_lock); + + kref_put(&ept->refcount, __ept_release); } /** @@ -790,12 +819,28 @@ static void rpmsg_recv_done(struct virtqueue *rvq) /* use the dst addr to fetch the callback of the appropriate user */ mutex_lock(&vrp->endpoints_lock); + ept = idr_find(&vrp->endpoints, msg->dst); + + /* let's make sure no one deallocates ept while we use it */ + if (ept) + kref_get(&ept->refcount); + mutex_unlock(&vrp->endpoints_lock); - if (ept && ept->cb) - ept->cb(ept->rpdev, msg->data, msg->len, ept->priv, msg->src); - else + if (ept) { + /* make sure ept->cb doesn't go away while we use it */ + mutex_lock(&ept->cb_lock); + + if (ept->cb) + ept->cb(ept->rpdev, msg->data, msg->len, ept->priv, + msg->src); + + mutex_unlock(&ept->cb_lock); + + /* farewell, ept, we don't need you anymore */ + kref_put(&ept->refcount, __ept_release); + } else dev_warn(dev, "msg received with no recepient\n"); /* publish the real size of the buffer */ diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index 4bcf9ca2818..370889d0489 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c @@ -17,6 +17,7 @@ #include <linux/mfd/abx500.h> #include <linux/mfd/abx500/ab8500.h> #include <linux/delay.h> +#include <linux/of.h> #define AB8500_RTC_SOFF_STAT_REG 0x00 #define AB8500_RTC_CC_CONF_REG 0x01 @@ -422,7 +423,7 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev) } err = request_threaded_irq(irq, NULL, rtc_alarm_handler, - IRQF_NO_SUSPEND, "ab8500-rtc", rtc); + IRQF_NO_SUSPEND | IRQF_ONESHOT, "ab8500-rtc", rtc); if (err < 0) { rtc_device_unregister(rtc); return err; @@ -430,7 +431,6 @@ static int __devinit ab8500_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rtc); - err = ab8500_sysfs_rtc_register(&pdev->dev); if (err) { dev_err(&pdev->dev, "sysfs RTC failed to register\n"); @@ -454,10 +454,16 @@ static int __devexit ab8500_rtc_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id ab8500_rtc_match[] = { + { .compatible = "stericsson,ab8500-rtc", }, + {} +}; + static struct platform_driver ab8500_rtc_driver = { .driver = { .name = "ab8500-rtc", .owner = THIS_MODULE, + .of_match_table = ab8500_rtc_match, }, .probe = ab8500_rtc_probe, .remove = __devexit_p(ab8500_rtc_remove), diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 5e1d64ee522..e3e50d69baf 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -202,10 +202,11 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) struct platform_device *pdev = dev_id; struct rtc_plat_data *pdata = platform_get_drvdata(pdev); void __iomem *ioaddr = pdata->ioaddr; + unsigned long flags; u32 status; u32 events = 0; - spin_lock_irq(&pdata->rtc->irq_lock); + spin_lock_irqsave(&pdata->rtc->irq_lock, flags); status = readw(ioaddr + RTC_RTCISR) & readw(ioaddr + RTC_RTCIENR); /* clear interrupt sources */ writew(status, ioaddr + RTC_RTCISR); @@ -224,7 +225,7 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id) events |= (RTC_PF | RTC_IRQF); rtc_update_irq(pdata->rtc, 1, events); - spin_unlock_irq(&pdata->rtc->irq_lock); + spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags); return IRQ_HANDLED; } diff --git a/drivers/rtc/rtc-spear.c b/drivers/rtc/rtc-spear.c index 1f76320e545..e2785479113 100644 --- a/drivers/rtc/rtc-spear.c +++ b/drivers/rtc/rtc-spear.c @@ -458,12 +458,12 @@ static int __devexit spear_rtc_remove(struct platform_device *pdev) clk_disable(config->clk); clk_put(config->clk); iounmap(config->ioaddr); - kfree(config); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res) release_mem_region(res->start, resource_size(res)); platform_set_drvdata(pdev, NULL); rtc_device_unregister(config->rtc); + kfree(config); return 0; } diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c index 258abeabf62..c5d06fe83bb 100644 --- a/drivers/rtc/rtc-twl.c +++ b/drivers/rtc/rtc-twl.c @@ -510,7 +510,7 @@ static int __devinit twl_rtc_probe(struct platform_device *pdev) } ret = request_threaded_irq(irq, NULL, twl_rtc_interrupt, - IRQF_TRIGGER_RISING, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, dev_name(&rtc->dev), rtc); if (ret < 0) { dev_err(&pdev->dev, "IRQ is not free.\n"); diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index 532d212b6b2..393e7ce8e95 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c @@ -201,7 +201,7 @@ static void asd_get_response_tasklet(struct asd_ascb *ascb, if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) { resp->frame_len = le16_to_cpu(*(__le16 *)(r+6)); - memcpy(&resp->ending_fis[0], r+16, 24); + memcpy(&resp->ending_fis[0], r+16, ATA_RESP_FIS_SIZE); ts->buf_valid_size = sizeof(*resp); } } diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index 0c53c28dc3d..7e77cf62029 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h @@ -350,6 +350,7 @@ struct bnx2i_hba { struct pci_dev *pcidev; struct net_device *netdev; void __iomem *regview; + resource_size_t reg_base; u32 age; unsigned long cnic_dev_type; diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index ece47e50228..86a12b48e47 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -2724,7 +2724,6 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep) goto arm_cq; } - reg_base = ep->hba->netdev->base_addr; if ((test_bit(BNX2I_NX2_DEV_5709, &ep->hba->cnic_dev_type)) && (ep->hba->mail_queue_access == BNX2I_MQ_BIN_MODE)) { config2 = REG_RD(ep->hba, BNX2_MQ_CONFIG2); @@ -2740,7 +2739,7 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep) /* 5709 device in normal node and 5706/5708 devices */ reg_off = CTX_OFFSET + (MB_KERNEL_CTX_SIZE * cid_num); - ep->qp.ctx_base = ioremap_nocache(reg_base + reg_off, + ep->qp.ctx_base = ioremap_nocache(ep->hba->reg_base + reg_off, MB_KERNEL_CTX_SIZE); if (!ep->qp.ctx_base) return -ENOMEM; diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index f8d516b5316..621538b8b54 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -811,13 +811,13 @@ struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic) bnx2i_identify_device(hba); bnx2i_setup_host_queue_size(hba, shost); + hba->reg_base = pci_resource_start(hba->pcidev, 0); if (test_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type)) { - hba->regview = ioremap_nocache(hba->netdev->base_addr, - BNX2_MQ_CONFIG2); + hba->regview = pci_iomap(hba->pcidev, 0, BNX2_MQ_CONFIG2); if (!hba->regview) goto ioreg_map_err; } else if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) { - hba->regview = ioremap_nocache(hba->netdev->base_addr, 4096); + hba->regview = pci_iomap(hba->pcidev, 0, 4096); if (!hba->regview) goto ioreg_map_err; } @@ -884,7 +884,7 @@ cid_que_err: bnx2i_free_mp_bdt(hba); mp_bdt_mem_err: if (hba->regview) { - iounmap(hba->regview); + pci_iounmap(hba->pcidev, hba->regview); hba->regview = NULL; } ioreg_map_err: @@ -910,7 +910,7 @@ void bnx2i_free_hba(struct bnx2i_hba *hba) pci_dev_put(hba->pcidev); if (hba->regview) { - iounmap(hba->regview); + pci_iounmap(hba->pcidev, hba->regview); hba->regview = NULL; } bnx2i_free_mp_bdt(hba); diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 441d88ad99a..d109cc3a17b 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -139,12 +139,12 @@ static void sas_ata_task_done(struct sas_task *task) if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD || ((stat->stat == SAM_STAT_CHECK_CONDITION && dev->sata_dev.command_set == ATAPI_COMMAND_SET))) { - ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf); + memcpy(dev->sata_dev.fis, resp->ending_fis, ATA_RESP_FIS_SIZE); if (!link->sactive) { - qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command); + qc->err_mask |= ac_err_mask(dev->sata_dev.fis[2]); } else { - link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.tf.command); + link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.fis[2]); if (unlikely(link->eh_info.err_mask)) qc->flags |= ATA_QCFLAG_FAILED; } @@ -161,8 +161,8 @@ static void sas_ata_task_done(struct sas_task *task) qc->flags |= ATA_QCFLAG_FAILED; } - dev->sata_dev.tf.feature = 0x04; /* status err */ - dev->sata_dev.tf.command = ATA_ERR; + dev->sata_dev.fis[3] = 0x04; /* status err */ + dev->sata_dev.fis[2] = ATA_ERR; } } @@ -269,7 +269,7 @@ static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc) { struct domain_device *dev = qc->ap->private_data; - memcpy(&qc->result_tf, &dev->sata_dev.tf, sizeof(qc->result_tf)); + ata_tf_from_fis(dev->sata_dev.fis, &qc->result_tf); return true; } diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c index ced26c8ccd5..0d2ea0c224c 100644 --- a/drivers/tty/hvc/hvc_opal.c +++ b/drivers/tty/hvc/hvc_opal.c @@ -401,7 +401,7 @@ out: } #ifdef CONFIG_PPC_EARLY_DEBUG_OPAL_RAW -void __init udbg_init_debug_opal(void) +void __init udbg_init_debug_opal_raw(void) { u32 index = CONFIG_PPC_EARLY_DEBUG_OPAL_VTERMNO; hvc_opal_privs[index] = &hvc_opal_boot_priv; diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 8fd398dffce..ee469274a3f 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -500,6 +500,8 @@ retry: goto retry; } if (!desc->reslength) { /* zero length read */ + dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__); + clear_bit(WDM_READ, &desc->flags); spin_unlock_irq(&desc->iuspin); goto retry; } diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 25a7422ee65..8fb484984c8 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2324,12 +2324,16 @@ static unsigned hub_is_wusb(struct usb_hub *hub) static int hub_port_reset(struct usb_hub *hub, int port1, struct usb_device *udev, unsigned int delay, bool warm); -/* Is a USB 3.0 port in the Inactive state? */ -static bool hub_port_inactive(struct usb_hub *hub, u16 portstatus) +/* Is a USB 3.0 port in the Inactive or Complinance Mode state? + * Port worm reset is required to recover + */ +static bool hub_port_warm_reset_required(struct usb_hub *hub, u16 portstatus) { return hub_is_superspeed(hub->hdev) && - (portstatus & USB_PORT_STAT_LINK_STATE) == - USB_SS_PORT_LS_SS_INACTIVE; + (((portstatus & USB_PORT_STAT_LINK_STATE) == + USB_SS_PORT_LS_SS_INACTIVE) || + ((portstatus & USB_PORT_STAT_LINK_STATE) == + USB_SS_PORT_LS_COMP_MOD)) ; } static int hub_port_wait_reset(struct usb_hub *hub, int port1, @@ -2365,7 +2369,7 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1, * * See https://bugzilla.kernel.org/show_bug.cgi?id=41752 */ - if (hub_port_inactive(hub, portstatus)) { + if (hub_port_warm_reset_required(hub, portstatus)) { int ret; if ((portchange & USB_PORT_STAT_C_CONNECTION)) @@ -4408,9 +4412,7 @@ static void hub_events(void) /* Warm reset a USB3 protocol port if it's in * SS.Inactive state. */ - if (hub_is_superspeed(hub->hdev) && - (portstatus & USB_PORT_STAT_LINK_STATE) - == USB_SS_PORT_LS_SS_INACTIVE) { + if (hub_port_warm_reset_required(hub, portstatus)) { dev_dbg(hub_dev, "warm reset port %d\n", i); hub_port_reset(hub, i, NULL, HUB_BH_RESET_TIME, true); diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 17cfb8a1131..c30435499a0 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c @@ -281,14 +281,13 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) } } + /* Hold PHYs in reset while initializing EHCI controller */ if (pdata->phy_reset) { if (gpio_is_valid(pdata->reset_gpio_port[0])) - gpio_request_one(pdata->reset_gpio_port[0], - GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); + gpio_set_value_cansleep(pdata->reset_gpio_port[0], 0); if (gpio_is_valid(pdata->reset_gpio_port[1])) - gpio_request_one(pdata->reset_gpio_port[1], - GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); + gpio_set_value_cansleep(pdata->reset_gpio_port[1], 0); /* Hold the PHY in RESET for enough time till DIR is high */ udelay(10); @@ -330,6 +329,11 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) omap_ehci->hcs_params = readl(&omap_ehci->caps->hcs_params); ehci_reset(omap_ehci); + ret = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (ret) { + dev_err(dev, "failed to add hcd with err %d\n", ret); + goto err_add_hcd; + } if (pdata->phy_reset) { /* Hold the PHY in RESET for enough time till @@ -344,12 +348,6 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) gpio_set_value_cansleep(pdata->reset_gpio_port[1], 1); } - ret = usb_add_hcd(hcd, irq, IRQF_SHARED); - if (ret) { - dev_err(dev, "failed to add hcd with err %d\n", ret); - goto err_add_hcd; - } - /* root ports should always stay powered */ ehci_port_power(omap_ehci, 1); diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 2732ef660c5..7b01094d799 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -462,6 +462,42 @@ void xhci_test_and_clear_bit(struct xhci_hcd *xhci, __le32 __iomem **port_array, } } +/* Updates Link Status for super Speed port */ +static void xhci_hub_report_link_state(u32 *status, u32 status_reg) +{ + u32 pls = status_reg & PORT_PLS_MASK; + + /* resume state is a xHCI internal state. + * Do not report it to usb core. + */ + if (pls == XDEV_RESUME) + return; + + /* When the CAS bit is set then warm reset + * should be performed on port + */ + if (status_reg & PORT_CAS) { + /* The CAS bit can be set while the port is + * in any link state. + * Only roothubs have CAS bit, so we + * pretend to be in compliance mode + * unless we're already in compliance + * or the inactive state. + */ + if (pls != USB_SS_PORT_LS_COMP_MOD && + pls != USB_SS_PORT_LS_SS_INACTIVE) { + pls = USB_SS_PORT_LS_COMP_MOD; + } + /* Return also connection bit - + * hub state machine resets port + * when this bit is set. + */ + pls |= USB_PORT_STAT_CONNECTION; + } + /* update status field */ + *status |= pls; +} + int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { @@ -606,13 +642,9 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, else status |= USB_PORT_STAT_POWER; } - /* Port Link State */ + /* Update Port Link State for super speed ports*/ if (hcd->speed == HCD_USB3) { - /* resume state is a xHCI internal state. - * Do not report it to usb core. - */ - if ((temp & PORT_PLS_MASK) != XDEV_RESUME) - status |= (temp & PORT_PLS_MASK); + xhci_hub_report_link_state(&status, temp); } if (bus_state->port_c_suspend & (1 << wIndex)) status |= 1 << USB_PORT_FEAT_C_SUSPEND; diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 23b4aefd103..8275645889d 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -885,6 +885,17 @@ static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci, num_trbs_free_temp = ep_ring->num_trbs_free; dequeue_temp = ep_ring->dequeue; + /* If we get two back-to-back stalls, and the first stalled transfer + * ends just before a link TRB, the dequeue pointer will be left on + * the link TRB by the code in the while loop. So we have to update + * the dequeue pointer one segment further, or we'll jump off + * the segment into la-la-land. + */ + if (last_trb(xhci, ep_ring, ep_ring->deq_seg, ep_ring->dequeue)) { + ep_ring->deq_seg = ep_ring->deq_seg->next; + ep_ring->dequeue = ep_ring->deq_seg->trbs; + } + while (ep_ring->dequeue != dev->eps[ep_index].queued_deq_ptr) { /* We have more usable TRBs */ ep_ring->num_trbs_free++; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index de3d6e3e57b..55c0785810c 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -341,7 +341,11 @@ struct xhci_op_regs { #define PORT_PLC (1 << 22) /* port configure error change - port failed to configure its link partner */ #define PORT_CEC (1 << 23) -/* bit 24 reserved */ +/* Cold Attach Status - xHC can set this bit to report device attached during + * Sx state. Warm port reset should be perfomed to clear this bit and move port + * to connected state. + */ +#define PORT_CAS (1 << 24) /* wake on connect (enable) */ #define PORT_WKCONN_E (1 << 25) /* wake on disconnect (enable) */ diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index 81423f7361d..d47eb06fe46 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c @@ -222,14 +222,6 @@ static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) metro_priv->throttled = 0; spin_unlock_irqrestore(&metro_priv->lock, flags); - /* - * Force low_latency on so that our tty_push actually forces the data - * through, otherwise it is scheduled, and with high data rates (like - * with OHCI) data can get lost. - */ - if (tty) - tty->low_latency = 1; - /* Clear the urb pipe. */ usb_clear_halt(serial->dev, port->interrupt_in_urb->pipe); diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index adf8ce72be5..417ab1b0aa3 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -497,6 +497,15 @@ static void option_instat_callback(struct urb *urb); /* MediaTek products */ #define MEDIATEK_VENDOR_ID 0x0e8d +#define MEDIATEK_PRODUCT_DC_1COM 0x00a0 +#define MEDIATEK_PRODUCT_DC_4COM 0x00a5 +#define MEDIATEK_PRODUCT_DC_5COM 0x00a4 +#define MEDIATEK_PRODUCT_7208_1COM 0x7101 +#define MEDIATEK_PRODUCT_7208_2COM 0x7102 +#define MEDIATEK_PRODUCT_FP_1COM 0x0003 +#define MEDIATEK_PRODUCT_FP_2COM 0x0023 +#define MEDIATEK_PRODUCT_FPDC_1COM 0x0043 +#define MEDIATEK_PRODUCT_FPDC_2COM 0x0033 /* Cellient products */ #define CELLIENT_VENDOR_ID 0x2692 @@ -554,6 +563,10 @@ static const struct option_blacklist_info net_intf1_blacklist = { .reserved = BIT(1), }; +static const struct option_blacklist_info net_intf2_blacklist = { + .reserved = BIT(2), +}; + static const struct option_blacklist_info net_intf3_blacklist = { .reserved = BIT(3), }; @@ -1099,6 +1112,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, @@ -1240,6 +1255,17 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a1, 0xff, 0x02, 0x01) }, { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, 0x00a2, 0xff, 0x02, 0x01) }, /* MediaTek MT6276M modem & app port */ + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_1COM, 0x0a, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_5COM, 0xff, 0x02, 0x01) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_5COM, 0xff, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM, 0xff, 0x02, 0x01) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_DC_4COM, 0xff, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7208_1COM, 0x02, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_7208_2COM, 0x02, 0x02, 0x01) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FP_1COM, 0x0a, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FP_2COM, 0x0a, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_1COM, 0x0a, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(MEDIATEK_VENDOR_ID, MEDIATEK_PRODUCT_FPDC_2COM, 0x0a, 0x00, 0x00) }, { USB_DEVICE(CELLIENT_VENDOR_ID, CELLIENT_PRODUCT_MEN200) }, { } /* Terminating entry */ }; diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 5066eee10cc..58bd9c27369 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -32,6 +32,7 @@ #include <linux/io.h> #include <linux/device.h> #include <linux/regulator/consumer.h> +#include <linux/suspend.h> #include <video/omapdss.h> @@ -201,6 +202,28 @@ int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *)) #endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */ /* PLATFORM DEVICE */ +static int omap_dss_pm_notif(struct notifier_block *b, unsigned long v, void *d) +{ + DSSDBG("pm notif %lu\n", v); + + switch (v) { + case PM_SUSPEND_PREPARE: + DSSDBG("suspending displays\n"); + return dss_suspend_all_devices(); + + case PM_POST_SUSPEND: + DSSDBG("resuming displays\n"); + return dss_resume_all_devices(); + + default: + return 0; + } +} + +static struct notifier_block omap_dss_pm_notif_block = { + .notifier_call = omap_dss_pm_notif, +}; + static int __init omap_dss_probe(struct platform_device *pdev) { struct omap_dss_board_info *pdata = pdev->dev.platform_data; @@ -224,6 +247,8 @@ static int __init omap_dss_probe(struct platform_device *pdev) else if (pdata->default_device) core.default_display_name = pdata->default_device->name; + register_pm_notifier(&omap_dss_pm_notif_block); + return 0; err_debugfs: @@ -233,6 +258,8 @@ err_debugfs: static int omap_dss_remove(struct platform_device *pdev) { + unregister_pm_notifier(&omap_dss_pm_notif_block); + dss_uninitialize_debugfs(); dss_uninit_overlays(pdev); @@ -247,25 +274,9 @@ static void omap_dss_shutdown(struct platform_device *pdev) dss_disable_all_devices(); } -static int omap_dss_suspend(struct platform_device *pdev, pm_message_t state) -{ - DSSDBG("suspend %d\n", state.event); - - return dss_suspend_all_devices(); -} - -static int omap_dss_resume(struct platform_device *pdev) -{ - DSSDBG("resume\n"); - - return dss_resume_all_devices(); -} - static struct platform_driver omap_dss_driver = { .remove = omap_dss_remove, .shutdown = omap_dss_shutdown, - .suspend = omap_dss_suspend, - .resume = omap_dss_resume, .driver = { .name = "omapdss", .owner = THIS_MODULE, diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 4749ac35646..397d4eee11b 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -384,7 +384,7 @@ void dispc_runtime_put(void) DSSDBG("dispc_runtime_put\n"); r = pm_runtime_put_sync(&dispc.pdev->dev); - WARN_ON(r < 0); + WARN_ON(r < 0 && r != -ENOSYS); } static inline bool dispc_mgr_is_lcd(enum omap_channel channel) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index ca8382d346e..14ce8cc079e 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1075,7 +1075,7 @@ void dsi_runtime_put(struct platform_device *dsidev) DSSDBG("dsi_runtime_put\n"); r = pm_runtime_put_sync(&dsi->pdev->dev); - WARN_ON(r < 0); + WARN_ON(r < 0 && r != -ENOSYS); } /* source clock for DSI PLL. this could also be PCLKFREE */ diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 770632359a1..d2b57197b29 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -731,7 +731,7 @@ static void dss_runtime_put(void) DSSDBG("dss_runtime_put\n"); r = pm_runtime_put_sync(&dss.pdev->dev); - WARN_ON(r < 0 && r != -EBUSY); + WARN_ON(r < 0 && r != -ENOSYS && r != -EBUSY); } /* DEBUGFS */ diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 8195c7166d2..26a2430a702 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -138,7 +138,7 @@ static void hdmi_runtime_put(void) DSSDBG("hdmi_runtime_put\n"); r = pm_runtime_put_sync(&hdmi.pdev->dev); - WARN_ON(r < 0); + WARN_ON(r < 0 && r != -ENOSYS); } static int __init hdmi_init_display(struct omap_dss_device *dssdev) diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 3d8c206e90e..7985fa12b9b 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -141,7 +141,7 @@ static void rfbi_runtime_put(void) DSSDBG("rfbi_runtime_put\n"); r = pm_runtime_put_sync(&rfbi.pdev->dev); - WARN_ON(r < 0); + WARN_ON(r < 0 && r != -ENOSYS); } void rfbi_bus_lock(void) diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 2b8973931ff..3907c8b6ecb 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -402,7 +402,7 @@ static void venc_runtime_put(void) DSSDBG("venc_runtime_put\n"); r = pm_runtime_put_sync(&venc.pdev->dev); - WARN_ON(r < 0); + WARN_ON(r < 0 && r != -ENOSYS); } static const struct venc_config *venc_timings_to_config( diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index bfbc15ca38d..0908e604433 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -47,7 +47,7 @@ struct virtio_balloon struct task_struct *thread; /* Waiting for host to ack the pages we released. */ - struct completion acked; + wait_queue_head_t acked; /* Number of balloon pages we've told the Host we're not using. */ unsigned int num_pages; @@ -89,29 +89,25 @@ static struct page *balloon_pfn_to_page(u32 pfn) static void balloon_ack(struct virtqueue *vq) { - struct virtio_balloon *vb; - unsigned int len; + struct virtio_balloon *vb = vq->vdev->priv; - vb = virtqueue_get_buf(vq, &len); - if (vb) - complete(&vb->acked); + wake_up(&vb->acked); } static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) { struct scatterlist sg; + unsigned int len; sg_init_one(&sg, vb->pfns, sizeof(vb->pfns[0]) * vb->num_pfns); - init_completion(&vb->acked); - /* We should always be able to add one buffer to an empty queue. */ if (virtqueue_add_buf(vq, &sg, 1, 0, vb, GFP_KERNEL) < 0) BUG(); virtqueue_kick(vq); /* When host has read buffer, this completes via balloon_ack */ - wait_for_completion(&vb->acked); + wait_event(vb->acked, virtqueue_get_buf(vq, &len)); } static void set_page_pfns(u32 pfns[], struct page *page) @@ -231,12 +227,8 @@ static void update_balloon_stats(struct virtio_balloon *vb) */ static void stats_request(struct virtqueue *vq) { - struct virtio_balloon *vb; - unsigned int len; + struct virtio_balloon *vb = vq->vdev->priv; - vb = virtqueue_get_buf(vq, &len); - if (!vb) - return; vb->need_stats_update = 1; wake_up(&vb->config_change); } @@ -245,11 +237,14 @@ static void stats_handle_request(struct virtio_balloon *vb) { struct virtqueue *vq; struct scatterlist sg; + unsigned int len; vb->need_stats_update = 0; update_balloon_stats(vb); vq = vb->stats_vq; + if (!virtqueue_get_buf(vq, &len)) + return; sg_init_one(&sg, vb->stats, sizeof(vb->stats)); if (virtqueue_add_buf(vq, &sg, 1, 0, vb, GFP_KERNEL) < 0) BUG(); @@ -358,6 +353,7 @@ static int virtballoon_probe(struct virtio_device *vdev) INIT_LIST_HEAD(&vb->pages); vb->num_pages = 0; init_waitqueue_head(&vb->config_change); + init_waitqueue_head(&vb->acked); vb->vdev = vdev; vb->need_stats_update = 0; |