diff options
-rw-r--r-- | 3.2.68/1067_linux-3.2.68.patch | 1050 |
1 files changed, 1050 insertions, 0 deletions
diff --git a/3.2.68/1067_linux-3.2.68.patch b/3.2.68/1067_linux-3.2.68.patch index e69de29..200e8b8 100644 --- a/3.2.68/1067_linux-3.2.68.patch +++ b/3.2.68/1067_linux-3.2.68.patch @@ -0,0 +1,1050 @@ +diff --git a/Makefile b/Makefile +index 70769fb..2e7cbda 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 3 + PATCHLEVEL = 2 +-SUBLEVEL = 67 ++SUBLEVEL = 68 + EXTRAVERSION = + NAME = Saber-toothed Squirrel + +diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c +index 191eb52..1f8712f 100644 +--- a/arch/mips/kernel/irq_cpu.c ++++ b/arch/mips/kernel/irq_cpu.c +@@ -56,6 +56,8 @@ static struct irq_chip mips_cpu_irq_controller = { + .irq_mask_ack = mask_mips_irq, + .irq_unmask = unmask_mips_irq, + .irq_eoi = unmask_mips_irq, ++ .irq_disable = mask_mips_irq, ++ .irq_enable = unmask_mips_irq, + }; + + /* +@@ -92,6 +94,8 @@ static struct irq_chip mips_mt_cpu_irq_controller = { + .irq_mask_ack = mips_mt_cpu_irq_ack, + .irq_unmask = unmask_mips_irq, + .irq_eoi = unmask_mips_irq, ++ .irq_disable = mask_mips_irq, ++ .irq_enable = unmask_mips_irq, + }; + + void __init mips_cpu_irq_init(void) +diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c +index 32c1e95..bbfae83 100644 +--- a/arch/mips/kernel/smp.c ++++ b/arch/mips/kernel/smp.c +@@ -105,10 +105,10 @@ asmlinkage __cpuinit void start_secondary(void) + if ((read_c0_tcbind() & TCBIND_CURTC) == 0) + #endif /* CONFIG_MIPS_MT_SMTC */ + cpu_probe(); +- cpu_report(); + per_cpu_trap_init(); + mips_clockevent_init(); + mp_ops->init_secondary(); ++ cpu_report(); + + /* + * XXX parity protection should be folded in here when it's converted +diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c +index 8cac088..351590e 100644 +--- a/arch/x86/mm/fault.c ++++ b/arch/x86/mm/fault.c +@@ -878,7 +878,7 @@ mm_fault_error(struct pt_regs *regs, unsigned long error_code, + VM_FAULT_HWPOISON_LARGE)) + do_sigbus(regs, error_code, address, fault); + else if (fault & VM_FAULT_SIGSEGV) +- bad_area_nosemaphore(regs, error_code, address); ++ bad_area(regs, error_code, address); + else + BUG(); + } +diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c +index 10e442b..22775ae 100644 +--- a/drivers/bluetooth/ath3k.c ++++ b/drivers/bluetooth/ath3k.c +@@ -172,6 +172,8 @@ static struct usb_device_id ath3k_blist_tbl[] = { + #define USB_REQ_DFU_DNLOAD 1 + #define BULK_SIZE 4096 + #define FW_HDR_SIZE 20 ++#define TIMEGAP_USEC_MIN 50 ++#define TIMEGAP_USEC_MAX 100 + + static int ath3k_load_firmware(struct usb_device *udev, + const struct firmware *firmware) +@@ -202,6 +204,9 @@ static int ath3k_load_firmware(struct usb_device *udev, + count -= 20; + + while (count) { ++ /* workaround the compatibility issue with xHCI controller*/ ++ usleep_range(TIMEGAP_USEC_MIN, TIMEGAP_USEC_MAX); ++ + size = min_t(uint, count, BULK_SIZE); + pipe = usb_sndbulkpipe(udev, 0x02); + memcpy(send_buf, firmware->data + sent, size); +@@ -278,6 +283,9 @@ static int ath3k_load_fwfile(struct usb_device *udev, + count -= size; + + while (count) { ++ /* workaround the compatibility issue with xHCI controller*/ ++ usleep_range(TIMEGAP_USEC_MIN, TIMEGAP_USEC_MAX); ++ + size = min_t(uint, count, BULK_SIZE); + pipe = usb_sndbulkpipe(udev, 0x02); + +diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c +index 51e5ee8..36ae055 100644 +--- a/drivers/gpio/gpiolib.c ++++ b/drivers/gpio/gpiolib.c +@@ -821,6 +821,7 @@ int gpio_export_link(struct device *dev, const char *name, unsigned gpio) + if (tdev != NULL) { + status = sysfs_create_link(&dev->kobj, &tdev->kobj, + name); ++ put_device(tdev); + } else { + status = -ENODEV; + } +@@ -871,7 +872,7 @@ int gpio_sysfs_set_active_low(unsigned gpio, int value) + } + + status = sysfs_set_active_low(desc, dev, value); +- ++ put_device(dev); + unlock: + mutex_unlock(&sysfs_lock); + +diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c +index 44442d5..f58067f 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -681,7 +681,7 @@ int vmbus_device_register(struct hv_device *child_device_obj) + if (ret) + pr_err("Unable to register child device\n"); + else +- pr_info("child device %s registered\n", ++ pr_debug("child device %s registered\n", + dev_name(&child_device_obj->device)); + + return ret; +@@ -693,14 +693,14 @@ int vmbus_device_register(struct hv_device *child_device_obj) + */ + void vmbus_device_unregister(struct hv_device *device_obj) + { ++ pr_debug("child device %s unregistered\n", ++ dev_name(&device_obj->device)); ++ + /* + * Kick off the process of unregistering the device. + * This will call vmbus_remove() and eventually vmbus_device_release() + */ + device_unregister(&device_obj->device); +- +- pr_info("child device %s unregistered\n", +- dev_name(&device_obj->device)); + } + + +diff --git a/drivers/media/rc/ir-lirc-codec.c b/drivers/media/rc/ir-lirc-codec.c +index 5faba2a..695fef9 100644 +--- a/drivers/media/rc/ir-lirc-codec.c ++++ b/drivers/media/rc/ir-lirc-codec.c +@@ -42,11 +42,17 @@ static int ir_lirc_decode(struct rc_dev *dev, struct ir_raw_event ev) + return -EINVAL; + + /* Packet start */ +- if (ev.reset) +- return 0; ++ if (ev.reset) { ++ /* Userspace expects a long space event before the start of ++ * the signal to use as a sync. This may be done with repeat ++ * packets and normal samples. But if a reset has been sent ++ * then we assume that a long time has passed, so we send a ++ * space with the maximum time value. */ ++ sample = LIRC_SPACE(LIRC_VALUE_MASK); ++ IR_dprintk(2, "delivering reset sync space to lirc_dev\n"); + + /* Carrier reports */ +- if (ev.carrier_report) { ++ } else if (ev.carrier_report) { + sample = LIRC_FREQUENCY(ev.carrier); + IR_dprintk(2, "carrier report (freq: %d)\n", sample); + +diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c +index 127dfe5d..481b184 100644 +--- a/drivers/pci/quirks.c ++++ b/drivers/pci/quirks.c +@@ -409,7 +409,7 @@ static void quirk_io(struct pci_dev *dev, int pos, unsigned size, + /* Convert from PCI bus to resource space */ + bus_region.start = region; + bus_region.end = region + size - 1; +- pcibios_bus_to_resource(dev->bus, res, &bus_region); ++ pcibios_bus_to_resource(dev, res, &bus_region); + + dev_info(&dev->dev, FW_BUG "%s quirk: reg 0x%x: %pR\n", + name, PCI_BASE_ADDRESS_0 + (pos << 2), res); +diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c +index 1e32419..c651c76 100644 +--- a/drivers/staging/comedi/drivers/cb_pcidas64.c ++++ b/drivers/staging/comedi/drivers/cb_pcidas64.c +@@ -424,6 +424,29 @@ static const struct comedi_lrange ai_ranges_64xx = { + } + }; + ++static const uint8_t ai_range_code_64xx[8] = { ++ 0x0, 0x1, 0x2, 0x3, /* bipolar 10, 5, 2,5, 1.25 */ ++ 0x8, 0x9, 0xa, 0xb /* unipolar 10, 5, 2.5, 1.25 */ ++}; ++ ++/* analog input ranges for 64-Mx boards */ ++static const struct comedi_lrange ai_ranges_64_mx = { ++ 7, { ++ BIP_RANGE(5), ++ BIP_RANGE(2.5), ++ BIP_RANGE(1.25), ++ BIP_RANGE(0.625), ++ UNI_RANGE(5), ++ UNI_RANGE(2.5), ++ UNI_RANGE(1.25) ++ } ++}; ++ ++static const uint8_t ai_range_code_64_mx[7] = { ++ 0x0, 0x1, 0x2, 0x3, /* bipolar 5, 2.5, 1.25, 0.625 */ ++ 0x9, 0xa, 0xb /* unipolar 5, 2.5, 1.25 */ ++}; ++ + /* analog input ranges for 60xx boards */ + static const struct comedi_lrange ai_ranges_60xx = { + 4, +@@ -435,6 +458,10 @@ static const struct comedi_lrange ai_ranges_60xx = { + } + }; + ++static const uint8_t ai_range_code_60xx[4] = { ++ 0x0, 0x1, 0x4, 0x7 /* bipolar 10, 5, 0.5, 0.05 */ ++}; ++ + /* analog input ranges for 6030, etc boards */ + static const struct comedi_lrange ai_ranges_6030 = { + 14, +@@ -456,6 +483,11 @@ static const struct comedi_lrange ai_ranges_6030 = { + } + }; + ++static const uint8_t ai_range_code_6030[14] = { ++ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, /* bip 10, 5, 2, 1, 0.5, 0.2, 0.1 */ ++ 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* uni 10, 5, 2, 1, 0.5, 0.2, 0.1 */ ++}; ++ + /* analog input ranges for 6052, etc boards */ + static const struct comedi_lrange ai_ranges_6052 = { + 15, +@@ -478,6 +510,11 @@ static const struct comedi_lrange ai_ranges_6052 = { + } + }; + ++static const uint8_t ai_range_code_6052[15] = { ++ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, /* bipolar 10 ... 0.05 */ ++ 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf /* unipolar 10 ... 0.1 */ ++}; ++ + /* analog input ranges for 4020 board */ + static const struct comedi_lrange ai_ranges_4020 = { + 2, +@@ -562,6 +599,7 @@ struct pcidas64_board { + int ai_bits; /* analog input resolution */ + int ai_speed; /* fastest conversion period in ns */ + const struct comedi_lrange *ai_range_table; ++ const uint8_t *ai_range_code; + int ao_nchan; /* number of analog out channels */ + int ao_bits; /* analog output resolution */ + int ao_scan_speed; /* analog output speed (for a scan, not conversion) */ +@@ -620,6 +658,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, ++ .ai_range_code = ai_range_code_64xx, + .ao_range_table = &ao_ranges_64xx, + .ao_range_code = ao_range_code_64xx, + .ai_fifo = &ai_fifo_64xx, +@@ -636,6 +675,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, ++ .ai_range_code = ai_range_code_64xx, + .ao_range_table = &ao_ranges_64xx, + .ao_range_code = ao_range_code_64xx, + .ai_fifo = &ai_fifo_64xx, +@@ -651,7 +691,8 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_bits = 16, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, +- .ai_range_table = &ai_ranges_64xx, ++ .ai_range_table = &ai_ranges_64_mx, ++ .ai_range_code = ai_range_code_64_mx, + .ao_range_table = &ao_ranges_64xx, + .ao_range_code = ao_range_code_64xx, + .ai_fifo = &ai_fifo_64xx, +@@ -667,7 +708,8 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_bits = 16, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, +- .ai_range_table = &ai_ranges_64xx, ++ .ai_range_table = &ai_ranges_64_mx, ++ .ai_range_code = ai_range_code_64_mx, + .ao_range_table = &ao_ranges_64xx, + .ao_range_code = ao_range_code_64xx, + .ai_fifo = &ai_fifo_64xx, +@@ -683,7 +725,8 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_bits = 16, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, +- .ai_range_table = &ai_ranges_64xx, ++ .ai_range_table = &ai_ranges_64_mx, ++ .ai_range_code = ai_range_code_64_mx, + .ao_range_table = &ao_ranges_64xx, + .ao_range_code = ao_range_code_64xx, + .ai_fifo = &ai_fifo_64xx, +@@ -699,6 +742,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_bits = 16, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, ++ .ai_range_code = ai_range_code_60xx, + .ao_range_table = &ao_ranges_60xx, + .ao_range_code = ao_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, +@@ -715,6 +759,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 100000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, ++ .ai_range_code = ai_range_code_60xx, + .ao_range_table = &ao_ranges_60xx, + .ao_range_code = ao_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, +@@ -730,6 +775,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 100000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, ++ .ai_range_code = ai_range_code_60xx, + .ao_range_table = &ao_ranges_60xx, + .ao_range_code = ao_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, +@@ -746,6 +792,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 100000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, ++ .ai_range_code = ai_range_code_60xx, + .ao_range_table = &ao_ranges_60xx, + .ao_range_code = ao_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, +@@ -762,6 +809,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 10000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6030, ++ .ai_range_code = ai_range_code_6030, + .ao_range_table = &ao_ranges_6030, + .ao_range_code = ao_range_code_6030, + .ai_fifo = &ai_fifo_60xx, +@@ -778,6 +826,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 10000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6030, ++ .ai_range_code = ai_range_code_6030, + .ao_range_table = &ao_ranges_6030, + .ao_range_code = ao_range_code_6030, + .ai_fifo = &ai_fifo_60xx, +@@ -792,6 +841,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_nchan = 0, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6030, ++ .ai_range_code = ai_range_code_6030, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, +@@ -804,6 +854,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_nchan = 0, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6030, ++ .ai_range_code = ai_range_code_6030, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, +@@ -817,6 +868,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 0, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, ++ .ai_range_code = ai_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, + .has_8255 = 0, + }, +@@ -831,6 +883,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 100000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, ++ .ai_range_code = ai_range_code_60xx, + .ao_range_table = &ao_ranges_60xx, + .ao_range_code = ao_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, +@@ -847,6 +900,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 100000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_60xx, ++ .ai_range_code = ai_range_code_60xx, + .ao_range_table = &ao_ranges_60xx, + .ao_range_code = ao_range_code_60xx, + .ai_fifo = &ai_fifo_60xx, +@@ -863,6 +917,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 1000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6052, ++ .ai_range_code = ai_range_code_6052, + .ao_range_table = &ao_ranges_6030, + .ao_range_code = ao_range_code_6030, + .ai_fifo = &ai_fifo_60xx, +@@ -879,6 +934,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 3333, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6052, ++ .ai_range_code = ai_range_code_6052, + .ao_range_table = &ao_ranges_6030, + .ao_range_code = ao_range_code_6030, + .ai_fifo = &ai_fifo_60xx, +@@ -895,6 +951,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 1000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6052, ++ .ai_range_code = ai_range_code_6052, + .ao_range_table = &ao_ranges_6030, + .ao_range_code = ao_range_code_6030, + .ai_fifo = &ai_fifo_60xx, +@@ -911,6 +968,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 1000, + .layout = LAYOUT_60XX, + .ai_range_table = &ai_ranges_6052, ++ .ai_range_code = ai_range_code_6052, + .ao_range_table = &ao_ranges_6030, + .ao_range_code = ao_range_code_6030, + .ai_fifo = &ai_fifo_60xx, +@@ -943,6 +1001,7 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, + .ai_range_table = &ai_ranges_64xx, ++ .ai_range_code = ai_range_code_64xx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, +@@ -955,7 +1014,8 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_nchan = 0, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, +- .ai_range_table = &ai_ranges_64xx, ++ .ai_range_table = &ai_ranges_64_mx, ++ .ai_range_code = ai_range_code_64_mx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, +@@ -968,7 +1028,8 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_nchan = 0, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, +- .ai_range_table = &ai_ranges_64xx, ++ .ai_range_table = &ai_ranges_64_mx, ++ .ai_range_code = ai_range_code_64_mx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, +@@ -981,7 +1042,8 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_nchan = 0, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, +- .ai_range_table = &ai_ranges_64xx, ++ .ai_range_table = &ai_ranges_64_mx, ++ .ai_range_code = ai_range_code_64_mx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, +@@ -994,7 +1056,8 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_nchan = 2, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, +- .ai_range_table = &ai_ranges_64xx, ++ .ai_range_table = &ai_ranges_64_mx, ++ .ai_range_code = ai_range_code_64_mx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, +@@ -1007,7 +1070,8 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_nchan = 2, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, +- .ai_range_table = &ai_ranges_64xx, ++ .ai_range_table = &ai_ranges_64_mx, ++ .ai_range_code = ai_range_code_64_mx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, +@@ -1020,7 +1084,8 @@ static const struct pcidas64_board pcidas64_boards[] = { + .ao_nchan = 2, + .ao_scan_speed = 10000, + .layout = LAYOUT_64XX, +- .ai_range_table = &ai_ranges_64xx, ++ .ai_range_table = &ai_ranges_64_mx, ++ .ai_range_code = ai_range_code_64_mx, + .ai_fifo = ai_fifo_64xx, + .has_8255 = 1, + }, +@@ -1258,45 +1323,7 @@ module_exit(driver_cb_pcidas_cleanup_module); + static unsigned int ai_range_bits_6xxx(const struct comedi_device *dev, + unsigned int range_index) + { +- const struct comedi_krange *range = +- &board(dev)->ai_range_table->range[range_index]; +- unsigned int bits = 0; +- +- switch (range->max) { +- case 10000000: +- bits = 0x000; +- break; +- case 5000000: +- bits = 0x100; +- break; +- case 2000000: +- case 2500000: +- bits = 0x200; +- break; +- case 1000000: +- case 1250000: +- bits = 0x300; +- break; +- case 500000: +- bits = 0x400; +- break; +- case 200000: +- case 250000: +- bits = 0x500; +- break; +- case 100000: +- bits = 0x600; +- break; +- case 50000: +- bits = 0x700; +- break; +- default: +- comedi_error(dev, "bug! in ai_range_bits_6xxx"); +- break; +- } +- if (range->min == 0) +- bits += 0x900; +- return bits; ++ return board(dev)->ai_range_code[range_index] << 8; + } + + static unsigned int hw_revision(const struct comedi_device *dev, +diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h +index 3777d13..7a2e7b8 100644 +--- a/fs/nilfs2/nilfs.h ++++ b/fs/nilfs2/nilfs.h +@@ -128,7 +128,6 @@ enum { + * @ti_save: Backup of journal_info field of task_struct + * @ti_flags: Flags + * @ti_count: Nest level +- * @ti_garbage: List of inode to be put when releasing semaphore + */ + struct nilfs_transaction_info { + u32 ti_magic; +@@ -137,7 +136,6 @@ struct nilfs_transaction_info { + one of other filesystems has a bug. */ + unsigned short ti_flags; + unsigned short ti_count; +- struct list_head ti_garbage; + }; + + /* ti_magic */ +diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c +index 3ceaced..eb7f6a6 100644 +--- a/fs/nilfs2/segment.c ++++ b/fs/nilfs2/segment.c +@@ -302,7 +302,6 @@ static void nilfs_transaction_lock(struct super_block *sb, + ti->ti_count = 0; + ti->ti_save = cur_ti; + ti->ti_magic = NILFS_TI_MAGIC; +- INIT_LIST_HEAD(&ti->ti_garbage); + current->journal_info = ti; + + for (;;) { +@@ -329,8 +328,6 @@ static void nilfs_transaction_unlock(struct super_block *sb) + + up_write(&nilfs->ns_segctor_sem); + current->journal_info = ti->ti_save; +- if (!list_empty(&ti->ti_garbage)) +- nilfs_dispose_list(nilfs, &ti->ti_garbage, 0); + } + + static void *nilfs_segctor_map_segsum_entry(struct nilfs_sc_info *sci, +@@ -743,6 +740,15 @@ static void nilfs_dispose_list(struct the_nilfs *nilfs, + } + } + ++static void nilfs_iput_work_func(struct work_struct *work) ++{ ++ struct nilfs_sc_info *sci = container_of(work, struct nilfs_sc_info, ++ sc_iput_work); ++ struct the_nilfs *nilfs = sci->sc_super->s_fs_info; ++ ++ nilfs_dispose_list(nilfs, &sci->sc_iput_queue, 0); ++} ++ + static int nilfs_test_metadata_dirty(struct the_nilfs *nilfs, + struct nilfs_root *root) + { +@@ -1896,8 +1902,8 @@ static int nilfs_segctor_collect_dirty_files(struct nilfs_sc_info *sci, + static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci, + struct the_nilfs *nilfs) + { +- struct nilfs_transaction_info *ti = current->journal_info; + struct nilfs_inode_info *ii, *n; ++ int defer_iput = false; + + spin_lock(&nilfs->ns_inode_lock); + list_for_each_entry_safe(ii, n, &sci->sc_dirty_files, i_dirty) { +@@ -1908,9 +1914,24 @@ static void nilfs_segctor_drop_written_files(struct nilfs_sc_info *sci, + clear_bit(NILFS_I_BUSY, &ii->i_state); + brelse(ii->i_bh); + ii->i_bh = NULL; +- list_move_tail(&ii->i_dirty, &ti->ti_garbage); ++ list_del_init(&ii->i_dirty); ++ if (!ii->vfs_inode.i_nlink) { ++ /* ++ * Defer calling iput() to avoid a deadlock ++ * over I_SYNC flag for inodes with i_nlink == 0 ++ */ ++ list_add_tail(&ii->i_dirty, &sci->sc_iput_queue); ++ defer_iput = true; ++ } else { ++ spin_unlock(&nilfs->ns_inode_lock); ++ iput(&ii->vfs_inode); ++ spin_lock(&nilfs->ns_inode_lock); ++ } + } + spin_unlock(&nilfs->ns_inode_lock); ++ ++ if (defer_iput) ++ schedule_work(&sci->sc_iput_work); + } + + /* +@@ -2577,6 +2598,8 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb, + INIT_LIST_HEAD(&sci->sc_segbufs); + INIT_LIST_HEAD(&sci->sc_write_logs); + INIT_LIST_HEAD(&sci->sc_gc_inodes); ++ INIT_LIST_HEAD(&sci->sc_iput_queue); ++ INIT_WORK(&sci->sc_iput_work, nilfs_iput_work_func); + init_timer(&sci->sc_timer); + + sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT; +@@ -2603,6 +2626,8 @@ static void nilfs_segctor_write_out(struct nilfs_sc_info *sci) + ret = nilfs_segctor_construct(sci, SC_LSEG_SR); + nilfs_transaction_unlock(sci->sc_super); + ++ flush_work(&sci->sc_iput_work); ++ + } while (ret && retrycount-- > 0); + } + +@@ -2627,6 +2652,9 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) + || sci->sc_seq_request != sci->sc_seq_done); + spin_unlock(&sci->sc_state_lock); + ++ if (flush_work(&sci->sc_iput_work)) ++ flag = true; ++ + if (flag || !nilfs_segctor_confirm(sci)) + nilfs_segctor_write_out(sci); + +@@ -2636,6 +2664,12 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci) + nilfs_dispose_list(nilfs, &sci->sc_dirty_files, 1); + } + ++ if (!list_empty(&sci->sc_iput_queue)) { ++ nilfs_warning(sci->sc_super, __func__, ++ "iput queue is not empty\n"); ++ nilfs_dispose_list(nilfs, &sci->sc_iput_queue, 1); ++ } ++ + WARN_ON(!list_empty(&sci->sc_segbufs)); + WARN_ON(!list_empty(&sci->sc_write_logs)); + +diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h +index 38a1d00..a48d6de 100644 +--- a/fs/nilfs2/segment.h ++++ b/fs/nilfs2/segment.h +@@ -26,6 +26,7 @@ + #include <linux/types.h> + #include <linux/fs.h> + #include <linux/buffer_head.h> ++#include <linux/workqueue.h> + #include <linux/nilfs2_fs.h> + #include "nilfs.h" + +@@ -92,6 +93,8 @@ struct nilfs_segsum_pointer { + * @sc_nblk_inc: Block count of current generation + * @sc_dirty_files: List of files to be written + * @sc_gc_inodes: List of GC inodes having blocks to be written ++ * @sc_iput_queue: list of inodes for which iput should be done ++ * @sc_iput_work: work struct to defer iput call + * @sc_freesegs: array of segment numbers to be freed + * @sc_nfreesegs: number of segments on @sc_freesegs + * @sc_dsync_inode: inode whose data pages are written for a sync operation +@@ -135,6 +138,8 @@ struct nilfs_sc_info { + + struct list_head sc_dirty_files; + struct list_head sc_gc_inodes; ++ struct list_head sc_iput_queue; ++ struct work_struct sc_iput_work; + + __u64 *sc_freesegs; + size_t sc_nfreesegs; +diff --git a/include/sound/ak4113.h b/include/sound/ak4113.h +index 2609048..3a34f6e 100644 +--- a/include/sound/ak4113.h ++++ b/include/sound/ak4113.h +@@ -286,7 +286,7 @@ struct ak4113 { + ak4113_write_t *write; + ak4113_read_t *read; + void *private_data; +- unsigned int init:1; ++ atomic_t wq_processing; + spinlock_t lock; + unsigned char regmap[AK4113_WRITABLE_REGS]; + struct snd_kcontrol *kctls[AK4113_CONTROLS]; +diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h +index 3ce69fd..6944116 100644 +--- a/include/sound/ak4114.h ++++ b/include/sound/ak4114.h +@@ -168,7 +168,7 @@ struct ak4114 { + ak4114_write_t * write; + ak4114_read_t * read; + void * private_data; +- unsigned int init: 1; ++ atomic_t wq_processing; + spinlock_t lock; + unsigned char regmap[7]; + unsigned char txcsb[5]; +diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c +index f57fda7..bd4afa4 100644 +--- a/kernel/sched_rt.c ++++ b/kernel/sched_rt.c +@@ -1067,7 +1067,12 @@ select_task_rq_rt(struct task_struct *p, int sd_flag, int flags) + (p->rt.nr_cpus_allowed > 1)) { + int target = find_lowest_rq(p); + +- if (target != -1) ++ /* ++ * Don't bother moving it if the destination CPU is ++ * not running a lower priority task. ++ */ ++ if (target != -1 && ++ p->prio < cpu_rq(target)->rt.highest_prio.curr) + cpu = target; + } + rcu_read_unlock(); +@@ -1346,6 +1351,16 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq) + + lowest_rq = cpu_rq(cpu); + ++ if (lowest_rq->rt.highest_prio.curr <= task->prio) { ++ /* ++ * Target rq has tasks of equal or higher priority, ++ * retrying does not release any lock and is unlikely ++ * to yield a different result. ++ */ ++ lowest_rq = NULL; ++ break; ++ } ++ + /* if the prio of this runqueue changed, try again */ + if (double_lock_balance(rq, lowest_rq)) { + /* +diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c +index f1eb182..34fd01e 100644 +--- a/kernel/time/ntp.c ++++ b/kernel/time/ntp.c +@@ -608,6 +608,17 @@ int do_adjtimex(struct timex *txc) + return -EINVAL; + } + ++ /* ++ * Check for potential multiplication overflows that can ++ * only happen on 64-bit systems: ++ */ ++ if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) { ++ if (LLONG_MIN / PPM_SCALE > txc->freq) ++ return -EINVAL; ++ if (LLONG_MAX / PPM_SCALE < txc->freq) ++ return -EINVAL; ++ } ++ + if (txc->modes & ADJ_SETOFFSET) { + struct timespec delta; + delta.tv_sec = txc->time.tv_sec; +diff --git a/lib/checksum.c b/lib/checksum.c +index 8df2f91..62282bb 100644 +--- a/lib/checksum.c ++++ b/lib/checksum.c +@@ -179,6 +179,15 @@ csum_partial_copy(const void *src, void *dst, int len, __wsum sum) + EXPORT_SYMBOL(csum_partial_copy); + + #ifndef csum_tcpudp_nofold ++static inline u32 from64to32(u64 x) ++{ ++ /* add up 32-bit and 32-bit for 32+c bit */ ++ x = (x & 0xffffffff) + (x >> 32); ++ /* add up carry.. */ ++ x = (x & 0xffffffff) + (x >> 32); ++ return (u32)x; ++} ++ + __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + unsigned short len, + unsigned short proto, +@@ -193,8 +202,7 @@ __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + #else + s += (proto + len) << 8; + #endif +- s += (s >> 32); +- return (__force __wsum)s; ++ return (__force __wsum)from64to32(s); + } + EXPORT_SYMBOL(csum_tcpudp_nofold); + #endif +diff --git a/mm/pagewalk.c b/mm/pagewalk.c +index 1090e77..fdc255e 100644 +--- a/mm/pagewalk.c ++++ b/mm/pagewalk.c +@@ -200,7 +200,10 @@ int walk_page_range(unsigned long addr, unsigned long end, + */ + if ((vma->vm_start <= addr) && + (vma->vm_flags & VM_PFNMAP)) { +- next = vma->vm_end; ++ if (walk->pte_hole) ++ err = walk->pte_hole(addr, next, walk); ++ if (err) ++ break; + pgd = pgd_offset(walk->mm, next); + continue; + } +diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c +index 8656909..b525aec 100644 +--- a/net/caif/chnl_net.c ++++ b/net/caif/chnl_net.c +@@ -464,7 +464,6 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev, + ASSERT_RTNL(); + caifdev = netdev_priv(dev); + caif_netlink_parms(data, &caifdev->conn_req); +- dev_net_set(caifdev->netdev, src_net); + + ret = register_netdevice(dev); + if (ret) +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index 443724f..ad62afc 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1276,9 +1276,9 @@ static int fib6_walk_continue(struct fib6_walker_t *w) + if (w->leaf && fn->fn_flags&RTN_RTINFO) { + int err; + +- if (w->count < w->skip) { +- w->count++; +- continue; ++ if (w->skip) { ++ w->skip--; ++ goto skip; + } + + err = w->func(w); +@@ -1288,6 +1288,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) + w->count++; + continue; + } ++skip: + w->state = FWS_U; + case FWS_U: + if (fn == w->root) +diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c +index c40952c..743a644 100644 +--- a/net/sctp/sm_make_chunk.c ++++ b/net/sctp/sm_make_chunk.c +@@ -2569,7 +2569,7 @@ do_addr_param: + + addr_param = param.v + sizeof(sctp_addip_param_t); + +- af = sctp_get_af_specific(param_type2af(param.p->type)); ++ af = sctp_get_af_specific(param_type2af(addr_param->p.type)); + if (af == NULL) + break; + +diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c +index dde5c9c..e1ab3ad 100644 +--- a/sound/i2c/other/ak4113.c ++++ b/sound/i2c/other/ak4113.c +@@ -56,8 +56,7 @@ static inline unsigned char reg_read(struct ak4113 *ak4113, unsigned char reg) + + static void snd_ak4113_free(struct ak4113 *chip) + { +- chip->init = 1; /* don't schedule new work */ +- mb(); ++ atomic_inc(&chip->wq_processing); /* don't schedule new work */ + cancel_delayed_work_sync(&chip->work); + kfree(chip); + } +@@ -89,6 +88,7 @@ int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, + chip->write = write; + chip->private_data = private_data; + INIT_DELAYED_WORK(&chip->work, ak4113_stats); ++ atomic_set(&chip->wq_processing, 0); + + for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++) + chip->regmap[reg] = pgm[reg]; +@@ -139,13 +139,11 @@ static void ak4113_init_regs(struct ak4113 *chip) + + void snd_ak4113_reinit(struct ak4113 *chip) + { +- chip->init = 1; +- mb(); +- flush_delayed_work_sync(&chip->work); ++ if (atomic_inc_return(&chip->wq_processing) == 1) ++ cancel_delayed_work_sync(&chip->work); + ak4113_init_regs(chip); + /* bring up statistics / event queing */ +- chip->init = 0; +- if (chip->kctls[0]) ++ if (atomic_dec_and_test(&chip->wq_processing)) + schedule_delayed_work(&chip->work, HZ / 10); + } + EXPORT_SYMBOL_GPL(snd_ak4113_reinit); +@@ -632,8 +630,9 @@ static void ak4113_stats(struct work_struct *work) + { + struct ak4113 *chip = container_of(work, struct ak4113, work.work); + +- if (!chip->init) ++ if (atomic_inc_return(&chip->wq_processing) == 1) + snd_ak4113_check_rate_and_errors(chip, chip->check_flags); + +- schedule_delayed_work(&chip->work, HZ / 10); ++ if (atomic_dec_and_test(&chip->wq_processing)) ++ schedule_delayed_work(&chip->work, HZ / 10); + } +diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c +index fdf3c1b..4c6b379 100644 +--- a/sound/i2c/other/ak4114.c ++++ b/sound/i2c/other/ak4114.c +@@ -66,8 +66,7 @@ static void reg_dump(struct ak4114 *ak4114) + + static void snd_ak4114_free(struct ak4114 *chip) + { +- chip->init = 1; /* don't schedule new work */ +- mb(); ++ atomic_inc(&chip->wq_processing); /* don't schedule new work */ + cancel_delayed_work_sync(&chip->work); + kfree(chip); + } +@@ -100,6 +99,7 @@ int snd_ak4114_create(struct snd_card *card, + chip->write = write; + chip->private_data = private_data; + INIT_DELAYED_WORK(&chip->work, ak4114_stats); ++ atomic_set(&chip->wq_processing, 0); + + for (reg = 0; reg < 7; reg++) + chip->regmap[reg] = pgm[reg]; +@@ -152,13 +152,11 @@ static void ak4114_init_regs(struct ak4114 *chip) + + void snd_ak4114_reinit(struct ak4114 *chip) + { +- chip->init = 1; +- mb(); +- flush_delayed_work_sync(&chip->work); ++ if (atomic_inc_return(&chip->wq_processing) == 1) ++ cancel_delayed_work_sync(&chip->work); + ak4114_init_regs(chip); + /* bring up statistics / event queing */ +- chip->init = 0; +- if (chip->kctls[0]) ++ if (atomic_dec_and_test(&chip->wq_processing)) + schedule_delayed_work(&chip->work, HZ / 10); + } + +@@ -612,10 +610,10 @@ static void ak4114_stats(struct work_struct *work) + { + struct ak4114 *chip = container_of(work, struct ak4114, work.work); + +- if (!chip->init) ++ if (atomic_inc_return(&chip->wq_processing) == 1) + snd_ak4114_check_rate_and_errors(chip, chip->check_flags); +- +- schedule_delayed_work(&chip->work, HZ / 10); ++ if (atomic_dec_and_test(&chip->wq_processing)) ++ schedule_delayed_work(&chip->work, HZ / 10); + } + + EXPORT_SYMBOL(snd_ak4114_create); +diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c +index 7122509..361078d 100644 +--- a/sound/soc/atmel/atmel_ssc_dai.c ++++ b/sound/soc/atmel/atmel_ssc_dai.c +@@ -341,7 +341,6 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, + struct atmel_pcm_dma_params *dma_params; + int dir, channels, bits; + u32 tfmr, rfmr, tcmr, rcmr; +- int start_event; + int ret; + + /* +@@ -460,19 +459,10 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, + * The SSC transmit clock is obtained from the BCLK signal on + * on the TK line, and the SSC receive clock is + * generated from the transmit clock. +- * +- * For single channel data, one sample is transferred +- * on the falling edge of the LRC clock. +- * For two channel data, one sample is +- * transferred on both edges of the LRC clock. + */ +- start_event = ((channels == 1) +- ? SSC_START_FALLING_RF +- : SSC_START_EDGE_RF); +- + rcmr = SSC_BF(RCMR_PERIOD, 0) + | SSC_BF(RCMR_STTDLY, START_DELAY) +- | SSC_BF(RCMR_START, start_event) ++ | SSC_BF(RCMR_START, SSC_START_FALLING_RF) + | SSC_BF(RCMR_CKI, SSC_CKI_RISING) + | SSC_BF(RCMR_CKO, SSC_CKO_NONE) + | SSC_BF(RCMR_CKS, SSC_CKS_CLOCK); +@@ -480,14 +470,14 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, + rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) + | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) + | SSC_BF(RFMR_FSLEN, 0) +- | SSC_BF(RFMR_DATNB, 0) ++ | SSC_BF(RFMR_DATNB, (channels - 1)) + | SSC_BIT(RFMR_MSBF) + | SSC_BF(RFMR_LOOP, 0) + | SSC_BF(RFMR_DATLEN, (bits - 1)); + + tcmr = SSC_BF(TCMR_PERIOD, 0) + | SSC_BF(TCMR_STTDLY, START_DELAY) +- | SSC_BF(TCMR_START, start_event) ++ | SSC_BF(TCMR_START, SSC_START_FALLING_RF) + | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) + | SSC_BF(TCMR_CKO, SSC_CKO_NONE) + | SSC_BF(TCMR_CKS, SSC_CKS_PIN); +@@ -496,7 +486,7 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, + | SSC_BF(TFMR_FSDEN, 0) + | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) + | SSC_BF(TFMR_FSLEN, 0) +- | SSC_BF(TFMR_DATNB, 0) ++ | SSC_BF(TFMR_DATNB, (channels - 1)) + | SSC_BIT(TFMR_MSBF) + | SSC_BF(TFMR_DATDEF, 0) + | SSC_BF(TFMR_DATLEN, (bits - 1)); |