diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2012-07-17 12:04:20 +0200 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2012-07-17 12:04:20 +0200 |
commit | 8ce44a2174c3b07950d7a8d44774e23e60518205 (patch) | |
tree | 4bf04cdeed59775462d5326d3bcb00c7343b6163 /drivers | |
parent | f9a4f063a88297e361fd6676986cf3e39b22de72 (diff) | |
parent | 84a1caf1453c3d44050bd22db958af4a7f99315c (diff) | |
download | linux-8ce44a2174c3b07950d7a8d44774e23e60518205.tar.gz linux-8ce44a2174c3b07950d7a8d44774e23e60518205.tar.bz2 linux-8ce44a2174c3b07950d7a8d44774e23e60518205.zip |
Merge tag 'v3.5-rc7' into arm/tegra
This solves the merge conflicts while creating the next
branch.
Linux 3.5-rc7
Conflicts:
drivers/iommu/tegra-smmu.c
Diffstat (limited to 'drivers')
382 files changed, 2882 insertions, 1693 deletions
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index a43fa1a57d57..1502c50273b5 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -36,6 +36,7 @@ #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" #define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80 static DEFINE_MUTEX(isolated_cpus_lock); +static DEFINE_MUTEX(round_robin_lock); static unsigned long power_saving_mwait_eax; @@ -107,7 +108,7 @@ static void round_robin_cpu(unsigned int tsk_index) if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) return; - mutex_lock(&isolated_cpus_lock); + mutex_lock(&round_robin_lock); cpumask_clear(tmp); for_each_cpu(cpu, pad_busy_cpus) cpumask_or(tmp, tmp, topology_thread_cpumask(cpu)); @@ -116,7 +117,7 @@ static void round_robin_cpu(unsigned int tsk_index) if (cpumask_empty(tmp)) cpumask_andnot(tmp, cpu_online_mask, pad_busy_cpus); if (cpumask_empty(tmp)) { - mutex_unlock(&isolated_cpus_lock); + mutex_unlock(&round_robin_lock); return; } for_each_cpu(cpu, tmp) { @@ -131,7 +132,7 @@ static void round_robin_cpu(unsigned int tsk_index) tsk_in_cpu[tsk_index] = preferred_cpu; cpumask_set_cpu(preferred_cpu, pad_busy_cpus); cpu_weight[preferred_cpu]++; - mutex_unlock(&isolated_cpus_lock); + mutex_unlock(&round_robin_lock); set_cpus_allowed_ptr(current, cpumask_of(preferred_cpu)); } diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 0ed85cac3231..615996a36bed 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 23ce09686418..fe6626035495 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/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 5577762daee1..6686b1eaf13e 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -243,7 +243,7 @@ static int pre_map_gar_callback(struct apei_exec_context *ctx, u8 ins = entry->instruction; if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) - return acpi_os_map_generic_address(&entry->register_region); + return apei_map_generic_address(&entry->register_region); return 0; } @@ -276,7 +276,7 @@ static int post_unmap_gar_callback(struct apei_exec_context *ctx, u8 ins = entry->instruction; if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) - acpi_os_unmap_generic_address(&entry->register_region); + apei_unmap_generic_address(&entry->register_region); return 0; } @@ -606,6 +606,19 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr, return 0; } +int apei_map_generic_address(struct acpi_generic_address *reg) +{ + int rc; + u32 access_bit_width; + u64 address; + + rc = apei_check_gar(reg, &address, &access_bit_width); + if (rc) + return rc; + return acpi_os_map_generic_address(reg); +} +EXPORT_SYMBOL_GPL(apei_map_generic_address); + /* read GAR in interrupt (including NMI) or process context */ int apei_read(u64 *val, struct acpi_generic_address *reg) { diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h index cca240a33038..f220d642136e 100644 --- a/drivers/acpi/apei/apei-internal.h +++ b/drivers/acpi/apei/apei-internal.h @@ -7,6 +7,8 @@ #define APEI_INTERNAL_H #include <linux/cper.h> +#include <linux/acpi.h> +#include <linux/acpi_io.h> struct apei_exec_context; @@ -68,6 +70,13 @@ static inline int apei_exec_run_optional(struct apei_exec_context *ctx, u8 actio /* IP has been set in instruction function */ #define APEI_EXEC_SET_IP 1 +int apei_map_generic_address(struct acpi_generic_address *reg); + +static inline void apei_unmap_generic_address(struct acpi_generic_address *reg) +{ + acpi_os_unmap_generic_address(reg); +} + int apei_read(u64 *val, struct acpi_generic_address *reg); int apei_write(u64 val, struct acpi_generic_address *reg); diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 9b3cac0abecc..1599566ed1fe 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -301,7 +301,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) if (!ghes) return ERR_PTR(-ENOMEM); ghes->generic = generic; - rc = acpi_os_map_generic_address(&generic->error_status_address); + rc = apei_map_generic_address(&generic->error_status_address); if (rc) goto err_free; error_block_length = generic->error_block_length; @@ -321,7 +321,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) return ghes; err_unmap: - acpi_os_unmap_generic_address(&generic->error_status_address); + apei_unmap_generic_address(&generic->error_status_address); err_free: kfree(ghes); return ERR_PTR(rc); @@ -330,7 +330,7 @@ err_free: static void ghes_fini(struct ghes *ghes) { kfree(ghes->estatus); - acpi_os_unmap_generic_address(&ghes->generic->error_status_address); + apei_unmap_generic_address(&ghes->generic->error_status_address); } enum { diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index c850de4c9a14..eff722278ff5 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/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f3decb30223f..47a8caa89dbe 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -224,6 +224,7 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr, /* * Suspend / resume control */ +static int acpi_idle_suspend; static u32 saved_bm_rld; static void acpi_idle_bm_rld_save(void) @@ -242,13 +243,21 @@ static void acpi_idle_bm_rld_restore(void) int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) { + if (acpi_idle_suspend == 1) + return 0; + acpi_idle_bm_rld_save(); + acpi_idle_suspend = 1; return 0; } int acpi_processor_resume(struct acpi_device * device) { + if (acpi_idle_suspend == 0) + return 0; + acpi_idle_bm_rld_restore(); + acpi_idle_suspend = 0; return 0; } @@ -754,6 +763,12 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, local_irq_disable(); + if (acpi_idle_suspend) { + local_irq_enable(); + cpu_relax(); + return -EBUSY; + } + lapic_timer_state_broadcast(pr, cx, 1); kt1 = ktime_get_real(); acpi_idle_do_entry(cx); @@ -823,6 +838,12 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, local_irq_disable(); + if (acpi_idle_suspend) { + local_irq_enable(); + cpu_relax(); + return -EBUSY; + } + if (cx->entry_method != ACPI_CSTATE_FFH) { current_thread_info()->status &= ~TS_POLLING; /* @@ -907,14 +928,21 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, drv, drv->safe_state_index); } else { local_irq_disable(); - acpi_safe_halt(); + if (!acpi_idle_suspend) + acpi_safe_halt(); local_irq_enable(); - return -EINVAL; + return -EBUSY; } } local_irq_disable(); + if (acpi_idle_suspend) { + local_irq_enable(); + cpu_relax(); + return -EBUSY; + } + if (cx->entry_method != ACPI_CSTATE_FFH) { current_thread_info()->status &= ~TS_POLLING; /* diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 9f66181c814e..240a24400976 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -173,7 +173,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) { int result = 0; - if (!strncmp(val, "enable", strlen("enable") - 1)) { + if (!strncmp(val, "enable", strlen("enable"))) { result = acpi_debug_trace(trace_method_name, trace_debug_level, trace_debug_layer, 0); if (result) @@ -181,7 +181,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) goto exit; } - if (!strncmp(val, "disable", strlen("disable") - 1)) { + if (!strncmp(val, "disable", strlen("disable"))) { int name = 0; result = acpi_debug_trace((char *)&name, trace_debug_level, trace_debug_layer, 0); diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index a576575617d7..1e0a9e17c31d 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -558,6 +558,8 @@ acpi_video_bus_DOS(struct acpi_video_bus *video, int bios_flag, int lcd_flag) union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; + if (!video->cap._DOS) + return 0; if (bios_flag < 0 || bios_flag > 3 || lcd_flag < 0 || lcd_flag > 1) return -EINVAL; diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 3239517f4d90..ac6a5beb28f3 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -4,7 +4,7 @@ * Arasan Compact Flash host controller source file * * Copyright (C) 2011 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -959,7 +959,7 @@ static struct platform_driver arasan_cf_driver = { module_platform_driver(arasan_cf_driver); -MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); +MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); MODULE_DESCRIPTION("Arasan ATA Compact Flash driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 1b1cbb571d38..dcb8a6e48692 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -100,7 +100,7 @@ static void driver_deferred_probe_add(struct device *dev) mutex_lock(&deferred_probe_mutex); if (list_empty(&dev->p->deferred_probe)) { dev_dbg(dev, "Added to deferred list\n"); - list_add(&dev->p->deferred_probe, &deferred_probe_pending_list); + list_add_tail(&dev->p->deferred_probe, &deferred_probe_pending_list); } mutex_unlock(&deferred_probe_mutex); } diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index e0fb5b0435a3..9cb845e49334 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1031,7 +1031,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) dpm_wait_for_children(dev, async); if (async_error) - return 0; + goto Complete; pm_runtime_get_noresume(dev); if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) @@ -1040,7 +1040,7 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) if (pm_wakeup_pending()) { pm_runtime_put_sync(dev); async_error = -EBUSY; - return 0; + goto Complete; } device_lock(dev); @@ -1097,6 +1097,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) } device_unlock(dev); + + Complete: complete_all(&dev->power.completion); if (error) { diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index b5c5ff53cb57..fcb956bb4b4c 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -1475,10 +1475,17 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi first_word = 0; spin_lock_irq(&b->bm_lock); } - /* last page (respectively only page, for first page == last page) */ last_word = MLPP(el >> LN2_BPL); - bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word); + + /* consider bitmap->bm_bits = 32768, bitmap->bm_number_of_pages = 1. (or multiples). + * ==> e = 32767, el = 32768, last_page = 2, + * and now last_word = 0. + * We do not want to touch last_page in this case, + * as we did not allocate it, it is not present in bitmap->bm_pages. + */ + if (last_word) + bm_set_full_words_within_one_page(mdev->bitmap, last_page, first_word, last_word); /* possibly trailing bits. * example: (e & 63) == 63, el will be e+1. diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index 9c5c84946b05..8e93a6ac9bb6 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -472,12 +472,17 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, req->rq_state |= RQ_LOCAL_COMPLETED; req->rq_state &= ~RQ_LOCAL_PENDING; - D_ASSERT(!(req->rq_state & RQ_NET_MASK)); + if (req->rq_state & RQ_LOCAL_ABORTED) { + _req_may_be_done(req, m); + break; + } __drbd_chk_io_error(mdev, false); goto_queue_for_net_read: + D_ASSERT(!(req->rq_state & RQ_NET_MASK)); + /* no point in retrying if there is no good remote data, * or we have no connection. */ if (mdev->state.pdsk != D_UP_TO_DATE) { @@ -765,6 +770,40 @@ static int drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int s return 0 == drbd_bm_count_bits(mdev, sbnr, ebnr); } +static void maybe_pull_ahead(struct drbd_conf *mdev) +{ + int congested = 0; + + /* If I don't even have good local storage, we can not reasonably try + * to pull ahead of the peer. We also need the local reference to make + * sure mdev->act_log is there. + * Note: caller has to make sure that net_conf is there. + */ + if (!get_ldev_if_state(mdev, D_UP_TO_DATE)) + return; + + if (mdev->net_conf->cong_fill && + atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) { + dev_info(DEV, "Congestion-fill threshold reached\n"); + congested = 1; + } + + if (mdev->act_log->used >= mdev->net_conf->cong_extents) { + dev_info(DEV, "Congestion-extents threshold reached\n"); + congested = 1; + } + + if (congested) { + queue_barrier(mdev); /* last barrier, after mirrored writes */ + + if (mdev->net_conf->on_congestion == OC_PULL_AHEAD) + _drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL); + else /*mdev->net_conf->on_congestion == OC_DISCONNECT */ + _drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL); + } + put_ldev(mdev); +} + static int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio, unsigned long start_time) { const int rw = bio_rw(bio); @@ -972,29 +1011,8 @@ allocate_barrier: _req_mod(req, queue_for_send_oos); if (remote && - mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) { - int congested = 0; - - if (mdev->net_conf->cong_fill && - atomic_read(&mdev->ap_in_flight) >= mdev->net_conf->cong_fill) { - dev_info(DEV, "Congestion-fill threshold reached\n"); - congested = 1; - } - - if (mdev->act_log->used >= mdev->net_conf->cong_extents) { - dev_info(DEV, "Congestion-extents threshold reached\n"); - congested = 1; - } - - if (congested) { - queue_barrier(mdev); /* last barrier, after mirrored writes */ - - if (mdev->net_conf->on_congestion == OC_PULL_AHEAD) - _drbd_set_state(_NS(mdev, conn, C_AHEAD), 0, NULL); - else /*mdev->net_conf->on_congestion == OC_DISCONNECT */ - _drbd_set_state(_NS(mdev, conn, C_DISCONNECTING), 0, NULL); - } - } + mdev->net_conf->on_congestion != OC_BLOCK && mdev->agreed_pro_version >= 96) + maybe_pull_ahead(mdev); spin_unlock_irq(&mdev->req_lock); kfree(b); /* if someone else has beaten us to it... */ diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index cce7df367b79..553f43a90953 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -671,6 +671,7 @@ static void __reschedule_timeout(int drive, const char *message) if (drive == current_reqD) drive = current_drive; + __cancel_delayed_work(&fd_timeout); if (drive < 0 || drive >= N_DRIVE) { delay = 20UL * HZ; diff --git a/drivers/block/loop.c b/drivers/block/loop.c index bbca966f8f66..3bba65510d23 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/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 264bc77dcb91..a8fddeb3d638 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -37,6 +37,7 @@ #include <linux/kthread.h> #include <../drivers/ata/ahci.h> #include <linux/export.h> +#include <linux/debugfs.h> #include "mtip32xx.h" #define HW_CMD_SLOT_SZ (MTIP_MAX_COMMAND_SLOTS * 32) @@ -85,6 +86,7 @@ static int instance; * allocated in mtip_init(). */ static int mtip_major; +static struct dentry *dfs_parent; static DEFINE_SPINLOCK(rssd_index_lock); static DEFINE_IDA(rssd_index_ida); @@ -2546,7 +2548,7 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, } /* - * Sysfs register/status dump. + * Sysfs status dump. * * @dev Pointer to the device structure, passed by the kernrel. * @attr Pointer to the device_attribute structure passed by the kernel. @@ -2555,45 +2557,68 @@ static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, * return value * The size, in bytes, of the data copied into buf. */ -static ssize_t mtip_hw_show_registers(struct device *dev, +static ssize_t mtip_hw_show_status(struct device *dev, struct device_attribute *attr, char *buf) { - u32 group_allocated; struct driver_data *dd = dev_to_disk(dev)->private_data; int size = 0; + + if (test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag)) + size += sprintf(buf, "%s", "thermal_shutdown\n"); + else if (test_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag)) + size += sprintf(buf, "%s", "write_protect\n"); + else + size += sprintf(buf, "%s", "online\n"); + + return size; +} + +static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); + +static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, + size_t len, loff_t *offset) +{ + struct driver_data *dd = (struct driver_data *)f->private_data; + char buf[MTIP_DFS_MAX_BUF_SIZE]; + u32 group_allocated; + int size = *offset; int n; - size += sprintf(&buf[size], "Hardware\n--------\n"); - size += sprintf(&buf[size], "S ACTive : [ 0x"); + if (!len || size) + return 0; + + if (size < 0) + return -EINVAL; + + size += sprintf(&buf[size], "H/ S ACTive : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) size += sprintf(&buf[size], "%08X ", readl(dd->port->s_active[n])); size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "Command Issue : [ 0x"); + size += sprintf(&buf[size], "H/ Command Issue : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) size += sprintf(&buf[size], "%08X ", readl(dd->port->cmd_issue[n])); size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "Completed : [ 0x"); + size += sprintf(&buf[size], "H/ Completed : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) size += sprintf(&buf[size], "%08X ", readl(dd->port->completed[n])); size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "PORT IRQ STAT : [ 0x%08X ]\n", + size += sprintf(&buf[size], "H/ PORT IRQ STAT : [ 0x%08X ]\n", readl(dd->port->mmio + PORT_IRQ_STAT)); - size += sprintf(&buf[size], "HOST IRQ STAT : [ 0x%08X ]\n", + size += sprintf(&buf[size], "H/ HOST IRQ STAT : [ 0x%08X ]\n", readl(dd->mmio + HOST_IRQ_STAT)); size += sprintf(&buf[size], "\n"); - size += sprintf(&buf[size], "Local\n-----\n"); - size += sprintf(&buf[size], "Allocated : [ 0x"); + size += sprintf(&buf[size], "L/ Allocated : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) { if (sizeof(long) > sizeof(u32)) @@ -2605,7 +2630,7 @@ static ssize_t mtip_hw_show_registers(struct device *dev, } size += sprintf(&buf[size], "]\n"); - size += sprintf(&buf[size], "Commands in Q: [ 0x"); + size += sprintf(&buf[size], "L/ Commands in Q : [ 0x"); for (n = dd->slot_groups-1; n >= 0; n--) { if (sizeof(long) > sizeof(u32)) @@ -2617,44 +2642,53 @@ static ssize_t mtip_hw_show_registers(struct device *dev, } size += sprintf(&buf[size], "]\n"); - return size; + *offset = size <= len ? size : len; + size = copy_to_user(ubuf, buf, *offset); + if (size) + return -EFAULT; + + return *offset; } -static ssize_t mtip_hw_show_status(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf, + size_t len, loff_t *offset) { - struct driver_data *dd = dev_to_disk(dev)->private_data; - int size = 0; + struct driver_data *dd = (struct driver_data *)f->private_data; + char buf[MTIP_DFS_MAX_BUF_SIZE]; + int size = *offset; - if (test_bit(MTIP_DDF_OVER_TEMP_BIT, &dd->dd_flag)) - size += sprintf(buf, "%s", "thermal_shutdown\n"); - else if (test_bit(MTIP_DDF_WRITE_PROTECT_BIT, &dd->dd_flag)) - size += sprintf(buf, "%s", "write_protect\n"); - else - size += sprintf(buf, "%s", "online\n"); - - return size; -} + if (!len || size) + return 0; -static ssize_t mtip_hw_show_flags(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct driver_data *dd = dev_to_disk(dev)->private_data; - int size = 0; + if (size < 0) + return -EINVAL; - size += sprintf(&buf[size], "Flag in port struct : [ %08lX ]\n", + size += sprintf(&buf[size], "Flag-port : [ %08lX ]\n", dd->port->flags); - size += sprintf(&buf[size], "Flag in dd struct : [ %08lX ]\n", + size += sprintf(&buf[size], "Flag-dd : [ %08lX ]\n", dd->dd_flag); - return size; + *offset = size <= len ? size : len; + size = copy_to_user(ubuf, buf, *offset); + if (size) + return -EFAULT; + + return *offset; } -static DEVICE_ATTR(registers, S_IRUGO, mtip_hw_show_registers, NULL); -static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); -static DEVICE_ATTR(flags, S_IRUGO, mtip_hw_show_flags, NULL); +static const struct file_operations mtip_regs_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = mtip_hw_read_registers, + .llseek = no_llseek, +}; + +static const struct file_operations mtip_flags_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = mtip_hw_read_flags, + .llseek = no_llseek, +}; /* * Create the sysfs related attributes. @@ -2671,15 +2705,9 @@ static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj) if (!kobj || !dd) return -EINVAL; - if (sysfs_create_file(kobj, &dev_attr_registers.attr)) - dev_warn(&dd->pdev->dev, - "Error creating 'registers' sysfs entry\n"); if (sysfs_create_file(kobj, &dev_attr_status.attr)) dev_warn(&dd->pdev->dev, "Error creating 'status' sysfs entry\n"); - if (sysfs_create_file(kobj, &dev_attr_flags.attr)) - dev_warn(&dd->pdev->dev, - "Error creating 'flags' sysfs entry\n"); return 0; } @@ -2698,13 +2726,39 @@ static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj) if (!kobj || !dd) return -EINVAL; - sysfs_remove_file(kobj, &dev_attr_registers.attr); sysfs_remove_file(kobj, &dev_attr_status.attr); - sysfs_remove_file(kobj, &dev_attr_flags.attr); return 0; } +static int mtip_hw_debugfs_init(struct driver_data *dd) +{ + if (!dfs_parent) + return -1; + + dd->dfs_node = debugfs_create_dir(dd->disk->disk_name, dfs_parent); + if (IS_ERR_OR_NULL(dd->dfs_node)) { + dev_warn(&dd->pdev->dev, + "Error creating node %s under debugfs\n", + dd->disk->disk_name); + dd->dfs_node = NULL; + return -1; + } + + debugfs_create_file("flags", S_IRUGO, dd->dfs_node, dd, + &mtip_flags_fops); + debugfs_create_file("registers", S_IRUGO, dd->dfs_node, dd, + &mtip_regs_fops); + + return 0; +} + +static void mtip_hw_debugfs_exit(struct driver_data *dd) +{ + debugfs_remove_recursive(dd->dfs_node); +} + + /* * Perform any init/resume time hardware setup * @@ -3730,6 +3784,7 @@ skip_create_disk: mtip_hw_sysfs_init(dd, kobj); kobject_put(kobj); } + mtip_hw_debugfs_init(dd); if (dd->mtip_svc_handler) { set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); @@ -3755,6 +3810,8 @@ start_service_thread: return rv; kthread_run_error: + mtip_hw_debugfs_exit(dd); + /* Delete our gendisk. This also removes the device from /dev */ del_gendisk(dd->disk); @@ -3805,6 +3862,7 @@ static int mtip_block_remove(struct driver_data *dd) kobject_put(kobj); } } + mtip_hw_debugfs_exit(dd); /* * Delete our gendisk structure. This also removes the device @@ -4152,10 +4210,20 @@ static int __init mtip_init(void) } mtip_major = error; + if (!dfs_parent) { + dfs_parent = debugfs_create_dir("rssd", NULL); + if (IS_ERR_OR_NULL(dfs_parent)) { + printk(KERN_WARNING "Error creating debugfs parent\n"); + dfs_parent = NULL; + } + } + /* Register our PCI operations. */ error = pci_register_driver(&mtip_pci_driver); - if (error) + if (error) { + debugfs_remove(dfs_parent); unregister_blkdev(mtip_major, MTIP_DRV_NAME); + } return error; } @@ -4172,6 +4240,8 @@ static int __init mtip_init(void) */ static void __exit mtip_exit(void) { + debugfs_remove_recursive(dfs_parent); + /* Release the allocated major block device number. */ unregister_blkdev(mtip_major, MTIP_DRV_NAME); diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index b2c88da26b2a..f51fc23d17bb 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -26,7 +26,6 @@ #include <linux/ata.h> #include <linux/interrupt.h> #include <linux/genhd.h> -#include <linux/version.h> /* Offset of Subsystem Device ID in pci confoguration space */ #define PCI_SUBSYSTEM_DEVICEID 0x2E @@ -111,6 +110,8 @@ #define dbg_printk(format, arg...) #endif +#define MTIP_DFS_MAX_BUF_SIZE 1024 + #define __force_bit2int (unsigned int __force) enum { @@ -447,6 +448,8 @@ struct driver_data { unsigned long dd_flag; /* NOTE: use atomic bit operations on this */ struct task_struct *mtip_svc_handler; /* task_struct of svc thd */ + + struct dentry *dfs_node; }; #endif diff --git a/drivers/block/umem.c b/drivers/block/umem.c index aa2712060bfb..9a72277a31df 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c @@ -513,6 +513,44 @@ static void process_page(unsigned long data) } } +struct mm_plug_cb { + struct blk_plug_cb cb; + struct cardinfo *card; +}; + +static void mm_unplug(struct blk_plug_cb *cb) +{ + struct mm_plug_cb *mmcb = container_of(cb, struct mm_plug_cb, cb); + + spin_lock_irq(&mmcb->card->lock); + activate(mmcb->card); + spin_unlock_irq(&mmcb->card->lock); + kfree(mmcb); +} + +static int mm_check_plugged(struct cardinfo *card) +{ + struct blk_plug *plug = current->plug; + struct mm_plug_cb *mmcb; + + if (!plug) + return 0; + + list_for_each_entry(mmcb, &plug->cb_list, cb.list) { + if (mmcb->cb.callback == mm_unplug && mmcb->card == card) + return 1; + } + /* Not currently on the callback list */ + mmcb = kmalloc(sizeof(*mmcb), GFP_ATOMIC); + if (!mmcb) + return 0; + + mmcb->card = card; + mmcb->cb.callback = mm_unplug; + list_add(&mmcb->cb.list, &plug->cb_list); + return 1; +} + static void mm_make_request(struct request_queue *q, struct bio *bio) { struct cardinfo *card = q->queuedata; @@ -523,6 +561,8 @@ static void mm_make_request(struct request_queue *q, struct bio *bio) *card->biotail = bio; bio->bi_next = NULL; card->biotail = &bio->bi_next; + if (bio->bi_rw & REQ_SYNC || !mm_check_plugged(card)) + activate(card); spin_unlock_irq(&card->lock); return; diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 773cf27dc23f..9ad3b5ec1dc1 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -257,6 +257,7 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, break; case BLKIF_OP_DISCARD: dst->u.discard.flag = src->u.discard.flag; + dst->u.discard.id = src->u.discard.id; dst->u.discard.sector_number = src->u.discard.sector_number; dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; @@ -287,6 +288,7 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst, break; case BLKIF_OP_DISCARD: dst->u.discard.flag = src->u.discard.flag; + dst->u.discard.id = src->u.discard.id; dst->u.discard.sector_number = src->u.discard.sector_number; dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 60eed4bdd2e4..e4fb3374dcd2 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -141,14 +141,36 @@ static int get_id_from_freelist(struct blkfront_info *info) return free; } -static void add_id_to_freelist(struct blkfront_info *info, +static int add_id_to_freelist(struct blkfront_info *info, unsigned long id) { + if (info->shadow[id].req.u.rw.id != id) + return -EINVAL; + if (info->shadow[id].request == NULL) + return -EINVAL; info->shadow[id].req.u.rw.id = info->shadow_free; info->shadow[id].request = NULL; info->shadow_free = id; + return 0; } +static const char *op_name(int op) +{ + static const char *const names[] = { + [BLKIF_OP_READ] = "read", + [BLKIF_OP_WRITE] = "write", + [BLKIF_OP_WRITE_BARRIER] = "barrier", + [BLKIF_OP_FLUSH_DISKCACHE] = "flush", + [BLKIF_OP_DISCARD] = "discard" }; + + if (op < 0 || op >= ARRAY_SIZE(names)) + return "unknown"; + + if (!names[op]) + return "reserved"; + + return names[op]; +} static int xlbd_reserve_minors(unsigned int minor, unsigned int nr) { unsigned int end = minor + nr; @@ -746,20 +768,36 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) bret = RING_GET_RESPONSE(&info->ring, i); id = bret->id; + /* + * The backend has messed up and given us an id that we would + * never have given to it (we stamp it up to BLK_RING_SIZE - + * look in get_id_from_freelist. + */ + if (id >= BLK_RING_SIZE) { + WARN(1, "%s: response to %s has incorrect id (%ld)\n", + info->gd->disk_name, op_name(bret->operation), id); + /* We can't safely get the 'struct request' as + * the id is busted. */ + continue; + } req = info->shadow[id].request; if (bret->operation != BLKIF_OP_DISCARD) blkif_completion(&info->shadow[id]); - add_id_to_freelist(info, id); + if (add_id_to_freelist(info, id)) { + WARN(1, "%s: response to %s (id %ld) couldn't be recycled!\n", + info->gd->disk_name, op_name(bret->operation), id); + continue; + } error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO; switch (bret->operation) { case BLKIF_OP_DISCARD: if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { struct request_queue *rq = info->rq; - printk(KERN_WARNING "blkfront: %s: discard op failed\n", - info->gd->disk_name); + printk(KERN_WARNING "blkfront: %s: %s op failed\n", + info->gd->disk_name, op_name(bret->operation)); error = -EOPNOTSUPP; info->feature_discard = 0; info->feature_secdiscard = 0; @@ -771,18 +809,14 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) case BLKIF_OP_FLUSH_DISKCACHE: case BLKIF_OP_WRITE_BARRIER: if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) { - printk(KERN_WARNING "blkfront: %s: write %s op failed\n", - info->flush_op == BLKIF_OP_WRITE_BARRIER ? - "barrier" : "flush disk cache", - info->gd->disk_name); + printk(KERN_WARNING "blkfront: %s: %s op failed\n", + info->gd->disk_name, op_name(bret->operation)); error = -EOPNOTSUPP; } if (unlikely(bret->status == BLKIF_RSP_ERROR && info->shadow[id].req.u.rw.nr_segments == 0)) { - printk(KERN_WARNING "blkfront: %s: empty write %s op failed\n", - info->flush_op == BLKIF_OP_WRITE_BARRIER ? - "barrier" : "flush disk cache", - info->gd->disk_name); + printk(KERN_WARNING "blkfront: %s: empty %s op failed\n", + info->gd->disk_name, op_name(bret->operation)); error = -EOPNOTSUPP; } if (unlikely(error)) { diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index ad591bd240ec..10308cd8a7ed 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -63,6 +63,7 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3002) }, + { USB_DEVICE(0x0CF3, 0xE019) }, { USB_DEVICE(0x13d3, 0x3304) }, { USB_DEVICE(0x0930, 0x0215) }, { USB_DEVICE(0x0489, 0xE03D) }, @@ -77,6 +78,7 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x0CF3, 0xE004) }, + { USB_DEVICE(0x0930, 0x0219) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, @@ -101,6 +103,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU22 with sflash firmware */ { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h index 94f2d65131c4..27068d149380 100644 --- a/drivers/bluetooth/btmrvl_drv.h +++ b/drivers/bluetooth/btmrvl_drv.h @@ -136,7 +136,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv); void btmrvl_interrupt(struct btmrvl_private *priv); -void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); +bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd); diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 681ca9d18e12..dc304def8400 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -44,23 +44,33 @@ void btmrvl_interrupt(struct btmrvl_private *priv) } EXPORT_SYMBOL_GPL(btmrvl_interrupt); -void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) +bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) { struct hci_event_hdr *hdr = (void *) skb->data; struct hci_ev_cmd_complete *ec; - u16 opcode, ocf; + u16 opcode, ocf, ogf; if (hdr->evt == HCI_EV_CMD_COMPLETE) { ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); opcode = __le16_to_cpu(ec->opcode); ocf = hci_opcode_ocf(opcode); + ogf = hci_opcode_ogf(opcode); + if (ocf == BT_CMD_MODULE_CFG_REQ && priv->btmrvl_dev.sendcmdflag) { priv->btmrvl_dev.sendcmdflag = false; priv->adapter->cmd_complete = true; wake_up_interruptible(&priv->adapter->cmd_wait_q); } + + if (ogf == OGF) { + BT_DBG("vendor event skipped: ogf 0x%4.4x", ogf); + kfree_skb(skb); + return false; + } } + + return true; } EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt); diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index a853244e7fd7..0cd61d9f07cd 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c @@ -562,10 +562,12 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) skb_put(skb, buf_len); skb_pull(skb, SDIO_HEADER_LEN); - if (type == HCI_EVENT_PKT) - btmrvl_check_evtpkt(priv, skb); + if (type == HCI_EVENT_PKT) { + if (btmrvl_check_evtpkt(priv, skb)) + hci_recv_frame(skb); + } else + hci_recv_frame(skb); - hci_recv_frame(skb); hdev->stat.byte_rx += buf_len; break; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c9463af8e564..83ebb241bfcc 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -125,6 +125,7 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3011 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, + { USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, @@ -139,6 +140,7 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index 6289f0eee24c..731c9046cf7b 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c @@ -34,7 +34,7 @@ static int atmel_trng_read(struct hwrng *rng, void *buf, size_t max, u32 *data = buf; /* data ready? */ - if (readl(trng->base + TRNG_ODATA) & 1) { + if (readl(trng->base + TRNG_ISR) & 1) { *data = readl(trng->base + TRNG_ODATA); /* ensure data ready is only set again AFTER the next data diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 687b00d67c8a..9a1eb0cfa95f 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -850,18 +850,21 @@ static void clk_change_rate(struct clk *clk) { struct clk *child; unsigned long old_rate; + unsigned long best_parent_rate = 0; struct hlist_node *tmp; old_rate = clk->rate; + if (clk->parent) + best_parent_rate = clk->parent->rate; + if (clk->ops->set_rate) - clk->ops->set_rate(clk->hw, clk->new_rate, clk->parent->rate); + clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate); if (clk->ops->recalc_rate) - clk->rate = clk->ops->recalc_rate(clk->hw, - clk->parent->rate); + clk->rate = clk->ops->recalc_rate(clk->hw, best_parent_rate); else - clk->rate = clk->parent->rate; + clk->rate = best_parent_rate; if (clk->notifier_count && old_rate != clk->rate) __clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate); @@ -999,7 +1002,7 @@ static struct clk *__clk_init_parent(struct clk *clk) if (!clk->parents) clk->parents = - kmalloc((sizeof(struct clk*) * clk->num_parents), + kzalloc((sizeof(struct clk*) * clk->num_parents), GFP_KERNEL); if (!clk->parents) @@ -1064,21 +1067,24 @@ static int __clk_set_parent(struct clk *clk, struct clk *parent) old_parent = clk->parent; - /* find index of new parent clock using cached parent ptrs */ - for (i = 0; i < clk->num_parents; i++) - if (clk->parents[i] == parent) - break; + if (!clk->parents) + clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents), + GFP_KERNEL); /* - * find index of new parent clock using string name comparison - * also try to cache the parent to avoid future calls to __clk_lookup + * find index of new parent clock using cached parent ptrs, + * or if not yet cached, use string name comparison and cache + * them now to avoid future calls to __clk_lookup. */ - if (i == clk->num_parents) - for (i = 0; i < clk->num_parents; i++) - if (!strcmp(clk->parent_names[i], parent->name)) { + for (i = 0; i < clk->num_parents; i++) { + if (clk->parents && clk->parents[i] == parent) + break; + else if (!strcmp(clk->parent_names[i], parent->name)) { + if (clk->parents) clk->parents[i] = __clk_lookup(parent->name); - break; - } + break; + } + } if (i == clk->num_parents) { pr_debug("%s: clock %s is not a possible parent of clock %s\n", diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c index f7be225f544c..db2391c054ee 100644 --- a/drivers/clk/mxs/clk-imx23.c +++ b/drivers/clk/mxs/clk-imx23.c @@ -71,7 +71,7 @@ static void __init clk_misc_init(void) __mxs_setl(30 << BP_FRAC_IOFRAC, FRAC); } -static struct clk_lookup uart_lookups[] __initdata = { +static struct clk_lookup uart_lookups[] = { { .dev_id = "duart", }, { .dev_id = "mxs-auart.0", }, { .dev_id = "mxs-auart.1", }, @@ -80,31 +80,31 @@ static struct clk_lookup uart_lookups[] __initdata = { { .dev_id = "80070000.serial", }, }; -static struct clk_lookup hbus_lookups[] __initdata = { +static struct clk_lookup hbus_lookups[] = { { .dev_id = "imx23-dma-apbh", }, { .dev_id = "80004000.dma-apbh", }, }; -static struct clk_lookup xbus_lookups[] __initdata = { +static struct clk_lookup xbus_lookups[] = { { .dev_id = "duart", .con_id = "apb_pclk"}, { .dev_id = "80070000.serial", .con_id = "apb_pclk"}, { .dev_id = "imx23-dma-apbx", }, { .dev_id = "80024000.dma-apbx", }, }; -static struct clk_lookup ssp_lookups[] __initdata = { +static struct clk_lookup ssp_lookups[] = { { .dev_id = "imx23-mmc.0", }, { .dev_id = "imx23-mmc.1", }, { .dev_id = "80010000.ssp", }, { .dev_id = "80034000.ssp", }, }; -static struct clk_lookup lcdif_lookups[] __initdata = { +static struct clk_lookup lcdif_lookups[] = { { .dev_id = "imx23-fb", }, { .dev_id = "80030000.lcdif", }, }; -static struct clk_lookup gpmi_lookups[] __initdata = { +static struct clk_lookup gpmi_lookups[] = { { .dev_id = "imx23-gpmi-nand", }, { .dev_id = "8000c000.gpmi", }, }; diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index 2826a2606a29..7fad6c8c13d2 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c @@ -120,7 +120,7 @@ static void __init clk_misc_init(void) writel_relaxed(val, FRAC0); } -static struct clk_lookup uart_lookups[] __initdata = { +static struct clk_lookup uart_lookups[] = { { .dev_id = "duart", }, { .dev_id = "mxs-auart.0", }, { .dev_id = "mxs-auart.1", }, @@ -135,71 +135,71 @@ static struct clk_lookup uart_lookups[] __initdata = { { .dev_id = "80074000.serial", }, }; -static struct clk_lookup hbus_lookups[] __initdata = { +static struct clk_lookup hbus_lookups[] = { { .dev_id = "imx28-dma-apbh", }, { .dev_id = "80004000.dma-apbh", }, }; -static struct clk_lookup xbus_lookups[] __initdata = { +static struct clk_lookup xbus_lookups[] = { { .dev_id = "duart", .con_id = "apb_pclk"}, { .dev_id = "80074000.serial", .con_id = "apb_pclk"}, { .dev_id = "imx28-dma-apbx", }, { .dev_id = "80024000.dma-apbx", }, }; -static struct clk_lookup ssp0_lookups[] __initdata = { +static struct clk_lookup ssp0_lookups[] = { { .dev_id = "imx28-mmc.0", }, { .dev_id = "80010000.ssp", }, }; -static struct clk_lookup ssp1_lookups[] __initdata = { +static struct clk_lookup ssp1_lookups[] = { { .dev_id = "imx28-mmc.1", }, { .dev_id = "80012000.ssp", }, }; -static struct clk_lookup ssp2_lookups[] __initdata = { +static struct clk_lookup ssp2_lookups[] = { { .dev_id = "imx28-mmc.2", }, { .dev_id = "80014000.ssp", }, }; -static struct clk_lookup ssp3_lookups[] __initdata = { +static struct clk_lookup ssp3_lookups[] = { { .dev_id = "imx28-mmc.3", }, { .dev_id = "80016000.ssp", }, }; -static struct clk_lookup lcdif_lookups[] __initdata = { +static struct clk_lookup lcdif_lookups[] = { { .dev_id = "imx28-fb", }, { .dev_id = "80030000.lcdif", }, }; -static struct clk_lookup gpmi_lookups[] __initdata = { +static struct clk_lookup gpmi_lookups[] = { { .dev_id = "imx28-gpmi-nand", }, { .dev_id = "8000c000.gpmi", }, }; -static struct clk_lookup fec_lookups[] __initdata = { +static struct clk_lookup fec_lookups[] = { { .dev_id = "imx28-fec.0", }, { .dev_id = "imx28-fec.1", }, { .dev_id = "800f0000.ethernet", }, { .dev_id = "800f4000.ethernet", }, }; -static struct clk_lookup can0_lookups[] __initdata = { +static struct clk_lookup can0_lookups[] = { { .dev_id = "flexcan.0", }, { .dev_id = "80032000.can", }, }; -static struct clk_lookup can1_lookups[] __initdata = { +static struct clk_lookup can1_lookups[] = { { .dev_id = "flexcan.1", }, { .dev_id = "80034000.can", }, }; -static struct clk_lookup saif0_lookups[] __initdata = { +static struct clk_lookup saif0_lookups[] = { { .dev_id = "mxs-saif.0", }, { .dev_id = "80042000.saif", }, }; -static struct clk_lookup saif1_lookups[] __initdata = { +static struct clk_lookup saif1_lookups[] = { { .dev_id = "mxs-saif.1", }, { .dev_id = "80046000.saif", }, }; @@ -245,8 +245,8 @@ int __init mx28_clocks_init(void) clks[pll2] = mxs_clk_pll("pll2", "ref_xtal", PLL2CTRL0, 23, 50000000); clks[ref_cpu] = mxs_clk_ref("ref_cpu", "pll0", FRAC0, 0); clks[ref_emi] = mxs_clk_ref("ref_emi", "pll0", FRAC0, 1); - clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 2); - clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 3); + clks[ref_io1] = mxs_clk_ref("ref_io1", "pll0", FRAC0, 2); + clks[ref_io0] = mxs_clk_ref("ref_io0", "pll0", FRAC0, 3); clks[ref_pix] = mxs_clk_ref("ref_pix", "pll0", FRAC1, 0); clks[ref_hsadc] = mxs_clk_ref("ref_hsadc", "pll0", FRAC1, 1); clks[ref_gpmi] = mxs_clk_ref("ref_gpmi", "pll0", FRAC1, 2); diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c index af34074e702b..6756e7c3bc07 100644 --- a/drivers/clk/spear/clk-aux-synth.c +++ b/drivers/clk/spear/clk-aux-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c index 4dbdb3fe18e0..958aa3ad1d60 100644 --- a/drivers/clk/spear/clk-frac-synth.c +++ b/drivers/clk/spear/clk-frac-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c index b471c9762a97..1afc18c4effc 100644 --- a/drivers/clk/spear/clk-gpt-synth.c +++ b/drivers/clk/spear/clk-gpt-synth.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c index dcd4bdf4b0d9..5f1b6badeb15 100644 --- a/drivers/clk/spear/clk-vco-pll.c +++ b/drivers/clk/spear/clk-vco-pll.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk.c b/drivers/clk/spear/clk.c index 376d4e5ff326..7cd63788d546 100644 --- a/drivers/clk/spear/clk.c +++ b/drivers/clk/spear/clk.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/clk.h b/drivers/clk/spear/clk.h index 3321c46a071c..931737677dfa 100644 --- a/drivers/clk/spear/clk.h +++ b/drivers/clk/spear/clk.h @@ -2,7 +2,7 @@ * Clock framework definitions for SPEAr platform * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear1310_clock.c b/drivers/clk/spear/spear1310_clock.c index 42b68df9aeef..8f05652d53e6 100644 --- a/drivers/clk/spear/spear1310_clock.c +++ b/drivers/clk/spear/spear1310_clock.c @@ -4,7 +4,7 @@ * SPEAr1310 machine clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c index f130919d5bf8..e3ea72162236 100644 --- a/drivers/clk/spear/spear1340_clock.c +++ b/drivers/clk/spear/spear1340_clock.c @@ -4,7 +4,7 @@ * SPEAr1340 machine clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear3xx_clock.c b/drivers/clk/spear/spear3xx_clock.c index 440bb3e4c971..01dd6daff2a1 100644 --- a/drivers/clk/spear/spear3xx_clock.c +++ b/drivers/clk/spear/spear3xx_clock.c @@ -2,7 +2,7 @@ * SPEAr3xx machines clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/clk/spear/spear6xx_clock.c b/drivers/clk/spear/spear6xx_clock.c index f9a20b382304..61026ae564ab 100644 --- a/drivers/clk/spear/spear6xx_clock.c +++ b/drivers/clk/spear/spear6xx_clock.c @@ -2,7 +2,7 @@ * SPEAr6xx machines clock framework source file * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -298,7 +298,7 @@ void __init spear6xx_clk_init(void) clk = clk_register_gate(NULL, "gmac_clk", "ahb_clk", 0, PERIP1_CLK_ENB, GMAC_CLK_ENB, 0, &_lock); - clk_register_clkdev(clk, NULL, "gmac"); + clk_register_clkdev(clk, NULL, "e0800000.ethernet"); clk = clk_register_gate(NULL, "i2c_clk", "ahb_clk", 0, PERIP1_CLK_ENB, I2C_CLK_ENB, 0, &_lock); diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c index e23dc82d43ac..721296157577 100644 --- a/drivers/dma/dw_dmac.c +++ b/drivers/dma/dw_dmac.c @@ -1626,4 +1626,4 @@ module_exit(dw_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver"); MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); -MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); +MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index fb4f4990f5eb..1dc2a4ad0026 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -815,8 +815,6 @@ static int sdma_request_channel(struct sdma_channel *sdmac) init_completion(&sdmac->done); - sdmac->buf_tail = 0; - return 0; out: @@ -927,6 +925,8 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( sdmac->flags = 0; + sdmac->buf_tail = 0; + dev_dbg(sdma->dev, "setting up %d entries for channel %d.\n", sg_len, channel); @@ -1027,6 +1027,8 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic( sdmac->status = DMA_IN_PROGRESS; + sdmac->buf_tail = 0; + sdmac->flags |= IMX_DMA_SG_LOOP; sdmac->direction = direction; ret = sdma_load_context(sdmac); diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index cbcc28e79be6..e4feba6b03c0 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -392,6 +392,8 @@ struct pl330_req { struct pl330_reqcfg *cfg; /* Pointer to first xfer in the request. */ struct pl330_xfer *x; + /* Hook to attach to DMAC's list of reqs with due callback */ + struct list_head rqd; }; /* @@ -461,8 +463,6 @@ struct _pl330_req { /* Number of bytes taken to setup MC for the req */ u32 mc_len; struct pl330_req *r; - /* Hook to attach to DMAC's list of reqs with due callback */ - struct list_head rqd; }; /* ToBeDone for tasklet */ @@ -1683,7 +1683,7 @@ static void pl330_dotask(unsigned long data) /* Returns 1 if state was updated, 0 otherwise */ static int pl330_update(const struct pl330_info *pi) { - struct _pl330_req *rqdone; + struct pl330_req *rqdone, *tmp; struct pl330_dmac *pl330; unsigned long flags; void __iomem *regs; @@ -1750,7 +1750,10 @@ static int pl330_update(const struct pl330_info *pi) if (active == -1) /* Aborted */ continue; - rqdone = &thrd->req[active]; + /* Detach the req */ + rqdone = thrd->req[active].r; + thrd->req[active].r = NULL; + mark_free(thrd, active); /* Get going again ASAP */ @@ -1762,20 +1765,11 @@ static int pl330_update(const struct pl330_info *pi) } /* Now that we are in no hurry, do the callbacks */ - while (!list_empty(&pl330->req_done)) { - struct pl330_req *r; - - rqdone = container_of(pl330->req_done.next, - struct _pl330_req, rqd); - - list_del_init(&rqdone->rqd); - - /* Detach the req */ - r = rqdone->r; - rqdone->r = NULL; + list_for_each_entry_safe(rqdone, tmp, &pl330->req_done, rqd) { + list_del(&rqdone->rqd); spin_unlock_irqrestore(&pl330->lock, flags); - _callback(r, PL330_ERR_NONE); + _callback(rqdone, PL330_ERR_NONE); spin_lock_irqsave(&pl330->lock, flags); } @@ -2321,7 +2315,7 @@ static void pl330_tasklet(unsigned long data) /* Pick up ripe tomatoes */ list_for_each_entry_safe(desc, _dt, &pch->work_list, node) if (desc->status == DONE) { - if (pch->cyclic) + if (!pch->cyclic) dma_cookie_complete(&desc->txd); list_move_tail(&desc->node, &list); } @@ -2539,7 +2533,7 @@ static inline void _init_desc(struct dma_pl330_desc *desc) } /* Returns the number of descriptors added to the DMAC pool */ -int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) +static int add_desc(struct dma_pl330_dmac *pdmac, gfp_t flg, int count) { struct dma_pl330_desc *desc; unsigned long flags; diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 10f375032e96..de5ba86e8b89 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -164,7 +164,7 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems) else return (char *)ptr; - r = size % align; + r = (unsigned long)p % align; if (r == 0) return (char *)ptr; diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index d27778f65a5d..a499c7ed820a 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1814,12 +1814,6 @@ static int i7core_mce_check_error(struct notifier_block *nb, unsigned long val, if (mce->bank != 8) return NOTIFY_DONE; -#ifdef CONFIG_SMP - /* Only handle if it is the right mc controller */ - if (mce->socketid != pvt->i7core_dev->socket) - return NOTIFY_DONE; -#endif - smp_rmb(); if ((pvt->mce_out + 1) % MCE_LOG_LEN == pvt->mce_in) { smp_wmb(); @@ -2116,8 +2110,6 @@ static void i7core_unregister_mci(struct i7core_dev *i7core_dev) if (pvt->enable_scrub) disable_sdram_scrub_setting(mci); - mce_unregister_decode_chain(&i7_mce_dec); - /* Disable EDAC polling */ i7core_pci_ctl_release(pvt); @@ -2222,8 +2214,6 @@ static int i7core_register_mci(struct i7core_dev *i7core_dev) /* DCLK for scrub rate setting */ pvt->dclk_freq = get_dclk_freq(); - mce_register_decode_chain(&i7_mce_dec); - return 0; fail0: @@ -2367,8 +2357,10 @@ static int __init i7core_init(void) pci_rc = pci_register_driver(&i7core_driver); - if (pci_rc >= 0) + if (pci_rc >= 0) { + mce_register_decode_chain(&i7_mce_dec); return 0; + } i7core_printk(KERN_ERR, "Failed to register device with error %d.\n", pci_rc); @@ -2384,6 +2376,7 @@ static void __exit i7core_exit(void) { debugf2("MC: " __FILE__ ": %s()\n", __func__); pci_unregister_driver(&i7core_driver); + mce_unregister_decode_chain(&i7_mce_dec); } module_init(i7core_init); diff --git a/drivers/edac/mpc85xx_edac.c b/drivers/edac/mpc85xx_edac.c index 4c402353ba98..0e374625f6f8 100644 --- a/drivers/edac/mpc85xx_edac.c +++ b/drivers/edac/mpc85xx_edac.c @@ -980,7 +980,8 @@ static int __devinit mpc85xx_mc_err_probe(struct platform_device *op) layers[1].type = EDAC_MC_LAYER_CHANNEL; layers[1].size = 1; layers[1].is_virt_csrow = false; - mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), sizeof(*pdata)); + mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), layers, + sizeof(*pdata)); if (!mci) { devres_release_group(&op->dev, mpc85xx_mc_err_probe); return -ENOMEM; diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index 4adaf4b7da99..36ad17e79d61 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -555,7 +555,7 @@ static int get_dimm_config(struct mem_ctl_info *mci) pvt->is_close_pg = false; } - pci_read_config_dword(pvt->pci_ta, RANK_CFG_A, ®); + pci_read_config_dword(pvt->pci_ddrio, RANK_CFG_A, ®); if (IS_RDIMM_ENABLED(reg)) { /* FIXME: Can also be LRDIMM */ debugf0("Memory is registered\n"); @@ -1604,8 +1604,6 @@ static void sbridge_unregister_mci(struct sbridge_dev *sbridge_dev) debugf0("MC: " __FILE__ ": %s(): mci = %p, dev = %p\n", __func__, mci, &sbridge_dev->pdev[0]->dev); - mce_unregister_decode_chain(&sbridge_mce_dec); - /* Remove MC sysfs nodes */ edac_mc_del_mc(mci->dev); @@ -1682,7 +1680,6 @@ static int sbridge_register_mci(struct sbridge_dev *sbridge_dev) goto fail0; } - mce_register_decode_chain(&sbridge_mce_dec); return 0; fail0: @@ -1811,8 +1808,10 @@ static int __init sbridge_init(void) pci_rc = pci_register_driver(&sbridge_driver); - if (pci_rc >= 0) + if (pci_rc >= 0) { + mce_register_decode_chain(&sbridge_mce_dec); return 0; + } sbridge_printk(KERN_ERR, "Failed to register device with error %d.\n", pci_rc); @@ -1828,6 +1827,7 @@ static void __exit sbridge_exit(void) { debugf2("MC: " __FILE__ ": %s()\n", __func__); pci_unregister_driver(&sbridge_driver); + mce_unregister_decode_chain(&sbridge_mce_dec); } module_init(sbridge_init); diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index 23416e443765..a4ed30bd9a41 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -116,8 +116,8 @@ const char *max8997_extcon_cable[] = { [5] = "Charge-downstream", [6] = "MHL", [7] = "Dock-desk", - [7] = "Dock-card", - [8] = "JIG", + [8] = "Dock-card", + [9] = "JIG", NULL, }; @@ -514,6 +514,7 @@ static int __devexit max8997_muic_remove(struct platform_device *pdev) extcon_dev_unregister(info->edev); + kfree(info->edev); kfree(info); return 0; diff --git a/drivers/extcon/extcon_class.c b/drivers/extcon/extcon_class.c index f598a700ec15..159aeb07b3ba 100644 --- a/drivers/extcon/extcon_class.c +++ b/drivers/extcon/extcon_class.c @@ -762,7 +762,7 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev) #if defined(CONFIG_ANDROID) if (switch_class) ret = class_compat_create_link(switch_class, edev->dev, - dev); + NULL); #endif /* CONFIG_ANDROID */ spin_lock_init(&edev->lock); diff --git a/drivers/extcon/extcon_gpio.c b/drivers/extcon/extcon_gpio.c index fe7a07b47336..8a0dcc11c7c7 100644 --- a/drivers/extcon/extcon_gpio.c +++ b/drivers/extcon/extcon_gpio.c @@ -125,6 +125,7 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) if (ret < 0) goto err_request_irq; + platform_set_drvdata(pdev, extcon_data); /* Perform initial detection */ gpio_extcon_work(&extcon_data->work.work); @@ -146,6 +147,7 @@ static int __devexit gpio_extcon_remove(struct platform_device *pdev) struct gpio_extcon_data *extcon_data = platform_get_drvdata(pdev); cancel_delayed_work_sync(&extcon_data->work); + free_irq(extcon_data->irq, extcon_data); gpio_free(extcon_data->gpio); extcon_dev_unregister(&extcon_data->edev); devm_kfree(&pdev->dev, extcon_data); diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index c4067d0141f7..542f0c04b695 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 9e9947cb86a3..1077754f8289 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 c337143b18f8..c89c4c1e668d 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 c4ed1722734c..4fbc208c32cf 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 38416be8ba11..6064fb376e11 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 c1ad2884f2ed..11f29c82253c 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 92ea5350dfe9..aa61ad2fcaaa 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/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index eb92fe257a39..a8743c399e83 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -610,7 +610,7 @@ static bool drm_monitor_supports_rb(struct edid *edid) { if (edid->revision >= 4) { - bool ret; + bool ret = false; drm_for_each_detailed_block((u8 *)edid, is_rb, &ret); return ret; } @@ -1039,6 +1039,24 @@ mode_in_range(const struct drm_display_mode *mode, struct edid *edid, return true; } +static bool valid_inferred_mode(const struct drm_connector *connector, + const struct drm_display_mode *mode) +{ + struct drm_display_mode *m; + bool ok = false; + + list_for_each_entry(m, &connector->probed_modes, head) { + if (mode->hdisplay == m->hdisplay && + mode->vdisplay == m->vdisplay && + drm_mode_vrefresh(mode) == drm_mode_vrefresh(m)) + return false; /* duplicated */ + if (mode->hdisplay <= m->hdisplay && + mode->vdisplay <= m->vdisplay) + ok = true; + } + return ok; +} + static int drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid, struct detailed_timing *timing) @@ -1048,7 +1066,8 @@ drm_dmt_modes_for_range(struct drm_connector *connector, struct edid *edid, struct drm_device *dev = connector->dev; for (i = 0; i < drm_num_dmt_modes; i++) { - if (mode_in_range(drm_dmt_modes + i, edid, timing)) { + if (mode_in_range(drm_dmt_modes + i, edid, timing) && + valid_inferred_mode(connector, drm_dmt_modes + i)) { newmode = drm_mode_duplicate(dev, &drm_dmt_modes[i]); if (newmode) { drm_mode_probed_add(connector, newmode); @@ -1088,7 +1107,8 @@ drm_gtf_modes_for_range(struct drm_connector *connector, struct edid *edid, return modes; fixup_mode_1366x768(newmode); - if (!mode_in_range(newmode, edid, timing)) { + if (!mode_in_range(newmode, edid, timing) || + !valid_inferred_mode(connector, newmode)) { drm_mode_destroy(dev, newmode); continue; } @@ -1116,7 +1136,8 @@ drm_cvt_modes_for_range(struct drm_connector *connector, struct edid *edid, return modes; fixup_mode_1366x768(newmode); - if (!mode_in_range(newmode, edid, timing)) { + if (!mode_in_range(newmode, edid, timing) || + !valid_inferred_mode(connector, newmode)) { drm_mode_destroy(dev, newmode); continue; } diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f94792626b94..36822b924eb1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1401,6 +1401,27 @@ i915_mtrr_setup(struct drm_i915_private *dev_priv, unsigned long base, } } +static void i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) +{ + struct apertures_struct *ap; + struct pci_dev *pdev = dev_priv->dev->pdev; + bool primary; + + ap = alloc_apertures(1); + if (!ap) + return; + + ap->ranges[0].base = dev_priv->dev->agp->base; + ap->ranges[0].size = + dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; + primary = + pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; + + remove_conflicting_framebuffers(ap, "inteldrmfb", primary); + + kfree(ap); +} + /** * i915_driver_load - setup chip and create an initial config * @dev: DRM device @@ -1446,6 +1467,15 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto free_priv; } + dev_priv->mm.gtt = intel_gtt_get(); + if (!dev_priv->mm.gtt) { + DRM_ERROR("Failed to initialize GTT\n"); + ret = -ENODEV; + goto put_bridge; + } + + i915_kick_out_firmware_fb(dev_priv); + pci_set_master(dev->pdev); /* overlay on gen2 is broken and can't address above 1G */ @@ -1471,13 +1501,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto put_bridge; } - dev_priv->mm.gtt = intel_gtt_get(); - if (!dev_priv->mm.gtt) { - DRM_ERROR("Failed to initialize GTT\n"); - ret = -ENODEV; - goto out_rmmap; - } - aperture_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; dev_priv->mm.gtt_mapping = diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b1fe0edda955..ed3224c37423 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -412,7 +412,6 @@ static void gen6_queue_rps_work(struct drm_i915_private *dev_priv, */ spin_lock_irqsave(&dev_priv->rps_lock, flags); - WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n"); dev_priv->pm_iir |= pm_iir; I915_WRITE(GEN6_PMIMR, dev_priv->pm_iir); POSTING_READ(GEN6_PMIMR); diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 0ede02a99d91..a748e5cabe14 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -740,8 +740,11 @@ static void i915_restore_display(struct drm_device *dev) if (HAS_PCH_SPLIT(dev)) { I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); - I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); + /* NOTE: BLC_PWM_CPU_CTL must be written after BLC_PWM_CPU_CTL2; + * otherwise we get blank eDP screen after S3 on some machines + */ I915_WRITE(BLC_PWM_CPU_CTL2, dev_priv->saveBLC_CPU_PWM_CTL2); + I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); I915_WRITE(PCH_PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS); I915_WRITE(PCH_PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS); I915_WRITE(PCH_PP_DIVISOR, dev_priv->savePP_DIVISOR); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e0aa064def31..a8538ac0299d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6558,7 +6558,7 @@ static void intel_setup_outputs(struct drm_device *dev) if (I915_READ(HDMIC) & PORT_DETECTED) intel_hdmi_init(dev, HDMIC); - if (I915_READ(HDMID) & PORT_DETECTED) + if (!dpd_is_edp && I915_READ(HDMID) & PORT_DETECTED) intel_hdmi_init(dev, HDMID); if (I915_READ(PCH_DP_C) & DP_DETECTED) @@ -6921,19 +6921,6 @@ static void i915_disable_vga(struct drm_device *dev) POSTING_READ(vga_reg); } -static void ivb_pch_pwm_override(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - /* - * IVB has CPU eDP backlight regs too, set things up to let the - * PCH regs control the backlight - */ - I915_WRITE(BLC_PWM_CPU_CTL2, PWM_ENABLE); - I915_WRITE(BLC_PWM_CPU_CTL, 0); - I915_WRITE(BLC_PWM_PCH_CTL1, PWM_ENABLE | (1<<30)); -} - void intel_modeset_init_hw(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -6950,9 +6937,6 @@ void intel_modeset_init_hw(struct drm_device *dev) gen6_enable_rps(dev_priv); gen6_update_ring_freq(dev_priv); } - - if (IS_IVYBRIDGE(dev)) - ivb_pch_pwm_override(dev); } void intel_modeset_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 296cfc201a81..c0449324143c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -32,6 +32,7 @@ #include "drm.h" #include "drm_crtc.h" #include "drm_crtc_helper.h" +#include "drm_edid.h" #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" @@ -67,6 +68,8 @@ struct intel_dp { struct drm_display_mode *panel_fixed_mode; /* for eDP */ struct delayed_work panel_vdd_work; bool want_panel_vdd; + struct edid *edid; /* cached EDID for eDP */ + int edid_mode_count; }; /** @@ -371,7 +374,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, int recv_bytes; uint32_t status; uint32_t aux_clock_divider; - int try, precharge = 5; + int try, precharge; intel_dp_check_edp(intel_dp); /* The clock divider is based off the hrawclk, @@ -391,6 +394,11 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, else aux_clock_divider = intel_hrawclk(dev) / 2; + if (IS_GEN6(dev)) + precharge = 3; + else + precharge = 5; + /* Try to wait for any previous AUX channel activity */ for (try = 0; try < 3; try++) { status = I915_READ(ch_ctl); @@ -1973,6 +1981,8 @@ intel_dp_probe_oui(struct intel_dp *intel_dp) if (!(intel_dp->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) return; + ironlake_edp_panel_vdd_on(intel_dp); + if (intel_dp_aux_native_read_retry(intel_dp, DP_SINK_OUI, buf, 3)) DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); @@ -1980,6 +1990,8 @@ intel_dp_probe_oui(struct intel_dp *intel_dp) if (intel_dp_aux_native_read_retry(intel_dp, DP_BRANCH_OUI, buf, 3)) DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); + + ironlake_edp_panel_vdd_off(intel_dp, false); } static bool @@ -2116,10 +2128,22 @@ intel_dp_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) { struct intel_dp *intel_dp = intel_attached_dp(connector); struct edid *edid; + int size; + + if (is_edp(intel_dp)) { + if (!intel_dp->edid) + return NULL; + + size = (intel_dp->edid->extensions + 1) * EDID_LENGTH; + edid = kmalloc(size, GFP_KERNEL); + if (!edid) + return NULL; + + memcpy(edid, intel_dp->edid, size); + return edid; + } - ironlake_edp_panel_vdd_on(intel_dp); edid = drm_get_edid(connector, adapter); - ironlake_edp_panel_vdd_off(intel_dp, false); return edid; } @@ -2129,9 +2153,17 @@ intel_dp_get_edid_modes(struct drm_connector *connector, struct i2c_adapter *ada struct intel_dp *intel_dp = intel_attached_dp(connector); int ret; - ironlake_edp_panel_vdd_on(intel_dp); + if (is_edp(intel_dp)) { + drm_mode_connector_update_edid_property(connector, + intel_dp->edid); + ret = drm_add_edid_modes(connector, intel_dp->edid); + drm_edid_to_eld(connector, + intel_dp->edid); + connector->display_info.raw_edid = NULL; + return intel_dp->edid_mode_count; + } + ret = intel_ddc_get_modes(connector, adapter); - ironlake_edp_panel_vdd_off(intel_dp, false); return ret; } @@ -2321,6 +2353,7 @@ static void intel_dp_encoder_destroy(struct drm_encoder *encoder) i2c_del_adapter(&intel_dp->adapter); drm_encoder_cleanup(encoder); if (is_edp(intel_dp)) { + kfree(intel_dp->edid); cancel_delayed_work_sync(&intel_dp->panel_vdd_work); ironlake_panel_vdd_off_sync(intel_dp); } @@ -2504,11 +2537,14 @@ intel_dp_init(struct drm_device *dev, int output_reg) break; } + intel_dp_i2c_init(intel_dp, intel_connector, name); + /* Cache some DPCD data in the eDP case */ if (is_edp(intel_dp)) { bool ret; struct edp_power_seq cur, vbt; u32 pp_on, pp_off, pp_div; + struct edid *edid; pp_on = I915_READ(PCH_PP_ON_DELAYS); pp_off = I915_READ(PCH_PP_OFF_DELAYS); @@ -2576,9 +2612,19 @@ intel_dp_init(struct drm_device *dev, int output_reg) intel_dp_destroy(&intel_connector->base); return; } - } - intel_dp_i2c_init(intel_dp, intel_connector, name); + ironlake_edp_panel_vdd_on(intel_dp); + edid = drm_get_edid(connector, &intel_dp->adapter); + if (edid) { + drm_mode_connector_update_edid_property(connector, + edid); + intel_dp->edid_mode_count = + drm_add_edid_modes(connector, edid); + drm_edid_to_eld(connector, edid); + intel_dp->edid = edid; + } + ironlake_edp_panel_vdd_off(intel_dp, false); + } intel_encoder->hot_plug = intel_dp_hot_plug; diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 153b9a15469b..1074bc5dd418 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -467,7 +467,7 @@ int nouveau_fbcon_init(struct drm_device *dev) nfbdev->helper.funcs = &nouveau_fbcon_helper_funcs; ret = drm_fb_helper_init(dev, &nfbdev->helper, - nv_two_heads(dev) ? 2 : 1, 4); + dev->mode_config.num_crtc, 4); if (ret) { kfree(nfbdev); return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c index a89240e5fb29..a25cf2cb931f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -1,3 +1,26 @@ +/* + * Copyright 2011 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Dave Airlie + */ #include "drmP.h" #include "drm.h" diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 01d77d1554f4..3904d7964a4b 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c @@ -1149,7 +1149,9 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, } if (tiling_flags & RADEON_TILING_MACRO) { - if (rdev->family >= CHIP_CAYMAN) + if (rdev->family >= CHIP_TAHITI) + tmp = rdev->config.si.tile_config; + else if (rdev->family >= CHIP_CAYMAN) tmp = rdev->config.cayman.tile_config; else tmp = rdev->config.evergreen.tile_config; @@ -1177,6 +1179,12 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, } else if (tiling_flags & RADEON_TILING_MICRO) fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); + if ((rdev->family == CHIP_TAHITI) || + (rdev->family == CHIP_PITCAIRN)) + fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16); + else if (rdev->family == CHIP_VERDE) + fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16); + switch (radeon_crtc->crtc_id) { case 0: WREG32(AVIVO_D1VGA_CONTROL, 0); diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index e7b1ec5ae8c6..486ccdf4aacd 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -1926,7 +1926,9 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) { r600_hdmi_enable(encoder); - if (ASIC_IS_DCE4(rdev)) + if (ASIC_IS_DCE6(rdev)) + ; /* TODO (use pointers instead of if-s?) */ + else if (ASIC_IS_DCE4(rdev)) evergreen_hdmi_setmode(encoder, adjusted_mode); else r600_hdmi_setmode(encoder, adjusted_mode); diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 01550d05e273..7fb3d2e0434c 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1932,6 +1932,9 @@ static void evergreen_gpu_init(struct radeon_device *rdev) smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets); WREG32(SMX_DC_CTL0, smx_dc_ctl0); + if (rdev->family <= CHIP_SUMO2) + WREG32(SMX_SAR_CTL0, 0x00010000); + WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) | POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) | SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1))); diff --git a/drivers/gpu/drm/radeon/evergreen_hdmi.c b/drivers/gpu/drm/radeon/evergreen_hdmi.c index a51f880985f8..65c54160028b 100644 --- a/drivers/gpu/drm/radeon/evergreen_hdmi.c +++ b/drivers/gpu/drm/radeon/evergreen_hdmi.c @@ -156,9 +156,6 @@ void evergreen_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE5(rdev)) - return; - /* Silent, r600_hdmi_enable will raise WARN for us */ if (!dig->afmt->enabled) return; diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 2773039b4902..b50b15c70498 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -503,6 +503,7 @@ #define SCRATCH_UMSK 0x8540 #define SCRATCH_ADDR 0x8544 +#define SMX_SAR_CTL0 0xA008 #define SMX_DC_CTL0 0xA020 #define USE_HASH_FUNCTION (1 << 0) #define NUMBER_OF_SETS(x) ((x) << 1) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 3186522a4458..b7bf18e40215 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1303,6 +1303,10 @@ static int cayman_startup(struct radeon_device *rdev) if (r) return r; + r = r600_audio_init(rdev); + if (r) + return r; + return 0; } @@ -1329,6 +1333,7 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { + r600_audio_fini(rdev); /* FIXME: we should wait for ring to be empty */ radeon_ib_pool_suspend(rdev); radeon_vm_manager_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index f30dc95f83b1..bff627293812 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1839,6 +1839,7 @@ void r600_gpu_init(struct radeon_device *rdev) WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3))); WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095)); + WREG32(VC_ENHANCE, 0); } diff --git a/drivers/gpu/drm/radeon/r600_audio.c b/drivers/gpu/drm/radeon/r600_audio.c index 7479a5c503e4..79b55916cf90 100644 --- a/drivers/gpu/drm/radeon/r600_audio.c +++ b/drivers/gpu/drm/radeon/r600_audio.c @@ -57,7 +57,7 @@ static bool radeon_dig_encoder(struct drm_encoder *encoder) */ static int r600_audio_chipset_supported(struct radeon_device *rdev) { - return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE5(rdev)) + return (rdev->family >= CHIP_R600 && !ASIC_IS_DCE6(rdev)) || rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740; diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0133f5f09bd6..ca87f7afaf23 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -2079,6 +2079,48 @@ static int r600_packet3_check(struct radeon_cs_parser *p, return -EINVAL; } break; + case PACKET3_STRMOUT_BASE_UPDATE: + if (p->family < CHIP_RV770) { + DRM_ERROR("STRMOUT_BASE_UPDATE only supported on 7xx\n"); + return -EINVAL; + } + if (pkt->count != 1) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE packet count\n"); + return -EINVAL; + } + if (idx_value > 3) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE index\n"); + return -EINVAL; + } + { + u64 offset; + + r = r600_cs_packet_next_reloc(p, &reloc); + if (r) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE reloc\n"); + return -EINVAL; + } + + if (reloc->robj != track->vgt_strmout_bo[idx_value]) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo does not match\n"); + return -EINVAL; + } + + offset = radeon_get_ib_value(p, idx+1) << 8; + if (offset != track->vgt_strmout_bo_offset[idx_value]) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE, bo offset does not match: 0x%llx, 0x%x\n", + offset, track->vgt_strmout_bo_offset[idx_value]); + return -EINVAL; + } + + if ((offset + 4) > radeon_bo_size(reloc->robj)) { + DRM_ERROR("bad STRMOUT_BASE_UPDATE bo too small: 0x%llx, 0x%lx\n", + offset + 4, radeon_bo_size(reloc->robj)); + return -EINVAL; + } + ib[idx+1] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); + } + break; case PACKET3_SURFACE_BASE_UPDATE: if (p->family >= CHIP_RV770 || p->family == CHIP_R600) { DRM_ERROR("bad SURFACE_BASE_UPDATE\n"); diff --git a/drivers/gpu/drm/radeon/r600_hdmi.c b/drivers/gpu/drm/radeon/r600_hdmi.c index 969c27529dfe..82a0a4c919c0 100644 --- a/drivers/gpu/drm/radeon/r600_hdmi.c +++ b/drivers/gpu/drm/radeon/r600_hdmi.c @@ -322,9 +322,6 @@ void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mod struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE5(rdev)) - return; - /* Silent, r600_hdmi_enable will raise WARN for us */ if (!dig->afmt->enabled) return; @@ -483,7 +480,7 @@ void r600_hdmi_enable(struct drm_encoder *encoder) uint32_t offset; u32 hdmi; - if (ASIC_IS_DCE5(rdev)) + if (ASIC_IS_DCE6(rdev)) return; /* Silent, r600_hdmi_enable will raise WARN for us */ @@ -543,7 +540,7 @@ void r600_hdmi_disable(struct drm_encoder *encoder) struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; uint32_t offset; - if (ASIC_IS_DCE5(rdev)) + if (ASIC_IS_DCE6(rdev)) return; /* Called for ATOM_ENCODER_MODE_HDMI only */ diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index a0dbf1fe6a40..025fd5b6c08c 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -485,6 +485,7 @@ #define TC_L2_SIZE(x) ((x)<<5) #define L2_DISABLE_LATE_HIT (1<<9) +#define VC_ENHANCE 0x9714 #define VGT_CACHE_INVALIDATION 0x88C4 #define CACHE_INVALIDATION(x) ((x)<<0) @@ -1163,6 +1164,7 @@ #define PACKET3_SET_CTL_CONST 0x6F #define PACKET3_SET_CTL_CONST_OFFSET 0x0003cff0 #define PACKET3_SET_CTL_CONST_END 0x0003e200 +#define PACKET3_STRMOUT_BASE_UPDATE 0x72 /* r7xx */ #define PACKET3_SURFACE_BASE_UPDATE 0x73 diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 03e5f5df40f1..2c4d53fd20c5 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -58,9 +58,10 @@ * 2.14.0 - add evergreen tiling informations * 2.15.0 - add max_pipes query * 2.16.0 - fix evergreen 2D tiled surface calculation + * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 16 +#define KMS_DRIVER_MINOR 17 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 59d44937dd9f..84b648a7ddd8 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -289,8 +289,9 @@ int radeon_vm_manager_init(struct radeon_device *rdev) rdev->vm_manager.enabled = false; /* mark first vm as always in use, it's the system one */ + /* allocate enough for 2 full VM pts */ r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, - rdev->vm_manager.max_pfn * 8, + rdev->vm_manager.max_pfn * 8 * 2, RADEON_GEM_DOMAIN_VRAM); if (r) { dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", @@ -633,7 +634,15 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) mutex_init(&vm->mutex); INIT_LIST_HEAD(&vm->list); INIT_LIST_HEAD(&vm->va); - vm->last_pfn = 0; + /* SI requires equal sized PTs for all VMs, so always set + * last_pfn to max_pfn. cayman allows variable sized + * pts so we can grow then as needed. Once we switch + * to two level pts we can unify this again. + */ + if (rdev->family >= CHIP_TAHITI) + vm->last_pfn = rdev->vm_manager.max_pfn; + else + vm->last_pfn = 0; /* map the ib pool buffer at 0 in virtual address space, set * read only */ diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index f28bd4b7ef98..21ec9f5653ce 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -292,6 +292,7 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { + struct radeon_device *rdev = dev->dev_private; struct drm_radeon_gem_busy *args = data; struct drm_gem_object *gobj; struct radeon_bo *robj; @@ -317,13 +318,14 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, break; } drm_gem_object_unreference_unlocked(gobj); - r = radeon_gem_handle_lockup(robj->rdev, r); + r = radeon_gem_handle_lockup(rdev, r); return r; } int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { + struct radeon_device *rdev = dev->dev_private; struct drm_radeon_gem_wait_idle *args = data; struct drm_gem_object *gobj; struct radeon_bo *robj; @@ -336,10 +338,10 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, robj = gem_to_radeon_bo(gobj); r = radeon_bo_wait(robj, NULL, false); /* callback hw specific functions if any */ - if (robj->rdev->asic->ioctl_wait_idle) - robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj); + if (rdev->asic->ioctl_wait_idle) + robj->rdev->asic->ioctl_wait_idle(rdev, robj); drm_gem_object_unreference_unlocked(gobj); - r = radeon_gem_handle_lockup(robj->rdev, r); + r = radeon_gem_handle_lockup(rdev, r); return r; } diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 08825548ee69..5b37e283ec38 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -801,9 +801,13 @@ static void radeon_dynpm_idle_work_handler(struct work_struct *work) int i; for (i = 0; i < RADEON_NUM_RINGS; ++i) { - not_processed += radeon_fence_count_emitted(rdev, i); - if (not_processed >= 3) - break; + struct radeon_ring *ring = &rdev->ring[i]; + + if (ring->ready) { + not_processed += radeon_fence_count_emitted(rdev, i); + if (not_processed >= 3) + break; + } } if (not_processed >= 3) { /* should upclock */ diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c index 8ddab4c76710..6bef46ace831 100644 --- a/drivers/gpu/drm/radeon/radeon_prime.c +++ b/drivers/gpu/drm/radeon/radeon_prime.c @@ -169,11 +169,17 @@ struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, struct radeon_bo *bo = gem_to_radeon_bo(obj); int ret = 0; + ret = radeon_bo_reserve(bo, false); + if (unlikely(ret != 0)) + return ERR_PTR(ret); + /* pin buffer into GTT */ ret = radeon_bo_pin(bo, RADEON_GEM_DOMAIN_GTT, NULL); - if (ret) + if (ret) { + radeon_bo_unreserve(bo); return ERR_PTR(ret); - + } + radeon_bo_unreserve(bo); return dma_buf_export(bo, &radeon_dmabuf_ops, obj->size, flags); } diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 4ad0281fdc37..b4f51c569c36 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -616,6 +616,9 @@ static void rv770_gpu_init(struct radeon_device *rdev) ACK_FLUSH_CTL(3) | SYNC_FLUSH_CTL)); + if (rdev->family != CHIP_RV770) + WREG32(SMX_SAR_CTL0, 0x00003f3f); + db_debug3 = RREG32(DB_DEBUG3); db_debug3 &= ~DB_CLK_OFF_DELAY(0x1f); switch (rdev->family) { @@ -792,7 +795,7 @@ static void rv770_gpu_init(struct radeon_device *rdev) WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3))); - + WREG32(VC_ENHANCE, 0); } void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index fdc089896011..b0adfc595d75 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -211,6 +211,7 @@ #define SCRATCH_UMSK 0x8540 #define SCRATCH_ADDR 0x8544 +#define SMX_SAR_CTL0 0xA008 #define SMX_DC_CTL0 0xA020 #define USE_HASH_FUNCTION (1 << 0) #define CACHE_DEPTH(x) ((x) << 1) @@ -310,6 +311,8 @@ #define TCP_CNTL 0x9610 #define TCP_CHAN_STEER 0x9614 +#define VC_ENHANCE 0x9714 + #define VGT_CACHE_INVALIDATION 0x88C4 #define CACHE_INVALIDATION(x) ((x)<<0) #define VC_ONLY 0 diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index c7b61f16ecfd..0b0279291a73 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -2365,12 +2365,12 @@ int si_pcie_gart_enable(struct radeon_device *rdev) WREG32(0x15DC, 0); /* empty context1-15 */ - /* FIXME start with 1G, once using 2 level pt switch to full + /* FIXME start with 4G, once using 2 level pt switch to full * vm size space */ /* set vm size, must be a multiple of 4 */ WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); - WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, (1 << 30) / RADEON_GPU_PAGE_SIZE); + WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); for (i = 1; i < 16; i++) { if (i < 8) WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), diff --git a/drivers/gpu/drm/radeon/si_reg.h b/drivers/gpu/drm/radeon/si_reg.h index eda938a7cb6e..501f9d431d57 100644 --- a/drivers/gpu/drm/radeon/si_reg.h +++ b/drivers/gpu/drm/radeon/si_reg.h @@ -30,4 +30,76 @@ #define SI_DC_GPIO_HPD_EN 0x65b8 #define SI_DC_GPIO_HPD_Y 0x65bc +#define SI_GRPH_CONTROL 0x6804 +# define SI_GRPH_DEPTH(x) (((x) & 0x3) << 0) +# define SI_GRPH_DEPTH_8BPP 0 +# define SI_GRPH_DEPTH_16BPP 1 +# define SI_GRPH_DEPTH_32BPP 2 +# define SI_GRPH_NUM_BANKS(x) (((x) & 0x3) << 2) +# define SI_ADDR_SURF_2_BANK 0 +# define SI_ADDR_SURF_4_BANK 1 +# define SI_ADDR_SURF_8_BANK 2 +# define SI_ADDR_SURF_16_BANK 3 +# define SI_GRPH_Z(x) (((x) & 0x3) << 4) +# define SI_GRPH_BANK_WIDTH(x) (((x) & 0x3) << 6) +# define SI_ADDR_SURF_BANK_WIDTH_1 0 +# define SI_ADDR_SURF_BANK_WIDTH_2 1 +# define SI_ADDR_SURF_BANK_WIDTH_4 2 +# define SI_ADDR_SURF_BANK_WIDTH_8 3 +# define SI_GRPH_FORMAT(x) (((x) & 0x7) << 8) +/* 8 BPP */ +# define SI_GRPH_FORMAT_INDEXED 0 +/* 16 BPP */ +# define SI_GRPH_FORMAT_ARGB1555 0 +# define SI_GRPH_FORMAT_ARGB565 1 +# define SI_GRPH_FORMAT_ARGB4444 2 +# define SI_GRPH_FORMAT_AI88 3 +# define SI_GRPH_FORMAT_MONO16 4 +# define SI_GRPH_FORMAT_BGRA5551 5 +/* 32 BPP */ +# define SI_GRPH_FORMAT_ARGB8888 0 +# define SI_GRPH_FORMAT_ARGB2101010 1 +# define SI_GRPH_FORMAT_32BPP_DIG 2 +# define SI_GRPH_FORMAT_8B_ARGB2101010 3 +# define SI_GRPH_FORMAT_BGRA1010102 4 +# define SI_GRPH_FORMAT_8B_BGRA1010102 5 +# define SI_GRPH_FORMAT_RGB111110 6 +# define SI_GRPH_FORMAT_BGR101111 7 +# define SI_GRPH_BANK_HEIGHT(x) (((x) & 0x3) << 11) +# define SI_ADDR_SURF_BANK_HEIGHT_1 0 +# define SI_ADDR_SURF_BANK_HEIGHT_2 1 +# define SI_ADDR_SURF_BANK_HEIGHT_4 2 +# define SI_ADDR_SURF_BANK_HEIGHT_8 3 +# define SI_GRPH_TILE_SPLIT(x) (((x) & 0x7) << 13) +# define SI_ADDR_SURF_TILE_SPLIT_64B 0 +# define SI_ADDR_SURF_TILE_SPLIT_128B 1 +# define SI_ADDR_SURF_TILE_SPLIT_256B 2 +# define SI_ADDR_SURF_TILE_SPLIT_512B 3 +# define SI_ADDR_SURF_TILE_SPLIT_1KB 4 +# define SI_ADDR_SURF_TILE_SPLIT_2KB 5 +# define SI_ADDR_SURF_TILE_SPLIT_4KB 6 +# define SI_GRPH_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 18) +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_1 0 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_2 1 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_4 2 +# define SI_ADDR_SURF_MACRO_TILE_ASPECT_8 3 +# define SI_GRPH_ARRAY_MODE(x) (((x) & 0x7) << 20) +# define SI_GRPH_ARRAY_LINEAR_GENERAL 0 +# define SI_GRPH_ARRAY_LINEAR_ALIGNED 1 +# define SI_GRPH_ARRAY_1D_TILED_THIN1 2 +# define SI_GRPH_ARRAY_2D_TILED_THIN1 4 +# define SI_GRPH_PIPE_CONFIG(x) (((x) & 0x1f) << 24) +# define SI_ADDR_SURF_P2 0 +# define SI_ADDR_SURF_P4_8x16 4 +# define SI_ADDR_SURF_P4_16x16 5 +# define SI_ADDR_SURF_P4_16x32 6 +# define SI_ADDR_SURF_P4_32x32 7 +# define SI_ADDR_SURF_P8_16x16_8x16 8 +# define SI_ADDR_SURF_P8_16x32_8x16 9 +# define SI_ADDR_SURF_P8_32x32_8x16 10 +# define SI_ADDR_SURF_P8_16x32_16x16 11 +# define SI_ADDR_SURF_P8_32x32_16x16 12 +# define SI_ADDR_SURF_P8_32x32_16x32 13 +# define SI_ADDR_SURF_P8_32x64_32x32 14 + #endif diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 30d98d14b5c5..dd14cd1a0033 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c @@ -47,9 +47,9 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) if (dev_priv == NULL) return -ENOMEM; + idr_init(&dev_priv->object_idr); dev->dev_private = (void *)dev_priv; dev_priv->chipset = chipset; - idr_init(&dev->object_name_idr); return 0; } diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 4d02c46a9420..6e52069894b3 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -13,8 +13,21 @@ static struct drm_driver driver; +/* + * There are many DisplayLink-based graphics products, all with unique PIDs. + * So we match on DisplayLink's VID + Vendor-Defined Interface Class (0xff) + * We also require a match on SubClass (0x00) and Protocol (0x00), + * which is compatible with all known USB 2.0 era graphics chips and firmware, + * but allows DisplayLink to increment those for any future incompatible chips + */ static struct usb_device_id id_table[] = { - {.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,}, + {.idVendor = 0x17e9, .bInterfaceClass = 0xff, + .bInterfaceSubClass = 0x00, + .bInterfaceProtocol = 0x00, + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | + USB_DEVICE_ID_MATCH_INT_CLASS | + USB_DEVICE_ID_MATCH_INT_SUBCLASS | + USB_DEVICE_ID_MATCH_INT_PROTOCOL,}, {}, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index a8d5f09428c7..4c2d836a0893 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -61,7 +61,7 @@ static int udl_parse_vendor_descriptor(struct drm_device *dev, u8 length; u16 key; - key = *((u16 *) desc); + key = le16_to_cpu(*((u16 *) desc)); desc += sizeof(u16); length = *desc; desc++; diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c index 1f182254e81e..c126182ac07e 100644 --- a/drivers/gpu/drm/via/via_map.c +++ b/drivers/gpu/drm/via/via_map.c @@ -100,12 +100,11 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset) if (dev_priv == NULL) return -ENOMEM; + idr_init(&dev_priv->object_idr); dev->dev_private = (void *)dev_priv; dev_priv->chipset = chipset; - idr_init(&dev->object_name_idr); - pci_set_master(dev->pdev); ret = drm_vblank_init(dev, 1); diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 034c80a10f1f..bef04c192768 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -1,20 +1,11 @@ # # HID driver configuration # -menuconfig HID_SUPPORT - bool "HID Devices" - depends on INPUT - default y - ---help--- - Say Y here to get to see options for various computer-human interface - device drivers. This option alone does not add any kernel code. - - If you say N, all options in this submenu will be skipped and disabled. - -if HID_SUPPORT +menu "HID support" + depends on INPUT config HID - tristate "Generic HID support" + tristate "HID bus support" depends on INPUT default y ---help--- @@ -23,14 +14,17 @@ config HID most commonly used to refer to the USB-HID specification, but other devices (such as, but not strictly limited to, Bluetooth) are designed using HID specification (this involves certain keyboards, - mice, tablets, etc). This option compiles into kernel the generic - HID layer code (parser, usages, etc.), which can then be used by - transport-specific HID implementation (like USB or Bluetooth). + mice, tablets, etc). This option adds the HID bus to the kernel, + together with generic HID layer code. The HID devices are added and + removed from the HID bus by the transport-layer drivers, such as + usbhid (USB_HID) and hidp (BT_HIDP). For docs and specs, see http://www.usb.org/developers/hidpage/ If unsure, say Y. +if HID + config HID_BATTERY_STRENGTH bool "Battery level reporting for HID devices" depends on HID && POWER_SUPPLY && HID = POWER_SUPPLY @@ -59,23 +53,22 @@ config HIDRAW If unsure, say Y. -source "drivers/hid/usbhid/Kconfig" - -menu "Special HID drivers" - depends on HID - config HID_GENERIC tristate "Generic HID driver" depends on HID - default y + default HID ---help--- - Support for generic HID devices. + Support for generic devices on the HID bus. This includes most + keyboards and mice, joysticks, tablets and digitizers. To compile this driver as a module, choose M here: the module will be called hid-generic. If unsure, say Y. +menu "Special HID drivers" + depends on HID + config HID_A4TECH tristate "A4 tech mice" if EXPERT depends on USB_HID @@ -662,4 +655,8 @@ config HID_ZYDACRON endmenu -endif # HID_SUPPORT +endif # HID + +source "drivers/hid/usbhid/Kconfig" + +endmenu diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index fa10f847f7db..585344b6d338 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 8e3a6b261477..4c87276c8ddb 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) }, @@ -1880,6 +1883,7 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, + { HID_USB_DEVICE(USB_VENDOR_ID_AXENTIA, USB_DEVICE_ID_AXENTIA_FM_RADIO) }, { HID_USB_DEVICE(USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CIDC, 0x0103) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X) }, @@ -1994,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) }, @@ -2088,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 9373f535dfe9..875ff451842b 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 @@ -160,6 +163,9 @@ #define USB_VENDOR_ID_AVERMEDIA 0x07ca #define USB_DEVICE_ID_AVER_FM_MR800 0xb800 +#define USB_VENDOR_ID_AXENTIA 0x12cf +#define USB_DEVICE_ID_AXENTIA_FM_RADIO 0x7111 + #define USB_VENDOR_ID_BAANTO 0x2453 #define USB_DEVICE_ID_BAANTO_MT_190W2 0x0100 @@ -515,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/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 5e8a7ed42344..0f9c146fc00d 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -436,27 +436,37 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) { - struct dj_report dj_report; + struct dj_report *dj_report; + int retval; - memset(&dj_report, 0, sizeof(dj_report)); - dj_report.report_id = REPORT_ID_DJ_SHORT; - dj_report.device_index = 0xFF; - dj_report.report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES; - return logi_dj_recv_send_report(djrcv_dev, &dj_report); + dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); + if (!dj_report) + return -ENOMEM; + dj_report->report_id = REPORT_ID_DJ_SHORT; + dj_report->device_index = 0xFF; + dj_report->report_type = REPORT_TYPE_CMD_GET_PAIRED_DEVICES; + retval = logi_dj_recv_send_report(djrcv_dev, dj_report); + kfree(dj_report); + return retval; } static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, unsigned timeout) { - struct dj_report dj_report; + struct dj_report *dj_report; + int retval; - memset(&dj_report, 0, sizeof(dj_report)); - dj_report.report_id = REPORT_ID_DJ_SHORT; - dj_report.device_index = 0xFF; - dj_report.report_type = REPORT_TYPE_CMD_SWITCH; - dj_report.report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; - dj_report.report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; - return logi_dj_recv_send_report(djrcv_dev, &dj_report); + dj_report = kzalloc(sizeof(dj_report), GFP_KERNEL); + if (!dj_report) + return -ENOMEM; + dj_report->report_id = REPORT_ID_DJ_SHORT; + dj_report->device_index = 0xFF; + dj_report->report_type = REPORT_TYPE_CMD_SWITCH; + dj_report->report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; + dj_report->report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; + retval = logi_dj_recv_send_report(djrcv_dev, dj_report); + kfree(dj_report); + return retval; } diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 7cf3ffe4b7bc..40ac6654f1d1 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -426,8 +426,10 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h __set_bit(EV_ABS, input->evbit); input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); - input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2, + 4, 0); + input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2, + 4, 0); input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0); /* Note: Touch Y position from the device is inverted relative diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig index 0f20fd17cf06..0108c5991a04 100644 --- a/drivers/hid/usbhid/Kconfig +++ b/drivers/hid/usbhid/Kconfig @@ -1,13 +1,13 @@ -comment "USB Input Devices" +menu "USB HID support" depends on USB config USB_HID - tristate "USB Human Interface Device (full HID) support" + tristate "USB HID transport layer" default y depends on USB && INPUT select HID ---help--- - Say Y here if you want full HID support to connect USB keyboards, + Say Y here if you want to connect USB keyboards, mice, joysticks, graphic tablets, or any other HID based devices to your computer via USB, as well as Uninterruptible Power Supply (UPS) and monitor control devices. @@ -81,4 +81,4 @@ config USB_MOUSE endmenu - +endmenu diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index f082e48ab113..2cde9ecf7731 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -8,7 +8,7 @@ * * Based on hdaps.c driver: * Copyright (C) 2005 Robert Love <rml@novell.com> - * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com> + * Copyright (C) 2005 Jesper Juhl <jj@chaosbits.net> * * Fan control based on smcFanControl: * Copyright (C) 2006 Hendrik Holtmann <holtmann@mac.com> @@ -215,7 +215,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) int i; if (send_command(cmd) || send_argument(key)) { - pr_warn("%s: read arg fail\n", key); + pr_warn("%.4s: read arg fail\n", key); return -EIO; } @@ -223,7 +223,7 @@ static int read_smc(u8 cmd, const char *key, u8 *buffer, u8 len) for (i = 0; i < len; i++) { if (__wait_status(0x05)) { - pr_warn("%s: read data fail\n", key); + pr_warn("%.4s: read data fail\n", key); return -EIO; } buffer[i] = inb(APPLESMC_DATA_PORT); diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index b9d512331ed4..637c51c11b44 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -191,6 +191,24 @@ static ssize_t show_temp(struct device *dev, return tdata->valid ? sprintf(buf, "%d\n", tdata->temp) : -EAGAIN; } +struct tjmax { + char const *id; + int tjmax; +}; + +static struct tjmax __cpuinitconst tjmax_table[] = { + { "CPU D410", 100000 }, + { "CPU D425", 100000 }, + { "CPU D510", 100000 }, + { "CPU D525", 100000 }, + { "CPU N450", 100000 }, + { "CPU N455", 100000 }, + { "CPU N470", 100000 }, + { "CPU N475", 100000 }, + { "CPU 230", 100000 }, + { "CPU 330", 125000 }, +}; + static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) { @@ -202,6 +220,13 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, int err; u32 eax, edx; struct pci_dev *host_bridge; + int i; + + /* explicit tjmax table entries override heuristics */ + for (i = 0; i < ARRAY_SIZE(tjmax_table); i++) { + if (strstr(c->x86_model_id, tjmax_table[i].id)) + return tjmax_table[i].tjmax; + } /* Early chips have no MSR for TjMax */ @@ -210,7 +235,8 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, /* Atom CPUs */ - if (c->x86_model == 0x1c) { + if (c->x86_model == 0x1c || c->x86_model == 0x26 + || c->x86_model == 0x27) { usemsr_ee = 0; host_bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 0)); @@ -223,6 +249,9 @@ static int __cpuinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, tjmax = 90000; pci_dev_put(host_bridge); + } else if (c->x86_model == 0x36) { + usemsr_ee = 0; + tjmax = 100000; } if (c->x86_model > 0xe && usemsr_ee) { @@ -664,7 +693,7 @@ static void __cpuinit get_core_online(unsigned int cpu) * sensors. We check this bit only, all the early CPUs * without thermal sensors will be filtered out. */ - if (!cpu_has(c, X86_FEATURE_DTS)) + if (!cpu_has(c, X86_FEATURE_DTHERM)) return; if (!pdev) { @@ -765,14 +794,14 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { }; static const struct x86_cpu_id coretemp_ids[] = { - { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTS }, + { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTHERM }, {} }; MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); static int __init coretemp_init(void) { - int i, err = -ENODEV; + int i, err; /* * CPUID.06H.EAX[0] indicates whether the CPU has thermal diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c index 9691f664c76e..e7d234b59312 100644 --- a/drivers/hwmon/emc2103.c +++ b/drivers/hwmon/emc2103.c @@ -451,11 +451,15 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, data->fan_rpm_control = true; break; default: - mutex_unlock(&data->update_lock); - return -EINVAL; + count = -EINVAL; + goto err; } - read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); + result = read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg); + if (result) { + count = result; + goto err; + } if (data->fan_rpm_control) conf_reg |= 0x80; @@ -463,7 +467,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da, conf_reg &= ~0x80; i2c_smbus_write_byte_data(client, REG_FAN_CONF1, conf_reg); - +err: mutex_unlock(&data->update_lock); return count; } diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index e7701d99f8e8..f1de3979181f 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/hwmon/jc42.c b/drivers/hwmon/jc42.c index a9bfd6736d9a..e72ba5d2a824 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c @@ -590,6 +590,6 @@ abort: module_i2c_driver(jc42_driver); -MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); +MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); MODULE_DESCRIPTION("JC42 driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c index d264937c7f5e..bd75d2415432 100644 --- a/drivers/hwmon/lineage-pem.c +++ b/drivers/hwmon/lineage-pem.c @@ -567,6 +567,6 @@ static struct i2c_driver pem_driver = { module_i2c_driver(pem_driver); -MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); +MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); MODULE_DESCRIPTION("Lineage CPL PEM hardware monitoring driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c index 069b7d34d8f9..77476a575c4e 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c @@ -292,6 +292,6 @@ static struct i2c_driver ltc4261_driver = { module_i2c_driver(ltc4261_driver); -MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); +MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); MODULE_DESCRIPTION("LTC4261 driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/max16065.c b/drivers/hwmon/max16065.c index 822261be84dd..019427d7a5fd 100644 --- a/drivers/hwmon/max16065.c +++ b/drivers/hwmon/max16065.c @@ -692,6 +692,6 @@ static struct i2c_driver max16065_driver = { module_i2c_driver(max16065_driver); -MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>"); +MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); MODULE_DESCRIPTION("MAX16065 driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/hwspinlock/hwspinlock_core.c b/drivers/hwspinlock/hwspinlock_core.c index 61c9cf15fa52..1201a15784c3 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/iio/Kconfig b/drivers/iio/Kconfig index 56eecefcec75..2ec93da41e2c 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -8,8 +8,7 @@ menuconfig IIO help The industrial I/O subsystem provides a unified framework for drivers for many different types of embedded sensors using a - number of different physical interfaces (i2c, spi, etc). See - Documentation/iio for more information. + number of different physical interfaces (i2c, spi, etc). if IIO diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 1ddd8861c71b..4f947e4377ef 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -661,7 +661,6 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev) * New channel registration method - relies on the fact a group does * not need to be initialized if it is name is NULL. */ - INIT_LIST_HEAD(&indio_dev->channel_attr_list); if (indio_dev->channels) for (i = 0; i < indio_dev->num_channels; i++) { ret = iio_device_add_channel_sysfs(indio_dev, @@ -725,12 +724,16 @@ static void iio_device_unregister_sysfs(struct iio_dev *indio_dev) static void iio_dev_release(struct device *device) { struct iio_dev *indio_dev = dev_to_iio_dev(device); - cdev_del(&indio_dev->chrdev); + if (indio_dev->chrdev.dev) + cdev_del(&indio_dev->chrdev); if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) iio_device_unregister_trigger_consumer(indio_dev); iio_device_unregister_eventset(indio_dev); iio_device_unregister_sysfs(indio_dev); iio_device_unregister_debugfs(indio_dev); + + ida_simple_remove(&iio_ida, indio_dev->id); + kfree(indio_dev); } static struct device_type iio_dev_type = { @@ -761,6 +764,7 @@ struct iio_dev *iio_device_alloc(int sizeof_priv) dev_set_drvdata(&dev->dev, (void *)dev); mutex_init(&dev->mlock); mutex_init(&dev->info_exist_lock); + INIT_LIST_HEAD(&dev->channel_attr_list); dev->id = ida_simple_get(&iio_ida, 0, 0, GFP_KERNEL); if (dev->id < 0) { @@ -778,10 +782,8 @@ EXPORT_SYMBOL(iio_device_alloc); void iio_device_free(struct iio_dev *dev) { - if (dev) { - ida_simple_remove(&iio_ida, dev->id); - kfree(dev); - } + if (dev) + put_device(&dev->dev); } EXPORT_SYMBOL(iio_device_free); @@ -902,7 +904,7 @@ void iio_device_unregister(struct iio_dev *indio_dev) mutex_lock(&indio_dev->info_exist_lock); indio_dev->info = NULL; mutex_unlock(&indio_dev->info_exist_lock); - device_unregister(&indio_dev->dev); + device_del(&indio_dev->dev); } EXPORT_SYMBOL(iio_device_unregister); subsys_initcall(iio_init); diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 55d5642eb10a..2e826f9702c6 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1184,7 +1184,7 @@ static void cma_set_req_event_data(struct rdma_cm_event *event, static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_event) { - return (((ib_event->event == IB_CM_REQ_RECEIVED) || + return (((ib_event->event == IB_CM_REQ_RECEIVED) && (ib_event->param.req_rcvd.qp_type == id->qp_type)) || ((ib_event->event == IB_CM_SIDR_REQ_RECEIVED) && (id->qp_type == IB_QPT_UD)) || diff --git a/drivers/infiniband/hw/ocrdma/ocrdma.h b/drivers/infiniband/hw/ocrdma/ocrdma.h index 037f5cea85bd..48970af23679 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma.h @@ -61,6 +61,7 @@ struct ocrdma_dev_attr { u32 max_inline_data; int max_send_sge; int max_recv_sge; + int max_srq_sge; int max_mr; u64 max_mr_size; u32 max_num_mr_pbl; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 9343a1522977..71942af4fce9 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c @@ -990,8 +990,6 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, struct ocrdma_dev_attr *attr, struct ocrdma_mbx_query_config *rsp) { - int max_q_mem; - attr->max_pd = (rsp->max_pd_ca_ack_delay & OCRDMA_MBX_QUERY_CFG_MAX_PD_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_PD_SHIFT; @@ -1004,6 +1002,9 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, attr->max_recv_sge = (rsp->max_write_send_sge & OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT; + attr->max_srq_sge = (rsp->max_srq_rqe_sge & + OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_MASK) >> + OCRDMA_MBX_QUERY_CFG_MAX_SRQ_SGE_OFFSET; attr->max_ord_per_qp = (rsp->max_ird_ord_per_qp & OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK) >> OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT; @@ -1037,18 +1038,15 @@ static void ocrdma_get_attr(struct ocrdma_dev *dev, attr->max_inline_data = attr->wqe_size - (sizeof(struct ocrdma_hdr_wqe) + sizeof(struct ocrdma_sge)); - max_q_mem = OCRDMA_Q_PAGE_BASE_SIZE << (OCRDMA_MAX_Q_PAGE_SIZE_CNT - 1); - /* hw can queue one less then the configured size, - * so publish less by one to stack. - */ if (dev->nic_info.dev_family == OCRDMA_GEN2_FAMILY) { - dev->attr.max_wqe = max_q_mem / dev->attr.wqe_size; attr->ird = 1; attr->ird_page_size = OCRDMA_MIN_Q_PAGE_SIZE; attr->num_ird_pages = MAX_OCRDMA_IRD_PAGES; - } else - dev->attr.max_wqe = (max_q_mem / dev->attr.wqe_size) - 1; - dev->attr.max_rqe = (max_q_mem / dev->attr.rqe_size) - 1; + } + dev->attr.max_wqe = rsp->max_wqes_rqes_per_q >> + OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET; + dev->attr.max_rqe = rsp->max_wqes_rqes_per_q & + OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK; } static int ocrdma_check_fw_config(struct ocrdma_dev *dev, diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index 04fef3de6d75..b050e629e9c3 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c @@ -97,13 +97,11 @@ static void ocrdma_build_sgid_mac(union ib_gid *sgid, unsigned char *mac_addr, sgid->raw[15] = mac_addr[5]; } -static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, +static bool ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, bool is_vlan, u16 vlan_id) { int i; - bool found = false; union ib_gid new_sgid; - int free_idx = OCRDMA_MAX_SGID; unsigned long flags; memset(&ocrdma_zero_sgid, 0, sizeof(union ib_gid)); @@ -115,23 +113,19 @@ static void ocrdma_add_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, if (!memcmp(&dev->sgid_tbl[i], &ocrdma_zero_sgid, sizeof(union ib_gid))) { /* found free entry */ - if (!found) { - free_idx = i; - found = true; - break; - } + memcpy(&dev->sgid_tbl[i], &new_sgid, + sizeof(union ib_gid)); + spin_unlock_irqrestore(&dev->sgid_lock, flags); + return true; } else if (!memcmp(&dev->sgid_tbl[i], &new_sgid, sizeof(union ib_gid))) { /* entry already present, no addition is required. */ spin_unlock_irqrestore(&dev->sgid_lock, flags); - return; + return false; } } - /* if entry doesn't exist and if table has some space, add entry */ - if (found) - memcpy(&dev->sgid_tbl[free_idx], &new_sgid, - sizeof(union ib_gid)); spin_unlock_irqrestore(&dev->sgid_lock, flags); + return false; } static bool ocrdma_del_sgid(struct ocrdma_dev *dev, unsigned char *mac_addr, @@ -167,7 +161,8 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev) ocrdma_get_guid(dev, &sgid->raw[8]); } -static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) { struct net_device *netdev, *tmp; u16 vlan_id; @@ -175,8 +170,6 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) netdev = dev->nic_info.netdev; - ocrdma_add_default_sgid(dev); - rcu_read_lock(); for_each_netdev_rcu(&init_net, tmp) { if (netdev == tmp || vlan_dev_real_dev(tmp) == netdev) { @@ -194,10 +187,23 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) } } rcu_read_unlock(); +} +#else +static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) +{ + +} +#endif /* VLAN */ + +static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) +{ + ocrdma_add_default_sgid(dev); + ocrdma_add_vlan_sgids(dev); return 0; } -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) || \ +defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) static int ocrdma_inet6addr_event(struct notifier_block *notifier, unsigned long event, void *ptr) @@ -208,6 +214,7 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, struct ib_event gid_event; struct ocrdma_dev *dev; bool found = false; + bool updated = false; bool is_vlan = false; u16 vid = 0; @@ -233,23 +240,21 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, mutex_lock(&dev->dev_lock); switch (event) { case NETDEV_UP: - ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); + updated = ocrdma_add_sgid(dev, netdev->dev_addr, is_vlan, vid); break; case NETDEV_DOWN: - found = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); - if (found) { - /* found the matching entry, notify - * the consumers about it - */ - gid_event.device = &dev->ibdev; - gid_event.element.port_num = 1; - gid_event.event = IB_EVENT_GID_CHANGE; - ib_dispatch_event(&gid_event); - } + updated = ocrdma_del_sgid(dev, netdev->dev_addr, is_vlan, vid); break; default: break; } + if (updated) { + /* GID table updated, notify the consumers about it */ + gid_event.device = &dev->ibdev; + gid_event.element.port_num = 1; + gid_event.event = IB_EVENT_GID_CHANGE; + ib_dispatch_event(&gid_event); + } mutex_unlock(&dev->dev_lock); return NOTIFY_OK; } @@ -258,7 +263,7 @@ static struct notifier_block ocrdma_inet6addr_notifier = { .notifier_call = ocrdma_inet6addr_event }; -#endif /* IPV6 */ +#endif /* IPV6 and VLAN */ static enum rdma_link_layer ocrdma_link_layer(struct ib_device *device, u8 port_num) diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h index 7fd80cc0f037..c75cbdfa87e7 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_sli.h +++ b/drivers/infiniband/hw/ocrdma/ocrdma_sli.h @@ -418,6 +418,9 @@ enum { OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_SHIFT = 0, OCRDMA_MBX_QUERY_CFG_MAX_SEND_SGE_MASK = 0xFFFF, + OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT = 16, + OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_MASK = 0xFFFF << + OCRDMA_MBX_QUERY_CFG_MAX_WRITE_SGE_SHIFT, OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_SHIFT = 0, OCRDMA_MBX_QUERY_CFG_MAX_ORD_PER_QP_MASK = 0xFFFF, @@ -458,7 +461,7 @@ enum { OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET = 0, OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_MASK = 0xFFFF << - OCRDMA_MBX_QUERY_CFG_MAX_WQES_PER_WQ_OFFSET, + OCRDMA_MBX_QUERY_CFG_MAX_RQES_PER_RQ_OFFSET, OCRDMA_MBX_QUERY_CFG_MAX_CQ_OFFSET = 16, OCRDMA_MBX_QUERY_CFG_MAX_CQ_MASK = 0xFFFF << diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index d16d172b6b6b..2e2e7aecc990 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -53,7 +53,7 @@ int ocrdma_query_gid(struct ib_device *ibdev, u8 port, dev = get_ocrdma_dev(ibdev); memset(sgid, 0, sizeof(*sgid)); - if (index > OCRDMA_MAX_SGID) + if (index >= OCRDMA_MAX_SGID) return -EINVAL; memcpy(sgid, &dev->sgid_tbl[index], sizeof(*sgid)); @@ -83,8 +83,8 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) IB_DEVICE_SHUTDOWN_PORT | IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_LOCAL_DMA_LKEY; - attr->max_sge = dev->attr.max_send_sge; - attr->max_sge_rd = dev->attr.max_send_sge; + attr->max_sge = min(dev->attr.max_send_sge, dev->attr.max_srq_sge); + attr->max_sge_rd = 0; attr->max_cq = dev->attr.max_cq; attr->max_cqe = dev->attr.max_cqe; attr->max_mr = dev->attr.max_mr; @@ -97,7 +97,7 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr) min(dev->attr.max_ord_per_qp, dev->attr.max_ird_per_qp); attr->max_qp_init_rd_atom = dev->attr.max_ord_per_qp; attr->max_srq = (dev->attr.max_qp - 1); - attr->max_srq_sge = attr->max_sge; + attr->max_srq_sge = attr->max_srq_sge; attr->max_srq_wr = dev->attr.max_rqe; attr->local_ca_ack_delay = dev->attr.local_ca_ack_delay; attr->max_fast_reg_page_list_len = 0; @@ -2301,8 +2301,10 @@ static bool ocrdma_poll_err_rcqe(struct ocrdma_qp *qp, struct ocrdma_cqe *cqe, *stop = true; expand = false; } - } else + } else { + *polled = true; expand = ocrdma_update_err_rcqe(ibwc, cqe, qp, status); + } return expand; } diff --git a/drivers/input/joystick/as5011.c b/drivers/input/joystick/as5011.c index 57d19d4e0a2d..c96653b58867 100644 --- a/drivers/input/joystick/as5011.c +++ b/drivers/input/joystick/as5011.c @@ -282,7 +282,8 @@ static int __devinit as5011_probe(struct i2c_client *client, error = request_threaded_irq(as5011->button_irq, NULL, as5011_button_interrupt, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "as5011_button", as5011); if (error < 0) { dev_err(&client->dev, @@ -296,7 +297,7 @@ static int __devinit as5011_probe(struct i2c_client *client, error = request_threaded_irq(as5011->axis_irq, NULL, as5011_axis_interrupt, - plat_data->axis_irqflags, + plat_data->axis_irqflags | IRQF_ONESHOT, "as5011_joystick", as5011); if (error) { dev_err(&client->dev, diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index ee16fb67b7ae..83811e45d633 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/keyboard/mcs_touchkey.c b/drivers/input/keyboard/mcs_touchkey.c index 64a0ca4c92f3..0d77f6c84950 100644 --- a/drivers/input/keyboard/mcs_touchkey.c +++ b/drivers/input/keyboard/mcs_touchkey.c @@ -178,7 +178,8 @@ static int __devinit mcs_touchkey_probe(struct i2c_client *client, } error = request_threaded_irq(client->irq, NULL, mcs_touchkey_interrupt, - IRQF_TRIGGER_FALLING, client->dev.driver->name, data); + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + client->dev.driver->name, data); if (error) { dev_err(&client->dev, "Failed to register interrupt\n"); goto err_free_mem; diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index caa218a51b5a..7613f1cac951 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -248,7 +248,7 @@ static int __devinit mpr_touchkey_probe(struct i2c_client *client, error = request_threaded_irq(client->irq, NULL, mpr_touchkey_interrupt, - IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->dev.driver->name, mpr121); if (error) { dev_err(&client->dev, "Failed to register interrupt\n"); diff --git a/drivers/input/keyboard/qt1070.c b/drivers/input/keyboard/qt1070.c index 0b7b2f891752..ca68f2992d72 100644 --- a/drivers/input/keyboard/qt1070.c +++ b/drivers/input/keyboard/qt1070.c @@ -201,7 +201,8 @@ static int __devinit qt1070_probe(struct i2c_client *client, msleep(QT1070_RESET_TIME); err = request_threaded_irq(client->irq, NULL, qt1070_interrupt, - IRQF_TRIGGER_NONE, client->dev.driver->name, data); + IRQF_TRIGGER_NONE | IRQF_ONESHOT, + client->dev.driver->name, data); if (err) { dev_err(&client->dev, "fail to request irq\n"); goto err_free_mem; diff --git a/drivers/input/keyboard/tca6416-keypad.c b/drivers/input/keyboard/tca6416-keypad.c index 3afea3f89718..c355cdde8d22 100644 --- a/drivers/input/keyboard/tca6416-keypad.c +++ b/drivers/input/keyboard/tca6416-keypad.c @@ -278,7 +278,8 @@ static int __devinit tca6416_keypad_probe(struct i2c_client *client, error = request_threaded_irq(chip->irqnum, NULL, tca6416_keys_isr, - IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, "tca6416-keypad", chip); if (error) { dev_dbg(&client->dev, diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 5f87b28b3192..893869b29ed9 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -360,7 +360,7 @@ static int __devinit tca8418_keypad_probe(struct i2c_client *client, client->irq = gpio_to_irq(client->irq); error = request_threaded_irq(client->irq, NULL, tca8418_irq_handler, - IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, keypad_data); if (error) { dev_dbg(&client->dev, diff --git a/drivers/input/keyboard/tnetv107x-keypad.c b/drivers/input/keyboard/tnetv107x-keypad.c index a4a445fb7020..4c34f21fbe2d 100644 --- a/drivers/input/keyboard/tnetv107x-keypad.c +++ b/drivers/input/keyboard/tnetv107x-keypad.c @@ -227,15 +227,15 @@ static int __devinit keypad_probe(struct platform_device *pdev) goto error_clk; } - error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, 0, - dev_name(dev), kp); + error = request_threaded_irq(kp->irq_press, NULL, keypad_irq, + IRQF_ONESHOT, dev_name(dev), kp); if (error < 0) { dev_err(kp->dev, "Could not allocate keypad press key irq\n"); goto error_irq_press; } - error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, 0, - dev_name(dev), kp); + error = request_threaded_irq(kp->irq_release, NULL, keypad_irq, + IRQF_ONESHOT, dev_name(dev), kp); if (error < 0) { dev_err(kp->dev, "Could not allocate keypad release key irq\n"); goto error_irq_release; diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c index 0ac75bbad4d6..2e5d5e1de647 100644 --- a/drivers/input/misc/ad714x.c +++ b/drivers/input/misc/ad714x.c @@ -972,6 +972,7 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, struct ad714x_platform_data *plat_data = dev->platform_data; struct ad714x_chip *ad714x; void *drv_mem; + unsigned long irqflags; struct ad714x_button_drv *bt_drv; struct ad714x_slider_drv *sd_drv; @@ -1162,10 +1163,11 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, alloc_idx++; } + irqflags = plat_data->irqflags ?: IRQF_TRIGGER_FALLING; + irqflags |= IRQF_ONESHOT; + error = request_threaded_irq(ad714x->irq, NULL, ad714x_interrupt_thread, - plat_data->irqflags ? - plat_data->irqflags : IRQF_TRIGGER_FALLING, - "ad714x_captouch", ad714x); + irqflags, "ad714x_captouch", ad714x); if (error) { dev_err(dev, "can't allocate irq %d\n", ad714x->irq); goto err_unreg_dev; diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c index 35083c6836c3..c1313d8535c3 100644 --- a/drivers/input/misc/dm355evm_keys.c +++ b/drivers/input/misc/dm355evm_keys.c @@ -213,7 +213,8 @@ static int __devinit dm355evm_keys_probe(struct platform_device *pdev) /* REVISIT: flush the event queue? */ status = request_threaded_irq(keys->irq, NULL, dm355evm_keys_irq, - IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), keys); + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + dev_name(&pdev->dev), keys); if (status < 0) goto fail2; diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 2cf681d98c0d..d528c23e194f 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/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index cad5602d3ce4..8b31473a81fe 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -216,7 +216,7 @@ static void wacom_retrieve_report_data(struct usb_interface *intf, rep_data[0] = 12; result = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, - rep_data[0], &rep_data, 2, + rep_data[0], rep_data, 2, WAC_MSG_RETRIES); if (result >= 0 && rep_data[1] > 2) @@ -401,7 +401,9 @@ static int wacom_parse_hid(struct usb_interface *intf, break; case HID_USAGE_CONTACTMAX: - wacom_retrieve_report_data(intf, features); + /* leave touch_max as is if predefined */ + if (!features->touch_max) + wacom_retrieve_report_data(intf, features); i++; break; } diff --git a/drivers/input/touchscreen/ad7879.c b/drivers/input/touchscreen/ad7879.c index e2482b40da51..bd4eb4277697 100644 --- a/drivers/input/touchscreen/ad7879.c +++ b/drivers/input/touchscreen/ad7879.c @@ -597,7 +597,7 @@ struct ad7879 *ad7879_probe(struct device *dev, u8 devid, unsigned int irq, AD7879_TMR(ts->pen_down_acc_interval); err = request_threaded_irq(ts->irq, NULL, ad7879_irq, - IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, dev_name(dev), ts); if (err) { dev_err(dev, "irq %d busy?\n", ts->irq); diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 42e645062c20..25fd0561a17d 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -1149,7 +1149,8 @@ static int __devinit mxt_probe(struct i2c_client *client, goto err_free_object; error = request_threaded_irq(client->irq, NULL, mxt_interrupt, - pdata->irqflags, client->dev.driver->name, data); + pdata->irqflags | IRQF_ONESHOT, + client->dev.driver->name, data); if (error) { dev_err(&client->dev, "Failed to register interrupt\n"); goto err_free_object; diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c index f2d03c06c2da..5c487d23f11c 100644 --- a/drivers/input/touchscreen/bu21013_ts.c +++ b/drivers/input/touchscreen/bu21013_ts.c @@ -509,7 +509,8 @@ static int __devinit bu21013_probe(struct i2c_client *client, input_set_drvdata(in_dev, bu21013_data); error = request_threaded_irq(pdata->irq, NULL, bu21013_gpio_irq, - IRQF_TRIGGER_FALLING | IRQF_SHARED, + IRQF_TRIGGER_FALLING | IRQF_SHARED | + IRQF_ONESHOT, DRIVER_TP, bu21013_data); if (error) { dev_err(&client->dev, "request irq %d failed\n", pdata->irq); diff --git a/drivers/input/touchscreen/cy8ctmg110_ts.c b/drivers/input/touchscreen/cy8ctmg110_ts.c index 237753ad1031..464f1bf4b61d 100644 --- a/drivers/input/touchscreen/cy8ctmg110_ts.c +++ b/drivers/input/touchscreen/cy8ctmg110_ts.c @@ -251,7 +251,8 @@ static int __devinit cy8ctmg110_probe(struct i2c_client *client, } err = request_threaded_irq(client->irq, NULL, cy8ctmg110_irq_thread, - IRQF_TRIGGER_RISING, "touch_reset_key", ts); + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "touch_reset_key", ts); if (err < 0) { dev_err(&client->dev, "irq %d busy? error %d\n", client->irq, err); diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c index 3cd7a837f82b..cf299377fc49 100644 --- a/drivers/input/touchscreen/intel-mid-touch.c +++ b/drivers/input/touchscreen/intel-mid-touch.c @@ -620,7 +620,7 @@ static int __devinit mrstouch_probe(struct platform_device *pdev) MRST_PRESSURE_MIN, MRST_PRESSURE_MAX, 0, 0); err = request_threaded_irq(tsdev->irq, NULL, mrstouch_pendet_irq, - 0, "mrstouch", tsdev); + IRQF_ONESHOT, "mrstouch", tsdev); if (err) { dev_err(tsdev->dev, "unable to allocate irq\n"); goto err_free_mem; diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index 72f6ba3a4709..953b4c105cad 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -165,7 +165,7 @@ static int __devinit pixcir_i2c_ts_probe(struct i2c_client *client, input_set_drvdata(input, tsdata); error = request_threaded_irq(client->irq, NULL, pixcir_ts_isr, - IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, tsdata); if (error) { dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); diff --git a/drivers/input/touchscreen/tnetv107x-ts.c b/drivers/input/touchscreen/tnetv107x-ts.c index 7e7488097359..368d2c6cf780 100644 --- a/drivers/input/touchscreen/tnetv107x-ts.c +++ b/drivers/input/touchscreen/tnetv107x-ts.c @@ -297,7 +297,7 @@ static int __devinit tsc_probe(struct platform_device *pdev) goto error_clk; } - error = request_threaded_irq(ts->tsc_irq, NULL, tsc_irq, 0, + error = request_threaded_irq(ts->tsc_irq, NULL, tsc_irq, IRQF_ONESHOT, dev_name(dev), ts); if (error < 0) { dev_err(ts->dev, "Could not allocate ts irq\n"); diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index b6adeaee9cc5..5ce3fa8ce646 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c @@ -650,7 +650,8 @@ static int __devinit tsc2005_probe(struct spi_device *spi) tsc2005_stop_scan(ts); error = request_threaded_irq(spi->irq, NULL, tsc2005_irq_thread, - IRQF_TRIGGER_RISING, "tsc2005", ts); + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "tsc2005", ts); if (error) { dev_err(&spi->dev, "Failed to request irq, err: %d\n", error); goto err_free_mem; diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index a2e418cba0ff..625626391f2d 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 542024ba6dba..a33612f3206f 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 24355559a2ad..c1b1d489817e 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/leds/ledtrig-heartbeat.c b/drivers/leds/ledtrig-heartbeat.c index 41dc76db4311..a019fbb70880 100644 --- a/drivers/leds/ledtrig-heartbeat.c +++ b/drivers/leds/ledtrig-heartbeat.c @@ -21,6 +21,8 @@ #include <linux/reboot.h> #include "leds.h" +static int panic_heartbeats; + struct heartbeat_trig_data { unsigned int phase; unsigned int period; @@ -34,6 +36,11 @@ static void led_heartbeat_function(unsigned long data) unsigned long brightness = LED_OFF; unsigned long delay = 0; + if (unlikely(panic_heartbeats)) { + led_set_brightness(led_cdev, LED_OFF); + return; + } + /* acts like an actual heart beat -- ie thump-thump-pause... */ switch (heartbeat_data->phase) { case 0: @@ -111,12 +118,19 @@ static int heartbeat_reboot_notifier(struct notifier_block *nb, return NOTIFY_DONE; } +static int heartbeat_panic_notifier(struct notifier_block *nb, + unsigned long code, void *unused) +{ + panic_heartbeats = 1; + return NOTIFY_DONE; +} + static struct notifier_block heartbeat_reboot_nb = { .notifier_call = heartbeat_reboot_notifier, }; static struct notifier_block heartbeat_panic_nb = { - .notifier_call = heartbeat_reboot_notifier, + .notifier_call = heartbeat_panic_notifier, }; static int __init heartbeat_trig_init(void) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 37fdaf81bd1f..ce59824fb414 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -2292,6 +2292,13 @@ static int process_reserve_metadata_snap_mesg(unsigned argc, char **argv, struct if (r) return r; + r = dm_pool_commit_metadata(pool->pmd); + if (r) { + DMERR("%s: dm_pool_commit_metadata() failed, error = %d", + __func__, r); + return r; + } + r = dm_pool_reserve_metadata_snap(pool->pmd); if (r) DMWARN("reserve_metadata_snap message failed."); diff --git a/drivers/md/md.c b/drivers/md/md.c index 1c2f9048e1ae..a4c219e3c859 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5784,8 +5784,7 @@ static int add_new_disk(struct mddev * mddev, mdu_disk_info_t *info) super_types[mddev->major_version]. validate_super(mddev, rdev); if ((info->state & (1<<MD_DISK_SYNC)) && - (!test_bit(In_sync, &rdev->flags) || - rdev->raid_disk != info->raid_disk)) { + rdev->raid_disk != info->raid_disk) { /* This was a hot-add request, but events doesn't * match, so reject it. */ @@ -6751,7 +6750,7 @@ struct md_thread *md_register_thread(void (*run) (struct mddev *), struct mddev thread->tsk = kthread_run(md_thread, thread, "%s_%s", mdname(thread->mddev), - name ?: mddev->pers->name); + name); if (IS_ERR(thread->tsk)) { kfree(thread); return NULL; @@ -7298,6 +7297,7 @@ void md_do_sync(struct mddev *mddev) int skipped = 0; struct md_rdev *rdev; char *desc; + struct blk_plug plug; /* just incase thread restarts... */ if (test_bit(MD_RECOVERY_DONE, &mddev->recovery)) @@ -7447,6 +7447,7 @@ void md_do_sync(struct mddev *mddev) } mddev->curr_resync_completed = j; + blk_start_plug(&plug); while (j < max_sectors) { sector_t sectors; @@ -7552,6 +7553,7 @@ void md_do_sync(struct mddev *mddev) * this also signals 'finished resyncing' to md_stop */ out: + blk_finish_plug(&plug); wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active)); /* tell personality that we are finished */ diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 9339e67fcc79..61a1833ebaf3 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -474,7 +474,8 @@ static int multipath_run (struct mddev *mddev) } { - mddev->thread = md_register_thread(multipathd, mddev, NULL); + mddev->thread = md_register_thread(multipathd, mddev, + "multipath"); if (!mddev->thread) { printk(KERN_ERR "multipath: couldn't allocate thread" " for %s\n", mdname(mddev)); diff --git a/drivers/md/persistent-data/dm-space-map-checker.c b/drivers/md/persistent-data/dm-space-map-checker.c index 50ed53bf4aa2..fc90c11620ad 100644 --- a/drivers/md/persistent-data/dm-space-map-checker.c +++ b/drivers/md/persistent-data/dm-space-map-checker.c @@ -8,6 +8,7 @@ #include <linux/device-mapper.h> #include <linux/export.h> +#include <linux/vmalloc.h> #ifdef CONFIG_DM_DEBUG_SPACE_MAPS @@ -89,13 +90,23 @@ static int ca_create(struct count_array *ca, struct dm_space_map *sm) ca->nr = nr_blocks; ca->nr_free = nr_blocks; - ca->counts = kzalloc(sizeof(*ca->counts) * nr_blocks, GFP_KERNEL); - if (!ca->counts) - return -ENOMEM; + + if (!nr_blocks) + ca->counts = NULL; + else { + ca->counts = vzalloc(sizeof(*ca->counts) * nr_blocks); + if (!ca->counts) + return -ENOMEM; + } return 0; } +static void ca_destroy(struct count_array *ca) +{ + vfree(ca->counts); +} + static int ca_load(struct count_array *ca, struct dm_space_map *sm) { int r; @@ -126,12 +137,14 @@ static int ca_load(struct count_array *ca, struct dm_space_map *sm) static int ca_extend(struct count_array *ca, dm_block_t extra_blocks) { dm_block_t nr_blocks = ca->nr + extra_blocks; - uint32_t *counts = kzalloc(sizeof(*counts) * nr_blocks, GFP_KERNEL); + uint32_t *counts = vzalloc(sizeof(*counts) * nr_blocks); if (!counts) return -ENOMEM; - memcpy(counts, ca->counts, sizeof(*counts) * ca->nr); - kfree(ca->counts); + if (ca->counts) { + memcpy(counts, ca->counts, sizeof(*counts) * ca->nr); + ca_destroy(ca); + } ca->nr = nr_blocks; ca->nr_free += extra_blocks; ca->counts = counts; @@ -151,11 +164,6 @@ static int ca_commit(struct count_array *old, struct count_array *new) return 0; } -static void ca_destroy(struct count_array *ca) -{ - kfree(ca->counts); -} - /*----------------------------------------------------------------*/ struct sm_checker { @@ -343,25 +351,25 @@ struct dm_space_map *dm_sm_checker_create(struct dm_space_map *sm) int r; struct sm_checker *smc; - if (!sm) - return NULL; + if (IS_ERR_OR_NULL(sm)) + return ERR_PTR(-EINVAL); smc = kmalloc(sizeof(*smc), GFP_KERNEL); if (!smc) - return NULL; + return ERR_PTR(-ENOMEM); memcpy(&smc->sm, &ops_, sizeof(smc->sm)); r = ca_create(&smc->old_counts, sm); if (r) { kfree(smc); - return NULL; + return ERR_PTR(r); } r = ca_create(&smc->counts, sm); if (r) { ca_destroy(&smc->old_counts); kfree(smc); - return NULL; + return ERR_PTR(r); } smc->real_sm = sm; @@ -371,7 +379,7 @@ struct dm_space_map *dm_sm_checker_create(struct dm_space_map *sm) ca_destroy(&smc->counts); ca_destroy(&smc->old_counts); kfree(smc); - return NULL; + return ERR_PTR(r); } r = ca_commit(&smc->old_counts, &smc->counts); @@ -379,7 +387,7 @@ struct dm_space_map *dm_sm_checker_create(struct dm_space_map *sm) ca_destroy(&smc->counts); ca_destroy(&smc->old_counts); kfree(smc); - return NULL; + return ERR_PTR(r); } return &smc->sm; @@ -391,25 +399,25 @@ struct dm_space_map *dm_sm_checker_create_fresh(struct dm_space_map *sm) int r; struct sm_checker *smc; - if (!sm) - return NULL; + if (IS_ERR_OR_NULL(sm)) + return ERR_PTR(-EINVAL); smc = kmalloc(sizeof(*smc), GFP_KERNEL); if (!smc) - return NULL; + return ERR_PTR(-ENOMEM); memcpy(&smc->sm, &ops_, sizeof(smc->sm)); r = ca_create(&smc->old_counts, sm); if (r) { kfree(smc); - return NULL; + return ERR_PTR(r); } r = ca_create(&smc->counts, sm); if (r) { ca_destroy(&smc->old_counts); kfree(smc); - return NULL; + return ERR_PTR(r); } smc->real_sm = sm; diff --git a/drivers/md/persistent-data/dm-space-map-disk.c b/drivers/md/persistent-data/dm-space-map-disk.c index fc469ba9f627..3d0ed5332883 100644 --- a/drivers/md/persistent-data/dm-space-map-disk.c +++ b/drivers/md/persistent-data/dm-space-map-disk.c @@ -290,7 +290,16 @@ struct dm_space_map *dm_sm_disk_create(struct dm_transaction_manager *tm, dm_block_t nr_blocks) { struct dm_space_map *sm = dm_sm_disk_create_real(tm, nr_blocks); - return dm_sm_checker_create_fresh(sm); + struct dm_space_map *smc; + + if (IS_ERR_OR_NULL(sm)) + return sm; + + smc = dm_sm_checker_create_fresh(sm); + if (IS_ERR(smc)) + dm_sm_destroy(sm); + + return smc; } EXPORT_SYMBOL_GPL(dm_sm_disk_create); diff --git a/drivers/md/persistent-data/dm-transaction-manager.c b/drivers/md/persistent-data/dm-transaction-manager.c index 400fe144c0cd..e5604b32d91f 100644 --- a/drivers/md/persistent-data/dm-transaction-manager.c +++ b/drivers/md/persistent-data/dm-transaction-manager.c @@ -138,6 +138,9 @@ EXPORT_SYMBOL_GPL(dm_tm_create_non_blocking_clone); void dm_tm_destroy(struct dm_transaction_manager *tm) { + if (!tm->is_clone) + wipe_shadow_table(tm); + kfree(tm); } EXPORT_SYMBOL_GPL(dm_tm_destroy); @@ -344,8 +347,10 @@ static int dm_tm_create_internal(struct dm_block_manager *bm, } *sm = dm_sm_checker_create(inner); - if (!*sm) + if (IS_ERR(*sm)) { + r = PTR_ERR(*sm); goto bad2; + } } else { r = dm_bm_write_lock(dm_tm_get_bm(*tm), sb_location, @@ -364,8 +369,10 @@ static int dm_tm_create_internal(struct dm_block_manager *bm, } *sm = dm_sm_checker_create(inner); - if (!*sm) + if (IS_ERR(*sm)) { + r = PTR_ERR(*sm); goto bad2; + } } return 0; diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index a9c7981ddd24..240ff3125040 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -517,8 +517,8 @@ static int read_balance(struct r1conf *conf, struct r1bio *r1_bio, int *max_sect int bad_sectors; int disk = start_disk + i; - if (disk >= conf->raid_disks) - disk -= conf->raid_disks; + if (disk >= conf->raid_disks * 2) + disk -= conf->raid_disks * 2; rdev = rcu_dereference(conf->mirrors[disk].rdev); if (r1_bio->bios[disk] == IO_BLOCKED @@ -883,7 +883,6 @@ static void make_request(struct mddev *mddev, struct bio * bio) const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); struct md_rdev *blocked_rdev; - int plugged; int first_clone; int sectors_handled; int max_sectors; @@ -1034,7 +1033,6 @@ read_again: * the bad blocks. Each set of writes gets it's own r1bio * with a set of bios attached. */ - plugged = mddev_check_plugged(mddev); disks = conf->raid_disks * 2; retry_write: @@ -1191,6 +1189,8 @@ read_again: bio_list_add(&conf->pending_bio_list, mbio); conf->pending_count++; spin_unlock_irqrestore(&conf->device_lock, flags); + if (!mddev_check_plugged(mddev)) + md_wakeup_thread(mddev->thread); } /* Mustn't call r1_bio_write_done before this next test, * as it could result in the bio being freed. @@ -1213,9 +1213,6 @@ read_again: /* In case raid1d snuck in to freeze_array */ wake_up(&conf->wait_barrier); - - if (do_sync || !bitmap || !plugged) - md_wakeup_thread(mddev->thread); } static void status(struct seq_file *seq, struct mddev *mddev) @@ -2488,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); } @@ -2621,7 +2619,7 @@ static struct r1conf *setup_conf(struct mddev *mddev) goto abort; } err = -ENOMEM; - conf->thread = md_register_thread(raid1d, mddev, NULL); + conf->thread = md_register_thread(raid1d, mddev, "raid1"); if (!conf->thread) { printk(KERN_ERR "md/raid1:%s: couldn't allocate thread\n", diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 99ae6068e456..8da6282254c3 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1039,7 +1039,6 @@ static void make_request(struct mddev *mddev, struct bio * bio) const unsigned long do_fua = (bio->bi_rw & REQ_FUA); unsigned long flags; struct md_rdev *blocked_rdev; - int plugged; int sectors_handled; int max_sectors; int sectors; @@ -1239,7 +1238,6 @@ read_again: * of r10_bios is recored in bio->bi_phys_segments just as with * the read case. */ - plugged = mddev_check_plugged(mddev); r10_bio->read_slot = -1; /* make sure repl_bio gets freed */ raid10_find_phys(conf, r10_bio); @@ -1396,6 +1394,8 @@ retry_write: bio_list_add(&conf->pending_bio_list, mbio); conf->pending_count++; spin_unlock_irqrestore(&conf->device_lock, flags); + if (!mddev_check_plugged(mddev)) + md_wakeup_thread(mddev->thread); if (!r10_bio->devs[i].repl_bio) continue; @@ -1423,6 +1423,8 @@ retry_write: bio_list_add(&conf->pending_bio_list, mbio); conf->pending_count++; spin_unlock_irqrestore(&conf->device_lock, flags); + if (!mddev_check_plugged(mddev)) + md_wakeup_thread(mddev->thread); } /* Don't remove the bias on 'remaining' (one_write_done) until @@ -1448,9 +1450,6 @@ retry_write: /* In case raid10d snuck in to freeze_array */ wake_up(&conf->wait_barrier); - - if (do_sync || !mddev->bitmap || !plugged) - md_wakeup_thread(mddev->thread); } static void status(struct seq_file *seq, struct mddev *mddev) @@ -2310,7 +2309,7 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10 if (r10_sync_page_io(rdev, r10_bio->devs[sl].addr + sect, - s<<9, conf->tmppage, WRITE) + s, conf->tmppage, WRITE) == 0) { /* Well, this device is dead */ printk(KERN_NOTICE @@ -2349,7 +2348,7 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10 switch (r10_sync_page_io(rdev, r10_bio->devs[sl].addr + sect, - s<<9, conf->tmppage, + s, conf->tmppage, READ)) { case 0: /* Well, this device is dead */ @@ -2512,7 +2511,7 @@ read_more: slot = r10_bio->read_slot; printk_ratelimited( KERN_ERR - "md/raid10:%s: %s: redirecting" + "md/raid10:%s: %s: redirecting " "sector %llu to another mirror\n", mdname(mddev), bdevname(rdev->bdev, b), @@ -2661,7 +2660,8 @@ static void raid10d(struct mddev *mddev) blk_start_plug(&plug); for (;;) { - flush_pending_writes(conf); + if (atomic_read(&mddev->plug_cnt) == 0) + flush_pending_writes(conf); spin_lock_irqsave(&conf->device_lock, flags); if (list_empty(head)) { @@ -2890,6 +2890,12 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr, /* want to reconstruct this device */ rb2 = r10_bio; sect = raid10_find_virt(conf, sector_nr, i); + if (sect >= mddev->resync_max_sectors) { + /* last stripe is not complete - don't + * try to recover this sector. + */ + continue; + } /* Unless we are doing a full sync, or a replacement * we only need to recover the block if it is set in * the bitmap @@ -3421,7 +3427,7 @@ static struct r10conf *setup_conf(struct mddev *mddev) spin_lock_init(&conf->resync_lock); init_waitqueue_head(&conf->wait_barrier); - conf->thread = md_register_thread(raid10d, mddev, NULL); + conf->thread = md_register_thread(raid10d, mddev, "raid10"); if (!conf->thread) goto out; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index d26767246d26..04348d76bb30 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -196,12 +196,14 @@ static void __release_stripe(struct r5conf *conf, struct stripe_head *sh) BUG_ON(!list_empty(&sh->lru)); BUG_ON(atomic_read(&conf->active_stripes)==0); if (test_bit(STRIPE_HANDLE, &sh->state)) { - if (test_bit(STRIPE_DELAYED, &sh->state)) + if (test_bit(STRIPE_DELAYED, &sh->state) && + !test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) list_add_tail(&sh->lru, &conf->delayed_list); else if (test_bit(STRIPE_BIT_DELAY, &sh->state) && sh->bm_seq - conf->seq_write > 0) list_add_tail(&sh->lru, &conf->bitmap_list); else { + clear_bit(STRIPE_DELAYED, &sh->state); clear_bit(STRIPE_BIT_DELAY, &sh->state); list_add_tail(&sh->lru, &conf->handle_list); } @@ -606,6 +608,12 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) * a chance*/ md_check_recovery(conf->mddev); } + /* + * Because md_wait_for_blocked_rdev + * will dec nr_pending, we must + * increment it first. + */ + atomic_inc(&rdev->nr_pending); md_wait_for_blocked_rdev(rdev, conf->mddev); } else { /* Acknowledged bad block - skip the write */ @@ -1737,6 +1745,7 @@ static void raid5_end_read_request(struct bio * bi, int error) } else { const char *bdn = bdevname(rdev->bdev, b); int retry = 0; + int set_bad = 0; clear_bit(R5_UPTODATE, &sh->dev[i].flags); atomic_inc(&rdev->read_errors); @@ -1748,7 +1757,8 @@ static void raid5_end_read_request(struct bio * bi, int error) mdname(conf->mddev), (unsigned long long)s, bdn); - else if (conf->mddev->degraded >= conf->max_degraded) + else if (conf->mddev->degraded >= conf->max_degraded) { + set_bad = 1; printk_ratelimited( KERN_WARNING "md/raid:%s: read error not correctable " @@ -1756,8 +1766,9 @@ static void raid5_end_read_request(struct bio * bi, int error) mdname(conf->mddev), (unsigned long long)s, bdn); - else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) + } else if (test_bit(R5_ReWrite, &sh->dev[i].flags)) { /* Oh, no!!! */ + set_bad = 1; printk_ratelimited( KERN_WARNING "md/raid:%s: read error NOT corrected!! " @@ -1765,7 +1776,7 @@ static void raid5_end_read_request(struct bio * bi, int error) mdname(conf->mddev), (unsigned long long)s, bdn); - else if (atomic_read(&rdev->read_errors) + } else if (atomic_read(&rdev->read_errors) > conf->max_nr_stripes) printk(KERN_WARNING "md/raid:%s: Too many read errors, failing device %s.\n", @@ -1777,7 +1788,11 @@ static void raid5_end_read_request(struct bio * bi, int error) else { clear_bit(R5_ReadError, &sh->dev[i].flags); clear_bit(R5_ReWrite, &sh->dev[i].flags); - md_error(conf->mddev, rdev); + if (!(set_bad + && test_bit(In_sync, &rdev->flags) + && rdev_set_badblocks( + rdev, sh->sector, STRIPE_SECTORS, 0))) + md_error(conf->mddev, rdev); } } rdev_dec_pending(rdev, conf->mddev); @@ -3582,8 +3597,18 @@ static void handle_stripe(struct stripe_head *sh) finish: /* wait for this device to become unblocked */ - if (conf->mddev->external && unlikely(s.blocked_rdev)) - md_wait_for_blocked_rdev(s.blocked_rdev, conf->mddev); + if (unlikely(s.blocked_rdev)) { + if (conf->mddev->external) + md_wait_for_blocked_rdev(s.blocked_rdev, + conf->mddev); + else + /* Internal metadata will immediately + * be written by raid5d, so we don't + * need to wait here. + */ + rdev_dec_pending(s.blocked_rdev, + conf->mddev); + } if (s.handle_bad_blocks) for (i = disks; i--; ) { @@ -3881,8 +3906,6 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio) raid_bio->bi_next = (void*)rdev; align_bi->bi_bdev = rdev->bdev; align_bi->bi_flags &= ~(1 << BIO_SEG_VALID); - /* No reshape active, so we can trust rdev->data_offset */ - align_bi->bi_sector += rdev->data_offset; if (!bio_fits_rdev(align_bi) || is_badblock(rdev, align_bi->bi_sector, align_bi->bi_size>>9, @@ -3893,6 +3916,9 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio) return 0; } + /* No reshape active, so we can trust rdev->data_offset */ + align_bi->bi_sector += rdev->data_offset; + spin_lock_irq(&conf->device_lock); wait_event_lock_irq(conf->wait_for_stripe, conf->quiesce == 0, @@ -3971,7 +3997,6 @@ static void make_request(struct mddev *mddev, struct bio * bi) struct stripe_head *sh; const int rw = bio_data_dir(bi); int remaining; - int plugged; if (unlikely(bi->bi_rw & REQ_FLUSH)) { md_flush_request(mddev, bi); @@ -3990,7 +4015,6 @@ static void make_request(struct mddev *mddev, struct bio * bi) bi->bi_next = NULL; bi->bi_phys_segments = 1; /* over-loaded to count active stripes */ - plugged = mddev_check_plugged(mddev); for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { DEFINE_WAIT(w); int previous; @@ -4092,6 +4116,7 @@ static void make_request(struct mddev *mddev, struct bio * bi) if ((bi->bi_rw & REQ_SYNC) && !test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) atomic_inc(&conf->preread_active_stripes); + mddev_check_plugged(mddev); release_stripe(sh); } else { /* cannot get stripe for read-ahead, just give-up */ @@ -4099,10 +4124,7 @@ static void make_request(struct mddev *mddev, struct bio * bi) finish_wait(&conf->wait_for_overlap, &w); break; } - } - if (!plugged) - md_wakeup_thread(mddev->thread); spin_lock_irq(&conf->device_lock); remaining = raid5_dec_bi_phys_segments(bi); @@ -4823,6 +4845,7 @@ static struct r5conf *setup_conf(struct mddev *mddev) int raid_disk, memory, max_disks; struct md_rdev *rdev; struct disk_info *disk; + char pers_name[6]; if (mddev->new_level != 5 && mddev->new_level != 4 @@ -4946,7 +4969,8 @@ static struct r5conf *setup_conf(struct mddev *mddev) printk(KERN_INFO "md/raid:%s: allocated %dkB\n", mdname(mddev), memory); - conf->thread = md_register_thread(raid5d, mddev, NULL); + sprintf(pers_name, "raid%d", mddev->new_level); + conf->thread = md_register_thread(raid5d, mddev, pers_name); if (!conf->thread) { printk(KERN_ERR "md/raid:%s: couldn't allocate thread.\n", @@ -5465,10 +5489,9 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev) if (rdev->saved_raid_disk >= 0 && rdev->saved_raid_disk >= first && conf->disks[rdev->saved_raid_disk].rdev == NULL) - disk = rdev->saved_raid_disk; - else - disk = first; - for ( ; disk <= last ; disk++) { + first = rdev->saved_raid_disk; + + for (disk = first; disk <= last; disk++) { p = conf->disks + disk; if (p->rdev == NULL) { clear_bit(In_sync, &rdev->flags); @@ -5477,8 +5500,11 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev) if (rdev->saved_raid_disk != disk) conf->fullsync = 1; rcu_assign_pointer(p->rdev, rdev); - break; + goto out; } + } + for (disk = first; disk <= last; disk++) { + p = conf->disks + disk; if (test_bit(WantReplacement, &p->rdev->flags) && p->replacement == NULL) { clear_bit(In_sync, &rdev->flags); @@ -5490,6 +5516,7 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev) break; } } +out: print_raid5_conf(conf); return err; } diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c index 7d42c11c8684..0cdbd742974a 100644 --- a/drivers/media/common/saa7146_fops.c +++ b/drivers/media/common/saa7146_fops.c @@ -198,7 +198,6 @@ static int fops_open(struct file *file) struct saa7146_dev *dev = video_drvdata(file); struct saa7146_fh *fh = NULL; int result = 0; - enum v4l2_buf_type type; DEB_EE("file:%p, dev:%s\n", file, video_device_node_name(vdev)); @@ -207,10 +206,6 @@ static int fops_open(struct file *file) DEB_D("using: %p\n", dev); - type = vdev->vfl_type == VFL_TYPE_GRABBER - ? V4L2_BUF_TYPE_VIDEO_CAPTURE - : V4L2_BUF_TYPE_VBI_CAPTURE; - /* check if an extension is registered */ if( NULL == dev->ext ) { DEB_S("no extension registered for this device\n"); diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index 00a67326c193..39eab73b01ae 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/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index 98ecaf0900d6..3180f5b2a6a6 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c @@ -516,9 +516,9 @@ static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) if(cx24110_readreg(state,0x10)&0x40) { /* the RS error counter has finished one counting window */ cx24110_writereg(state,0x10,0x60); /* select the byer reg */ - cx24110_readreg(state, 0x12) | + (void)(cx24110_readreg(state, 0x12) | (cx24110_readreg(state, 0x13) << 8) | - (cx24110_readreg(state, 0x14) << 16); + (cx24110_readreg(state, 0x14) << 16)); cx24110_writereg(state,0x10,0x70); /* select the bler reg */ state->lastbler=cx24110_readreg(state,0x12)| (cx24110_readreg(state,0x13)<<8)| diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c index 945404991529..ed3b0ba624de 100644 --- a/drivers/media/dvb/frontends/cxd2820r_c.c +++ b/drivers/media/dvb/frontends/cxd2820r_c.c @@ -121,7 +121,7 @@ int cxd2820r_get_frontend_c(struct dvb_frontend *fe) if (ret) goto error; - switch ((buf[0] >> 0) & 0x03) { + switch ((buf[0] >> 0) & 0x07) { case 0: c->modulation = QAM_16; break; diff --git a/drivers/media/dvb/frontends/lg2160.c b/drivers/media/dvb/frontends/lg2160.c index a3ab1a5b6597..cc11260e99df 100644 --- a/drivers/media/dvb/frontends/lg2160.c +++ b/drivers/media/dvb/frontends/lg2160.c @@ -126,7 +126,7 @@ static int lg216x_write_regs(struct lg216x_state *state, lg_reg("writing %d registers...\n", len); - for (i = 0; i < len - 1; i++) { + for (i = 0; i < len; i++) { ret = lg216x_write_reg(state, regs[i].reg, regs[i].val); if (lg_fail(ret)) return ret; diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 63c004a25e0b..664e460f247b 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -544,6 +544,8 @@ static const struct usb_device_id smsusb_id_table[] __devinitconst = { .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0xc0a0), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, + { USB_DEVICE(0x2040, 0xf5a0), + .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { } /* Terminating entry */ }; diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 740a3d5520c7..b415211d0c4b 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -157,7 +157,7 @@ static int __devinit maxiradio_probe(struct pci_dev *pdev, const struct pci_devi goto err_out_free_region; dev->io = pci_resource_start(pdev, 0); - if (snd_tea575x_init(&dev->tea)) { + if (snd_tea575x_init(&dev->tea, THIS_MODULE)) { printk(KERN_ERR "radio-maxiradio: Unable to detect TEA575x tuner\n"); goto err_out_free_region; } diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 52b8011f1b23..4efcbec74c52 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -238,7 +238,7 @@ static int __devinit fmr2_probe(struct fmr2 *fmr2, struct device *pdev, int io) snprintf(fmr2->tea.bus_info, sizeof(fmr2->tea.bus_info), "%s:%s", fmr2->is_fmd2 ? "PnP" : "ISA", dev_name(pdev)); - if (snd_tea575x_init(&fmr2->tea)) { + if (snd_tea575x_init(&fmr2->tea, THIS_MODULE)) { printk(KERN_ERR "radio-sf16fmr2: Unable to detect TEA575x tuner\n"); release_region(fmr2->io, 2); return -ENODEV; diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index e9f638761296..f412f7ab270b 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c @@ -51,6 +51,8 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, /* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */ { USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) }, + /* Axentia ALERT FM USB Receiver */ + { USB_DEVICE_AND_INTERFACE_INFO(0x12cf, 0x7111, USB_CLASS_HID, 0, 0) }, /* Terminating entry */ { } }; diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 342c2c8c1ddf..54ee34872d14 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/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c index ff2933ab705f..856ab962cd63 100644 --- a/drivers/media/video/bt8xx/bttv-cards.c +++ b/drivers/media/video/bt8xx/bttv-cards.c @@ -371,7 +371,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -384,7 +383,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -398,7 +396,6 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 4, 0, 2, 3 }, .gpiomute = 1, .no_msp34xx = 1, - .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -414,7 +411,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0 }, - .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -427,7 +423,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0, 1, 0, 1 }, .gpiomute = 3, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -440,7 +435,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x0f, .gpiomux = { 0x0c, 0x04, 0x08, 0x04 }, /* 0x04 for some cards ?? */ - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= avermedia_tvphone_audio, @@ -454,7 +448,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, - .needs_tvaudio = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -469,7 +462,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0xc00, 0x800, 0x400 }, .gpiomute = 0xc00, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -482,7 +474,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 3, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 1, 2, 3 }, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -496,7 +487,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 0, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -510,7 +500,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20001,0x10001, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -524,7 +513,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 14, 11, 7 }, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -536,7 +524,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 14, 11, 7 }, - .needs_tvaudio = 1, .msp34xx_alt = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -553,7 +540,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */ .gpiomute = 4, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -567,7 +553,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 1, 0 }, .gpiomute = 10, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -583,7 +568,6 @@ struct tvcard bttv_tvcards[] = { /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */ .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, .gpiomute = 0x002000, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -597,7 +581,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1, 0), .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 }, .gpiomute = 0xcfa007, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, .volume_gpio = winview_volume, @@ -611,7 +594,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 0, 0, 0 }, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -660,7 +642,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 0x800, 0x400 }, .gpiomute = 0xc00, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -691,7 +672,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = {0x400, 0x400, 0x400, 0x400 }, .gpiomute = 0xc00, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -706,7 +686,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, .gpiomute = 0x40000, - .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, @@ -720,7 +699,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 0, 1, 1), .gpiomux = { 0, 1, 2, 3 }, .gpiomute = 4, - .needs_tvaudio = 1, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, }, @@ -748,7 +726,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 }, .gpiomute = 0x40000, - .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .audio_mode_gpio= terratv_audio, @@ -793,7 +770,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, - .needs_tvaudio = 1, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .muxsel_hook = PXC200_muxsel, @@ -834,7 +810,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0 }, - .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -847,7 +822,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x500, 0, 0x300, 0x900 }, .gpiomute = 0x900, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -874,7 +848,6 @@ struct tvcard bttv_tvcards[] = { Note: There exists another variant "Winfast 2000" with tv stereo !? Note: eeprom only contains FF and pci subsystem id 107d:6606 */ - .needs_tvaudio = 0, .pll = PLL_28, .has_radio = 1, .tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */ @@ -934,7 +907,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0x551400, 0x551200, 0, 0 }, .gpiomute = 0x551c00, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, @@ -949,7 +921,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0xd0001, 0, 0 }, .gpiomute = 1, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -966,7 +937,6 @@ struct tvcard bttv_tvcards[] = { .gpiomux = { 4, 0, 2, 3 }, .gpiomute = 1, .no_msp34xx = 1, - .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -980,7 +950,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 15, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 13, 4, 11, 7 }, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -995,7 +964,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0, 0}, - .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, @@ -1066,7 +1034,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20000, 0x30000, 0x10000, 0 }, .gpiomute = 0x40000, - .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_35, .tuner_type = TUNER_PHILIPS_PAL_I, @@ -1084,7 +1051,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = {2,0,0,0 }, .gpiomute = 1, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1163,7 +1129,6 @@ struct tvcard bttv_tvcards[] = { MUX2 (mask 0x30000): 0,2,3= from MSP34xx 1= FM stereo Radio from Tuner */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1179,7 +1144,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0x10, 8 }, .gpiomute = 4, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1218,7 +1182,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TEMIC_PAL, .tuner_addr = ADDR_UNSET, @@ -1250,7 +1213,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(3, 1), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_35, .tuner_type = TUNER_ABSENT, @@ -1266,7 +1228,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x400, 0x400, 0x400, 0x400 }, .gpiomute = 0x800, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_TEMIC_4036FY5_NTSC, .tuner_addr = ADDR_UNSET, @@ -1312,7 +1273,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2), .gpiomux = { }, .no_msp34xx = 1, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -1329,7 +1289,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 1, 0, 4, 4 }, .gpiomute = 9, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1379,7 +1338,6 @@ struct tvcard bttv_tvcards[] = { .gpiomute = 0x1800, .audio_mode_gpio= fv2000s_audio, .no_msp34xx = 1, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1393,7 +1351,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x500, 0x500, 0x300, 0x900 }, .gpiomute = 0x900, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -1477,7 +1434,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */ .gpiomute = 13, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_LG_PAL_I_FM, .tuner_addr = ADDR_UNSET, @@ -1514,7 +1470,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x01, 0x00, 0x03, 0x03 }, .gpiomute = 0x09, - .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1540,7 +1495,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0, 0), .gpiomux = { 0 }, - .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -1567,7 +1521,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 4, - .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -1597,7 +1550,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -1619,7 +1571,6 @@ struct tvcard bttv_tvcards[] = { * btwincap uses 0x80000/0x80003 */ .gpiomute = 4, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -1655,7 +1606,6 @@ struct tvcard bttv_tvcards[] = { /* .audio_inputs= 1, */ .svhs = 2, .muxsel = MUXSEL(2, 0, 1, 1), - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1875,7 +1825,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 3}, .gpiomute = 4, - .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -1902,7 +1851,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -1920,7 +1868,6 @@ struct tvcard bttv_tvcards[] = { /* Tuner, Radio, external, internal, off, on */ .gpiomux = { 0x08, 0x0f, 0x0a, 0x08 }, .gpiomute = 0x0f, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, @@ -1936,7 +1883,6 @@ struct tvcard bttv_tvcards[] = { .svhs = 2, .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1, 1), - .needs_tvaudio = 1, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, @@ -2034,7 +1980,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -2049,7 +1994,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1, 0), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2062,7 +2006,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2079,7 +2022,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0), .muxsel_hook = phytec_muxsel, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2094,7 +2036,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1), .muxsel_hook = phytec_muxsel, .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2118,7 +2059,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, .svhs = NO_SVHS, /* card has no svhs */ - .needs_tvaudio = 0, .no_msp34xx = 1, .no_tda7432 = 1, .gpiomask = 0x00, @@ -2168,7 +2108,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 3, .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 1, 1, 1, 1 }, - .needs_tvaudio = 1, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .pll = PLL_35, @@ -2210,7 +2149,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 0), .no_msp34xx = 1, .no_tda7432 = 1, - .needs_tvaudio = 0, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, }, @@ -2222,7 +2160,6 @@ struct tvcard bttv_tvcards[] = { .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, .svhs = 2, - .needs_tvaudio = 0, .gpiomask = 0x68, .muxsel = MUXSEL(2, 3, 1), .gpiomux = { 0x68, 0x68, 0x61, 0x61 }, @@ -2241,7 +2178,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 3, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2265,7 +2201,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 2, 2, 2), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ .pll = PLL_28, - .needs_tvaudio = 0, .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/ .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2358,7 +2293,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL, .tuner_addr = ADDR_UNSET, @@ -2405,7 +2339,6 @@ struct tvcard bttv_tvcards[] = { .tuner_addr = ADDR_UNSET, .gpiomask = 0x008007, .gpiomux = { 0, 0x000001,0,0 }, - .needs_tvaudio = 1, .has_radio = 1, }, [BTTV_BOARD_TIBET_CS16] = { @@ -2518,7 +2451,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 }, .gpiomute = 0x002000, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_YMEC_TVF66T5_B_DFF, .tuner_addr = 0xc1 >>1, @@ -2534,7 +2466,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, .gpiomute = 3, - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_TENA_9533_DI, .tuner_addr = ADDR_UNSET, @@ -2615,7 +2546,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 2, 0, 0, 0 }, .gpiomute = 1, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_NTSC, .tuner_addr = ADDR_UNSET, @@ -2714,7 +2644,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0x20001,0x10001, 0, 0 }, .gpiomute = 10, - .needs_tvaudio = 1, .pll = PLL_28, .tuner_type = TUNER_PHILIPS_PAL_I, .tuner_addr = ADDR_UNSET, @@ -2746,7 +2675,6 @@ struct tvcard bttv_tvcards[] = { .muxsel = MUXSEL(2, 3, 1, 1), .gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */ .gpiomute = 3, /* CONTVFMi */ - .needs_tvaudio = 0, .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */ .tuner_addr = ADDR_UNSET, .pll = PLL_28, @@ -2785,7 +2713,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(0, 2, 3, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2799,7 +2726,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(2, 3, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2813,7 +2739,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0x00, .muxsel = MUXSEL(3, 2, 1), .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */ - .needs_tvaudio = 0, .pll = PLL_28, .tuner_type = TUNER_ABSENT, .tuner_addr = ADDR_UNSET, @@ -2877,7 +2802,6 @@ struct tvcard bttv_tvcards[] = { .gpiomask = 0, .muxsel = MUXSEL(2, 3), .gpiomux = { 0 }, - .needs_tvaudio = 0, .no_msp34xx = 1, .pll = PLL_28, .tuner_type = TUNER_ABSENT, @@ -3649,7 +3573,7 @@ void __devinit bttv_init_tuner(struct bttv *btv) struct tuner_setup tun_setup; /* Load tuner module before issuing tuner config call! */ - if (bttv_tvcards[btv->c.type].has_radio) + if (btv->has_radio) v4l2_i2c_new_subdev(&btv->c.v4l2_dev, &btv->c.i2c_adap, "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO)); @@ -3664,7 +3588,7 @@ void __devinit bttv_init_tuner(struct bttv *btv) tun_setup.type = btv->tuner_type; tun_setup.addr = addr; - if (bttv_tvcards[btv->c.type].has_radio) + if (btv->has_radio) tun_setup.mode_mask |= T_RADIO; bttv_call_all(btv, tuner, s_type_addr, &tun_setup); @@ -3724,6 +3648,10 @@ static void __devinit hauppauge_eeprom(struct bttv *btv) bttv_tvcards[BTTV_BOARD_HAUPPAUGE_IMPACTVCB].name); btv->c.type = BTTV_BOARD_HAUPPAUGE_IMPACTVCB; } + + /* The 61334 needs the msp3410 to do the radio demod to get sound */ + if (tv.model == 61334) + btv->radio_uses_msp_demodulator = 1; } static int terratec_active_radio_upgrade(struct bttv *btv) diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index a9cfb0f4be48..ff7a589d8e0f 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c @@ -1218,6 +1218,11 @@ audio_mux(struct bttv *btv, int input, int mute) For now this is sufficient. */ switch (input) { case TVAUDIO_INPUT_RADIO: + /* Some boards need the msp do to the radio demod */ + if (btv->radio_uses_msp_demodulator) { + in = MSP_INPUT_DEFAULT; + break; + } in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); break; diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h index c5171619ac79..acfe2f3b92d9 100644 --- a/drivers/media/video/bt8xx/bttv.h +++ b/drivers/media/video/bt8xx/bttv.h @@ -236,7 +236,6 @@ struct tvcard { /* i2c audio flags */ unsigned int no_msp34xx:1; unsigned int no_tda7432:1; - unsigned int needs_tvaudio:1; unsigned int msp34xx_alt:1; /* Note: currently no card definition needs to mark the presence of a RDS saa6588 chip. If this is ever needed, then add a new diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h index db943a8d580d..70fd4f23f605 100644 --- a/drivers/media/video/bt8xx/bttvp.h +++ b/drivers/media/video/bt8xx/bttvp.h @@ -440,6 +440,7 @@ struct bttv { /* radio data/state */ int has_radio; int radio_user; + int radio_uses_msp_demodulator; /* miro/pinnacle + Aimslab VHX philips matchbox (tea5757 radio tuner) support */ diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 2520219f01ba..5b75a64b199b 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c @@ -607,8 +607,9 @@ static long qc_capture(struct qcam *q, char __user *buf, unsigned long len) } o = i * pixels_per_line + pixels_read + k; if (o < len) { + u8 ch = invert - buffer[k]; got++; - put_user((invert - buffer[k]) << shift, buf + o); + put_user(ch << shift, buf + o); } } pixels_read += bytes; @@ -648,8 +649,8 @@ static int qcam_querycap(struct file *file, void *priv, struct qcam *qcam = video_drvdata(file); strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); - strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card)); - strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); + strlcpy(vcap->card, "Connectix B&W Quickcam", sizeof(vcap->card)); + strlcpy(vcap->bus_info, qcam->pport->name, sizeof(vcap->bus_info)); vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; @@ -688,8 +689,8 @@ static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f pix->height = qcam->height / qcam->transfer_scale; pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6; pix->field = V4L2_FIELD_NONE; - pix->bytesperline = qcam->width; - pix->sizeimage = qcam->width * qcam->height; + pix->bytesperline = pix->width; + pix->sizeimage = pix->width * pix->height; /* Just a guess */ pix->colorspace = V4L2_COLORSPACE_SRGB; return 0; @@ -757,7 +758,7 @@ static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdes "4-Bit Monochrome", V4L2_PIX_FMT_Y4, { 0, 0, 0, 0 } }, - { 0, 0, 0, + { 1, 0, 0, "6-Bit Monochrome", V4L2_PIX_FMT_Y6, { 0, 0, 0, 0 } }, @@ -772,6 +773,25 @@ static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdes return 0; } +static int qcam_enum_framesizes(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize) +{ + static const struct v4l2_frmsize_discrete sizes[] = { + { 80, 60 }, + { 160, 120 }, + { 320, 240 }, + }; + + if (fsize->index > 2) + return -EINVAL; + if (fsize->pixel_format != V4L2_PIX_FMT_Y4 && + fsize->pixel_format != V4L2_PIX_FMT_Y6) + return -EINVAL; + fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; + fsize->discrete = sizes[fsize->index]; + return 0; +} + static ssize_t qcam_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { @@ -795,6 +815,11 @@ static ssize_t qcam_read(struct file *file, char __user *buf, return len; } +static unsigned int qcam_poll(struct file *filp, poll_table *wait) +{ + return v4l2_ctrl_poll(filp, wait) | POLLIN | POLLRDNORM; +} + static int qcam_s_ctrl(struct v4l2_ctrl *ctrl) { struct qcam *qcam = @@ -828,7 +853,7 @@ static const struct v4l2_file_operations qcam_fops = { .owner = THIS_MODULE, .open = v4l2_fh_open, .release = v4l2_fh_release, - .poll = v4l2_ctrl_poll, + .poll = qcam_poll, .unlocked_ioctl = video_ioctl2, .read = qcam_read, }; @@ -839,6 +864,7 @@ static const struct v4l2_ioctl_ops qcam_ioctl_ops = { .vidioc_s_input = qcam_s_input, .vidioc_enum_input = qcam_enum_input, .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap, + .vidioc_enum_framesizes = qcam_enum_framesizes, .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, @@ -864,9 +890,9 @@ static struct qcam *qcam_init(struct parport *port) return NULL; v4l2_dev = &qcam->v4l2_dev; - strlcpy(v4l2_dev->name, "bw-qcam", sizeof(v4l2_dev->name)); + snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%d", num_cams); - if (v4l2_device_register(NULL, v4l2_dev) < 0) { + if (v4l2_device_register(port->dev, v4l2_dev) < 0) { v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); kfree(qcam); return NULL; @@ -886,7 +912,7 @@ static struct qcam *qcam_init(struct parport *port) return NULL; } qcam->pport = port; - qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, + qcam->pdev = parport_register_device(port, v4l2_dev->name, NULL, NULL, NULL, 0, NULL); if (qcam->pdev == NULL) { v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); @@ -975,6 +1001,7 @@ static int init_bwqcam(struct parport *port) return -ENODEV; } qc_calibrate(qcam); + v4l2_ctrl_handler_setup(&qcam->hdl); parport_release(qcam->pdev); diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index b55d57cc1a1c..7e5ffd6f5178 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -838,10 +838,10 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev, } CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, " - "irq: %d, latency: %d, memory: 0x%lx\n", + "irq: %d, latency: %d, memory: 0x%llx\n", cx->pci_dev->device, cx->card_rev, pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn), - cx->pci_dev->irq, pci_latency, (unsigned long)cx->base_addr); + cx->pci_dev->irq, pci_latency, (u64)cx->base_addr); return 0; } @@ -938,7 +938,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, if (retval) goto err; - CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); + CX18_DEBUG_INFO("base addr: 0x%llx\n", (u64)cx->base_addr); /* PCI Device Setup */ retval = cx18_setup_pci(cx, pci_dev, pci_id); @@ -946,8 +946,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, goto free_workqueues; /* map io memory */ - CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); + CX18_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", + (u64)cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); if (!cx->enc_mem) { diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 7a37e0ee136f..2767c64df0c8 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h @@ -622,7 +622,7 @@ struct cx18 { unique ID. Starts at 1, so 0 can be used as uninitialized value in the stream->id. */ - u32 base_addr; + resource_size_t base_addr; u8 card_rev; void __iomem *enc_mem, *reg_mem; diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c index 1b3fb502e6be..b85c292a849a 100644 --- a/drivers/media/video/cx18/cx18-firmware.c +++ b/drivers/media/video/cx18/cx18-firmware.c @@ -164,8 +164,13 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32]; while (offset + sizeof(seghdr) < fw->size) { - /* TODO: byteswapping */ - memcpy(&seghdr, src + offset / 4, sizeof(seghdr)); + const u32 *shptr = src + offset / 4; + + seghdr.sync1 = le32_to_cpu(shptr[0]); + seghdr.sync2 = le32_to_cpu(shptr[1]); + seghdr.addr = le32_to_cpu(shptr[2]); + seghdr.size = le32_to_cpu(shptr[3]); + offset += sizeof(seghdr); if (seghdr.sync1 != APU_ROM_SYNC1 || seghdr.sync2 != APU_ROM_SYNC2) { diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c index ed8118390b02..eabf00c6351b 100644 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ b/drivers/media/video/cx18/cx18-mailbox.c @@ -434,6 +434,7 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order) { u32 handle, mdl_ack_offset, mdl_ack_count; struct cx18_mailbox *mb; + int i; mb = &order->mb; handle = mb->args[0]; @@ -447,8 +448,9 @@ static int epu_dma_done_irq(struct cx18 *cx, struct cx18_in_work_order *order) return -1; } - cx18_memcpy_fromio(cx, order->mdl_ack, cx->enc_mem + mdl_ack_offset, - sizeof(struct cx18_mdl_ack) * mdl_ack_count); + for (i = 0; i < sizeof(struct cx18_mdl_ack) * mdl_ack_count; i += sizeof(u32)) + ((u32 *)order->mdl_ack)[i / sizeof(u32)] = + cx18_readl(cx, cx->enc_mem + mdl_ack_offset + i); if ((order->flags & CX18_F_EWO_MB_STALE) == 0) mb_ack_irq(cx, order); @@ -538,6 +540,7 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) struct cx18_mailbox *order_mb; struct cx18_in_work_order *order; int submit; + int i; switch (rpu) { case CPU: @@ -562,10 +565,12 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) order_mb = &order->mb; /* mb->cmd and mb->args[0] through mb->args[2] */ - cx18_memcpy_fromio(cx, &order_mb->cmd, &mb->cmd, 4 * sizeof(u32)); + for (i = 0; i < 4; i++) + (&order_mb->cmd)[i] = cx18_readl(cx, &mb->cmd + i); + /* mb->request and mb->ack. N.B. we want to read mb->ack last */ - cx18_memcpy_fromio(cx, &order_mb->request, &mb->request, - 2 * sizeof(u32)); + for (i = 0; i < 2; i++) + (&order_mb->request)[i] = cx18_readl(cx, &mb->request + i); if (order_mb->request == order_mb->ack) { CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our " diff --git a/drivers/media/video/cx231xx/cx231xx-audio.c b/drivers/media/video/cx231xx/cx231xx-audio.c index 068f78dc5d13..b4c99c7270cf 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 3d15314e1f88..ac7db52f404f 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 13739e002a63..080e11157e5f 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 a80a92c47455..cd542684ba02 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 c654bdc7ccb2..22f8e7fbd665 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 d884784a1c85..13c37ec07ae7 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 fc1ff69cffd0..d8eac3e30a7e 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/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index e46446a449c0..ed7b2aa1ed83 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c @@ -471,7 +471,7 @@ static int blackbird_load_firmware(struct cx8802_dev *dev) dprintk(1,"Loading firmware ...\n"); dataptr = (u32*)firmware->data; for (i = 0; i < (firmware->size >> 2); i++) { - value = *dataptr; + value = le32_to_cpu(*dataptr); checksum += ~value; memory_write(dev->core, i, value); dataptr++; diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index 20a7e24de6fb..862c6575c557 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -974,6 +974,7 @@ struct em28xx_board em28xx_boards[] = { [EM2884_BOARD_CINERGY_HTC_STICK] = { .name = "Terratec Cinergy HTC Stick", .has_dvb = 1, + .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, #if 0 .tuner_type = TUNER_PHILIPS_TDA8290, .tuner_addr = 0x41, @@ -2892,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/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index fce5f7680c99..5e30c4f3f248 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c @@ -527,6 +527,8 @@ static int em28xx_ir_init(struct em28xx *dev) if (dev->board.ir_codes == NULL) { /* No remote control support */ + em28xx_warn("Remote control support is not available for " + "this card.\n"); return 0; } diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 137166d73945..31721eadc597 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c @@ -1653,7 +1653,7 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type buf_type) { struct gspca_dev *gspca_dev = video_drvdata(file); - int ret; + int i, ret; if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1678,6 +1678,8 @@ static int vidioc_streamoff(struct file *file, void *priv, wake_up_interruptible(&gspca_dev->wq); /* empty the transfer queues */ + for (i = 0; i < gspca_dev->nframes; i++) + gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS; atomic_set(&gspca_dev->fr_q, 0); atomic_set(&gspca_dev->fr_i, 0); gspca_dev->fr_o = 0; diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index b5acb1e4b4e7..80c81dd6d68b 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -96,7 +96,7 @@ static void setbrightness(struct gspca_dev *gspca_dev); static void setcontrast(struct gspca_dev *gspca_dev); static void setgain(struct gspca_dev *gspca_dev); static void setexposure(struct gspca_dev *gspca_dev); -static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val); +static void setagc(struct gspca_dev *gspca_dev); static void setawb(struct gspca_dev *gspca_dev); static void setaec(struct gspca_dev *gspca_dev); static void setsharpness(struct gspca_dev *gspca_dev); @@ -189,7 +189,7 @@ static const struct ctrl sd_ctrls[] = { .step = 1, .default_value = 1, }, - .set = sd_setagc + .set_control = setagc }, [AWB] = { { @@ -851,6 +851,7 @@ static int sccb_check_status(struct gspca_dev *gspca_dev) int i; for (i = 0; i < 5; i++) { + msleep(10); data = ov534_reg_read(gspca_dev, OV534_REG_STATUS); switch (data) { @@ -1242,10 +1243,6 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->ctrls = sd->ctrls; - /* the auto white balance control works only when auto gain is set */ - if (sd_ctrls[AGC].qctrl.default_value == 0) - gspca_dev->ctrl_inac |= (1 << AWB); - cam->cam_mode = ov772x_mode; cam->nmodes = ARRAY_SIZE(ov772x_mode); @@ -1486,29 +1483,6 @@ scan_next: } while (remaining_len > 0); } -static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val) -{ - struct sd *sd = (struct sd *) gspca_dev; - - sd->ctrls[AGC].val = val; - - /* the auto white balance control works only - * when auto gain is set */ - if (val) { - gspca_dev->ctrl_inac &= ~(1 << AWB); - } else { - gspca_dev->ctrl_inac |= (1 << AWB); - if (sd->ctrls[AWB].val) { - sd->ctrls[AWB].val = 0; - if (gspca_dev->streaming) - setawb(gspca_dev); - } - } - if (gspca_dev->streaming) - setagc(gspca_dev); - return gspca_dev->usb_err; -} - static int sd_querymenu(struct gspca_dev *gspca_dev, struct v4l2_querymenu *menu) { diff --git a/drivers/media/video/gspca/ov534_9.c b/drivers/media/video/gspca/ov534_9.c index b5797308a39b..1fd41f0d2e95 100644 --- a/drivers/media/video/gspca/ov534_9.c +++ b/drivers/media/video/gspca/ov534_9.c @@ -1008,6 +1008,7 @@ static int sccb_check_status(struct gspca_dev *gspca_dev) int i; for (i = 0; i < 5; i++) { + msleep(10); data = reg_r(gspca_dev, OV534_REG_STATUS); switch (data) { diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c index 2cb7d95f7be7..115da169f32a 100644 --- a/drivers/media/video/gspca/pac7311.c +++ b/drivers/media/video/gspca/pac7311.c @@ -418,7 +418,7 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler; gspca_dev->vdev.ctrl_handler = hdl; - v4l2_ctrl_handler_init(hdl, 4); + v4l2_ctrl_handler_init(hdl, 5); sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_CONTRAST, 0, 15, 1, 7); diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c index ad098202d7f0..b9c6f17eabb2 100644 --- a/drivers/media/video/gspca/sn9c20x.c +++ b/drivers/media/video/gspca/sn9c20x.c @@ -1761,7 +1761,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_SATURATION, 0, 255, 1, 127); sd->hue = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_HUE, -180, 180, 1, 0); - v4l2_ctrl_cluster(4, &sd->brightness); sd->gamma = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_GAMMA, 0, 255, 1, 0x10); @@ -1770,7 +1769,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_BLUE_BALANCE, 0, 127, 1, 0x28); sd->red = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_RED_BALANCE, 0, 127, 1, 0x28); - v4l2_ctrl_cluster(2, &sd->blue); if (sd->sensor != SENSOR_OV9655 && sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_OV7670 && sd->sensor != SENSOR_MT9M001 && @@ -1779,7 +1777,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_HFLIP, 0, 1, 1, 0); sd->vflip = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0); - v4l2_ctrl_cluster(2, &sd->hflip); } if (sd->sensor != SENSOR_SOI968 && sd->sensor != SENSOR_MT9VPRB && @@ -1794,6 +1791,20 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) V4L2_CID_GAIN, 0, 28, 1, 0); sd->autogain = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 1); + } + + sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, + V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80); + if (hdl->error) { + pr_err("Could not initialize controls\n"); + return hdl->error; + } + + v4l2_ctrl_cluster(4, &sd->brightness); + v4l2_ctrl_cluster(2, &sd->blue); + if (sd->hflip) + v4l2_ctrl_cluster(2, &sd->hflip); + if (sd->autogain) { if (sd->sensor == SENSOR_SOI968) /* this sensor doesn't have the exposure control and autogain is clustered with gain instead. This works @@ -1803,13 +1814,6 @@ static int sd_init_controls(struct gspca_dev *gspca_dev) /* Otherwise autogain is clustered with exposure. */ v4l2_ctrl_auto_cluster(2, &sd->autogain, 0, false); } - - sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops, - V4L2_CID_JPEG_COMPRESSION_QUALITY, 50, 90, 1, 80); - if (hdl->error) { - pr_err("Could not initialize controls\n"); - return hdl->error; - } return 0; } @@ -2066,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); @@ -2172,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/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 4d1696d1a7f4..f38faa9b37c3 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c @@ -3120,7 +3120,7 @@ static const struct sd_desc sd_desc = { | (SENSOR_ ## sensor << 8) \ | (flags) static const struct usb_device_id device_table[] = { - {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)}, + {USB_DEVICE(0x0458, 0x7025), BSF(SN9C120, MI0360B, F_PDN_INV)}, {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)}, {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)}, {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)}, diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c index 057929e165ab..5462ce2f60ea 100644 --- a/drivers/media/video/ivtv/ivtv-driver.c +++ b/drivers/media/video/ivtv/ivtv-driver.c @@ -866,10 +866,10 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev, pci_write_config_dword(pdev, 0x40, 0xffff); IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, " - "irq: %d, latency: %d, memory: 0x%lx\n", + "irq: %d, latency: %d, memory: 0x%llx\n", pdev->device, pdev->revision, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), - pdev->irq, pci_latency, (unsigned long)itv->base_addr); + pdev->irq, pci_latency, (u64)itv->base_addr); return 0; } @@ -1007,7 +1007,7 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, itv->cxhdl.priv = itv; itv->cxhdl.func = ivtv_api_func; - IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); + IVTV_DEBUG_INFO("base addr: 0x%llx\n", (u64)itv->base_addr); /* PCI Device Setup */ retval = ivtv_setup_pci(itv, pdev, pci_id); @@ -1017,8 +1017,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, goto free_mem; /* map io memory */ - IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); + IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", + (u64)itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); itv->enc_mem = ioremap_nocache(itv->base_addr + IVTV_ENCODER_OFFSET, IVTV_ENCODER_SIZE); if (!itv->enc_mem) { @@ -1034,8 +1034,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, } if (itv->has_cx23415) { - IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); + IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", + (u64)itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); itv->dec_mem = ioremap_nocache(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE); if (!itv->dec_mem) { @@ -1056,8 +1056,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, } /* map registers memory */ - IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); + IVTV_DEBUG_INFO("attempting ioremap at 0x%llx len 0x%08x\n", + (u64)itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); itv->reg_mem = ioremap_nocache(itv->base_addr + IVTV_REG_OFFSET, IVTV_REG_SIZE); if (!itv->reg_mem) { diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 2e220028aad2..a7e00f8938f8 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -622,7 +622,7 @@ struct ivtv { struct v4l2_subdev *sd_video; /* controlling video decoder subdev */ struct v4l2_subdev *sd_audio; /* controlling audio subdev */ struct v4l2_subdev *sd_muxer; /* controlling audio muxer subdev */ - u32 base_addr; /* PCI resource base address */ + resource_size_t base_addr; /* PCI resource base address */ volatile void __iomem *enc_mem; /* pointer to mapped encoder memory */ volatile void __iomem *dec_mem; /* pointer to mapped decoder memory */ volatile void __iomem *reg_mem; /* pointer to mapped registers */ diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index d2dec585e61b..3945556f5733 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c @@ -110,22 +110,6 @@ enum { V4L2_M2M_DST = 1, }; -/* Source and destination queue data */ -static struct m2mtest_q_data q_data[2]; - -static struct m2mtest_q_data *get_q_data(enum v4l2_buf_type type) -{ - switch (type) { - case V4L2_BUF_TYPE_VIDEO_OUTPUT: - return &q_data[V4L2_M2M_SRC]; - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return &q_data[V4L2_M2M_DST]; - default: - BUG(); - } - return NULL; -} - #define V4L2_CID_TRANS_TIME_MSEC V4L2_CID_PRIVATE_BASE #define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_PRIVATE_BASE + 1) @@ -198,8 +182,26 @@ struct m2mtest_ctx { int aborting; struct v4l2_m2m_ctx *m2m_ctx; + + /* Source and destination queue data */ + struct m2mtest_q_data q_data[2]; }; +static struct m2mtest_q_data *get_q_data(struct m2mtest_ctx *ctx, + enum v4l2_buf_type type) +{ + switch (type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT: + return &ctx->q_data[V4L2_M2M_SRC]; + case V4L2_BUF_TYPE_VIDEO_CAPTURE: + return &ctx->q_data[V4L2_M2M_DST]; + default: + BUG(); + } + return NULL; +} + + static struct v4l2_queryctrl *get_ctrl(int id) { int i; @@ -223,7 +225,7 @@ static int device_process(struct m2mtest_ctx *ctx, int tile_w, bytes_left; int width, height, bytesperline; - q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT); + q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); width = q_data->width; height = q_data->height; @@ -436,7 +438,7 @@ static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) if (!vq) return -EINVAL; - q_data = get_q_data(f->type); + q_data = get_q_data(ctx, f->type); f->fmt.pix.width = q_data->width; f->fmt.pix.height = q_data->height; @@ -535,7 +537,7 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) if (!vq) return -EINVAL; - q_data = get_q_data(f->type); + q_data = get_q_data(ctx, f->type); if (!q_data) return -EINVAL; @@ -747,7 +749,7 @@ static int m2mtest_queue_setup(struct vb2_queue *vq, struct m2mtest_q_data *q_data; unsigned int size, count = *nbuffers; - q_data = get_q_data(vq->type); + q_data = get_q_data(ctx, vq->type); size = q_data->width * q_data->height * q_data->fmt->depth >> 3; @@ -775,7 +777,7 @@ static int m2mtest_buf_prepare(struct vb2_buffer *vb) dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type); - q_data = get_q_data(vb->vb2_queue->type); + q_data = get_q_data(ctx, vb->vb2_queue->type); if (vb2_plane_size(vb, 0) < q_data->sizeimage) { dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n", @@ -860,6 +862,9 @@ static int m2mtest_open(struct file *file) ctx->transtime = MEM2MEM_DEF_TRANSTIME; ctx->num_processed = 0; + ctx->q_data[V4L2_M2M_SRC].fmt = &formats[0]; + ctx->q_data[V4L2_M2M_DST].fmt = &formats[0]; + ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init); if (IS_ERR(ctx->m2m_ctx)) { @@ -986,9 +991,6 @@ static int m2mtest_probe(struct platform_device *pdev) goto err_m2m; } - q_data[V4L2_M2M_SRC].fmt = &formats[0]; - q_data[V4L2_M2M_DST].fmt = &formats[0]; - return 0; v4l2_m2m_release(dev->m2m_dev); diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index ded26b7286fa..637bde8aca28 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,7 @@ 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, } }, { @@ -356,6 +360,7 @@ 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_SWAP16_EN, } }, }; @@ -984,7 +989,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct mx2_camera_dev *pcdev = ici->priv; struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; - const struct soc_camera_format_xlate *xlate; unsigned long common_flags; int ret; int bytesperline; @@ -1029,24 +1033,7 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd) return ret; } - xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); - if (!xlate) { - dev_warn(icd->parent, "Format %x not found\n", pixfmt); - return -EINVAL; - } - - if (xlate->code == V4L2_MBUS_FMT_YUYV8_2X8) { - csicr1 |= CSICR1_PACK_DIR; - csicr1 &= ~CSICR1_SWAP16_EN; - dev_dbg(icd->parent, "already yuyv format, don't convert\n"); - } else if (xlate->code == V4L2_MBUS_FMT_UYVY8_2X8) { - csicr1 &= ~CSICR1_PACK_DIR; - csicr1 |= CSICR1_SWAP16_EN; - dev_dbg(icd->parent, "convert uyvy mbus format into yuyv\n"); - } else { - dev_warn(icd->parent, "mbus format not supported\n"); - return -EINVAL; - } + csicr1 = (csicr1 & ~CSICR1_FMT_MASK) | pcdev->emma_prp->cfg.csicr1; if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) csicr1 |= CSICR1_REDGE; @@ -1155,18 +1142,6 @@ static int mx2_camera_get_formats(struct soc_camera_device *icd, } } - if (code == V4L2_MBUS_FMT_UYVY8_2X8) { - formats++; - if (xlate) { - xlate->host_fmt = - soc_mbus_get_fmtdesc(V4L2_MBUS_FMT_YUYV8_2X8); - xlate->code = code; - dev_dbg(dev, "Providing host format %s for sensor code %d\n", - xlate->host_fmt->name, code); - xlate++; - } - } - /* Generic pass-trough */ formats++; if (xlate) { diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c index 8a4935ecc655..dd91da26f1b0 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 af2d9086d7e8..b4c679b3fb0f 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c @@ -26,9 +26,11 @@ #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> +#include <linux/slab.h> #include <linux/uaccess.h> #include <linux/isa.h> #include <asm/io.h> diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 354574591908..725812aa0c30 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 fedcd561ba27..a4646ca1d56f 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 }, @@ -615,7 +615,7 @@ int fimc_ctrls_create(struct fimc_ctx *ctx) ctx->effect.type = FIMC_REG_CIIMGEFF_FIN_BYPASS; if (!handler->error) { - v4l2_ctrl_cluster(3, &ctrls->colorfx); + v4l2_ctrl_cluster(2, &ctrls->colorfx); ctrls->ready = true; } @@ -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 400d701aef04..74ff310db30c 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 6753c45631b8..52cef4865423 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 3b8a3492a176..1f5dbaff5442 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/regs-mfc.h b/drivers/media/video/s5p-mfc/regs-mfc.h index 053a8a872fd7..a19bece41ba9 100644 --- a/drivers/media/video/s5p-mfc/regs-mfc.h +++ b/drivers/media/video/s5p-mfc/regs-mfc.h @@ -164,10 +164,15 @@ decoded pic */ #define S5P_FIMV_SI_DISPLAY_Y_ADR 0x2010 /* luma addr of displayed pic */ #define S5P_FIMV_SI_DISPLAY_C_ADR 0x2014 /* chroma addrof displayed pic */ + #define S5P_FIMV_SI_CONSUMED_BYTES 0x2018 /* Consumed number of bytes to decode a frame */ #define S5P_FIMV_SI_DISPLAY_STATUS 0x201c /* status of decoded picture */ +#define S5P_FIMV_SI_DECODE_Y_ADR 0x2024 /* luma addr of decoded pic */ +#define S5P_FIMV_SI_DECODE_C_ADR 0x2028 /* chroma addrof decoded pic */ +#define S5P_FIMV_SI_DECODE_STATUS 0x202c /* status of decoded picture */ + #define S5P_FIMV_SI_CH0_SB_ST_ADR 0x2044 /* start addr of stream buf */ #define S5P_FIMV_SI_CH0_SB_FRM_SIZE 0x2048 /* size of stream buf */ #define S5P_FIMV_SI_CH0_DESC_ADR 0x204c /* addr of descriptor buf */ diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c index c25ec022d267..feea867f318c 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c @@ -627,13 +627,13 @@ static int s5p_mfc_dec_s_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY: - ctx->loop_filter_mpeg4 = ctrl->val; + ctx->display_delay = ctrl->val; break; case V4L2_CID_MPEG_MFC51_VIDEO_DECODER_H264_DISPLAY_DELAY_ENABLE: ctx->display_delay_enable = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: - ctx->display_delay = ctrl->val; + ctx->loop_filter_mpeg4 = ctrl->val; break; case V4L2_CID_MPEG_VIDEO_DECODER_SLICE_INTERFACE: ctx->slice_interface = ctrl->val; @@ -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 acedb2004be3..158b78989b89 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c @@ -243,12 +243,6 @@ static struct mfc_control controls[] = { .minimum = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, .maximum = V4L2_MPEG_VIDEO_H264_LEVEL_4_0, .default_value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - .menu_skip_mask = ~( - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_1) | - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_4_2) | - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_0) | - (1 << V4L2_MPEG_VIDEO_H264_LEVEL_5_1) - ), }, { .id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, @@ -494,7 +488,7 @@ static struct mfc_control controls[] = { .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED, .maximum = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_EXTENDED, - .default_value = 0, + .default_value = V4L2_MPEG_VIDEO_H264_VUI_SAR_IDC_UNSPECIFIED, .menu_skip_mask = 0, }, { @@ -534,7 +528,7 @@ static struct mfc_control controls[] = { .type = V4L2_CTRL_TYPE_MENU, .minimum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, .maximum = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE, - .default_value = 0, + .default_value = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE, .menu_skip_mask = 0, }, { @@ -907,6 +901,8 @@ static int vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) mfc_err("failed to try output format\n"); return -EINVAL; } + v4l_bound_align_image(&pix_fmt_mp->width, 8, 1920, 1, + &pix_fmt_mp->height, 4, 1080, 1, 0); } else { mfc_err("invalid buf type\n"); return -EINVAL; @@ -1777,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/s5p-mfc/s5p_mfc_opr.h b/drivers/media/video/s5p-mfc/s5p_mfc_opr.h index db83836e6a9f..5932d1c782c5 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_opr.h +++ b/drivers/media/video/s5p-mfc/s5p_mfc_opr.h @@ -57,10 +57,12 @@ void s5p_mfc_cleanup_queue(struct list_head *lh, struct vb2_queue *vq); S5P_FIMV_SI_DISPLAY_Y_ADR) << \ MFC_OFFSET_SHIFT) #define s5p_mfc_get_dec_y_adr() (readl(dev->regs_base + \ - S5P_FIMV_SI_DISPLAY_Y_ADR) << \ + S5P_FIMV_SI_DECODE_Y_ADR) << \ MFC_OFFSET_SHIFT) #define s5p_mfc_get_dspl_status() readl(dev->regs_base + \ S5P_FIMV_SI_DISPLAY_STATUS) +#define s5p_mfc_get_dec_status() readl(dev->regs_base + \ + S5P_FIMV_SI_DECODE_STATUS) #define s5p_mfc_get_frame_type() (readl(dev->regs_base + \ S5P_FIMV_DECODE_FRAME_TYPE) \ & S5P_FIMV_DECODE_FRAME_MASK) diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h b/drivers/media/video/s5p-mfc/s5p_mfc_shm.h index 764eac6bcc4c..cf962a466276 100644 --- a/drivers/media/video/s5p-mfc/s5p_mfc_shm.h +++ b/drivers/media/video/s5p-mfc/s5p_mfc_shm.h @@ -13,8 +13,7 @@ #ifndef S5P_MFC_SHM_H_ #define S5P_MFC_SHM_H_ -enum MFC_SHM_OFS -{ +enum MFC_SHM_OFS { EXTENEDED_DECODE_STATUS = 0x00, /* D */ SET_FRAME_TAG = 0x04, /* D */ GET_FRAME_TAG_TOP = 0x08, /* D */ diff --git a/drivers/media/video/smiapp/Kconfig b/drivers/media/video/smiapp/Kconfig index f7b35ff443bf..fb99ff18be07 100644 --- a/drivers/media/video/smiapp/Kconfig +++ b/drivers/media/video/smiapp/Kconfig @@ -1,6 +1,6 @@ config VIDEO_SMIAPP tristate "SMIA++/SMIA sensor support" - depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API + depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAVE_CLK select VIDEO_SMIAPP_PLL ---help--- This is a generic driver for SMIA++/SMIA camera modules. diff --git a/drivers/media/video/smiapp/smiapp-core.c b/drivers/media/video/smiapp/smiapp-core.c index f518026cb67b..9cf5bda35fbe 100644 --- a/drivers/media/video/smiapp/smiapp-core.c +++ b/drivers/media/video/smiapp/smiapp-core.c @@ -31,7 +31,9 @@ #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> #include <media/v4l2-device.h> diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 3e050e12153b..1ad5ab6ce5cf 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -1178,7 +1178,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) return 0; if (vt->type == t->mode && analog_ops->get_afc) vt->afc = analog_ops->get_afc(&t->fe); - if (t->mode != V4L2_TUNER_RADIO) { + if (vt->type != V4L2_TUNER_RADIO) { vt->capability |= V4L2_TUNER_CAP_NORM; vt->rangelow = tv_range[0] * 16; vt->rangehigh = tv_range[1] * 16; diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 5ccbd4629f9c..83dbb2ddff10 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -656,7 +656,7 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_TRY_ENCODER_CMD, vidioc_try_encoder_cmd); SET_VALID_IOCTL(ops, VIDIOC_DECODER_CMD, vidioc_decoder_cmd); SET_VALID_IOCTL(ops, VIDIOC_TRY_DECODER_CMD, vidioc_try_decoder_cmd); - if (ops->vidioc_g_parm || vdev->current_norm) + if (ops->vidioc_g_parm || vdev->vfl_type == VFL_TYPE_GRABBER) set_bit(_IOC_NR(VIDIOC_G_PARM), valid_ioctls); SET_VALID_IOCTL(ops, VIDIOC_S_PARM, vidioc_s_parm); SET_VALID_IOCTL(ops, VIDIOC_G_TUNER, vidioc_g_tuner); @@ -679,6 +679,8 @@ static void determine_valid_ioctls(struct video_device *vdev) SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_PRESET, vidioc_query_dv_preset); SET_VALID_IOCTL(ops, VIDIOC_S_DV_TIMINGS, vidioc_s_dv_timings); SET_VALID_IOCTL(ops, VIDIOC_G_DV_TIMINGS, vidioc_g_dv_timings); + SET_VALID_IOCTL(ops, VIDIOC_ENUM_DV_TIMINGS, vidioc_enum_dv_timings); + SET_VALID_IOCTL(ops, VIDIOC_QUERY_DV_TIMINGS, vidioc_query_dv_timings); /* yes, really vidioc_subscribe_event */ SET_VALID_IOCTL(ops, VIDIOC_DQEVENT, vidioc_subscribe_event); SET_VALID_IOCTL(ops, VIDIOC_SUBSCRIBE_EVENT, vidioc_subscribe_event); diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 91be4e871f43..d7fa8962d8b3 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -1680,6 +1680,7 @@ static long __video_do_ioctl(struct file *file, break; ret = 0; + p->parm.capture.readbuffers = 2; if (ops->vidioc_g_std) ret = ops->vidioc_g_std(file, fh, &std); if (ret == 0) diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c index 4d7391ec8001..aae1720b2f2d 100644 --- a/drivers/media/video/vino.c +++ b/drivers/media/video/vino.c @@ -2561,7 +2561,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs) } else if (vino_drvdata->decoder && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) { int input; - int data_norm; + int data_norm = 0; v4l2_std_id norm; input = VINO_INPUT_COMPOSITE; @@ -2651,7 +2651,7 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input) } if (vino_drvdata->decoder_owner == vcs->channel) { - int data_norm; + int data_norm = 0; v4l2_std_id norm; ret = decoder_call(video, s_routing, diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 0960d7f0d394..08c10240e70f 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -1149,10 +1149,14 @@ static ssize_t vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { struct vivi_dev *dev = video_drvdata(file); + int err; dprintk(dev, 1, "read called\n"); - return vb2_read(&dev->vb_vidq, data, count, ppos, + mutex_lock(&dev->mutex); + err = vb2_read(&dev->vb_vidq, data, count, ppos, file->f_flags & O_NONBLOCK); + mutex_unlock(&dev->mutex); + return err; } static unsigned int diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index e129c820df7d..92144ed1ad46 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 63b30b17e4f3..000000000000 --- 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 3fcdab3eb8eb..03df422feb76 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 7e96bb229724..41088ecbb2a9 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 00c0aba7eba0..c4a69f193a1d 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/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c index 373f423b1181..947a06a1845f 100644 --- a/drivers/mfd/stmpe-i2c.c +++ b/drivers/mfd/stmpe-i2c.c @@ -6,7 +6,7 @@ * * License Terms: GNU General Public License, version 2 * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson - * Author: Viresh Kumar <viresh.kumar@st.com> for ST Microelectronics + * Author: Viresh Kumar <viresh.linux@gmail.com> for ST Microelectronics */ #include <linux/i2c.h> diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c index afd459013ecb..9edfe864cc05 100644 --- a/drivers/mfd/stmpe-spi.c +++ b/drivers/mfd/stmpe-spi.c @@ -4,7 +4,7 @@ * Copyright (C) ST Microelectronics SA 2011 * * License Terms: GNU General Public License, version 2 - * Author: Viresh Kumar <viresh.kumar@st.com> for ST Microelectronics + * Author: Viresh Kumar <viresh.linux@gmail.com> for ST Microelectronics */ #include <linux/spi/spi.h> @@ -146,4 +146,4 @@ module_exit(stmpe_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver"); -MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); +MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 93936f1b75eb..23f5463d4cae 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -835,7 +835,7 @@ static int _mei_irq_thread_read(struct mei_device *dev, s32 *slots, struct mei_cl *cl, struct mei_io_list *cmpl_list) { - if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) + + if ((*slots * sizeof(u32)) < (sizeof(struct mei_msg_hdr) + sizeof(struct hbm_flow_control))) { /* return the cancel routine */ list_del(&cb_pos->cb_list); diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index c70333228337..783fcd7365bc 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -982,7 +982,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, 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, @@ -992,7 +992,7 @@ static int __devinit mei_probe(struct pci_dev *pdev, if (err) { dev_err(&pdev->dev, "request_threaded_irq failure. irq = %d\n", pdev->irq); - goto unmap_memory; + goto disable_msi; } INIT_DELAYED_WORK(&dev->timer_work, mei_timer); if (mei_hw_init(dev)) { @@ -1023,8 +1023,8 @@ release_irq: mei_disable_interrupts(dev); flush_scheduled_work(); free_irq(pdev->irq, dev); +disable_msi: pci_disable_msi(pdev); -unmap_memory: pci_iounmap(pdev, dev->mem_addr); free_device: kfree(dev); @@ -1101,6 +1101,8 @@ static void __devexit mei_remove(struct pci_dev *pdev) pci_release_regions(pdev); pci_disable_device(pdev); + + misc_deregister(&mei_misc_device); } #ifdef CONFIG_PM static int mei_pci_suspend(struct device *device) @@ -1145,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, @@ -1216,7 +1218,6 @@ module_init(mei_init_module); */ static void __exit mei_exit_module(void) { - misc_deregister(&mei_misc_device); pci_unregister_driver(&mei_driver); pr_debug("unloaded successfully.\n"); diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c index 6be5605707b4..e2ec0505eb5c 100644 --- a/drivers/misc/mei/wd.c +++ b/drivers/misc/mei/wd.c @@ -341,7 +341,7 @@ static const struct watchdog_ops wd_ops = { }; static const struct watchdog_info wd_info = { .identity = INTEL_AMT_WATCHDOG_ID, - .options = WDIOF_KEEPALIVEPING, + .options = WDIOF_KEEPALIVEPING | WDIOF_ALARMONLY, }; static struct watchdog_device amt_wd_dev = { diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index 17bbacb1b4b1..87b251ab6ec5 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/card/block.c b/drivers/mmc/card/block.c index dd2d374dcc7a..276d21ce6bc1 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -554,7 +554,6 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) struct mmc_request mrq = {NULL}; struct mmc_command cmd = {0}; struct mmc_data data = {0}; - unsigned int timeout_us; struct scatterlist sg; @@ -574,23 +573,12 @@ static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) cmd.arg = 0; cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - data.timeout_ns = card->csd.tacc_ns * 100; - data.timeout_clks = card->csd.tacc_clks * 100; - - timeout_us = data.timeout_ns / 1000; - timeout_us += data.timeout_clks * 1000 / - (card->host->ios.clock / 1000); - - if (timeout_us > 100000) { - data.timeout_ns = 100000000; - data.timeout_clks = 0; - } - data.blksz = 4; data.blocks = 1; data.flags = MMC_DATA_READ; data.sg = &sg; data.sg_len = 1; + mmc_set_data_timeout(&data, card); mrq.cmd = &cmd; mrq.data = &data; diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c index f13e38deceac..8f5dc08d6598 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 2d4a4b746750..4f4489aa6bae 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, @@ -1326,7 +1330,7 @@ static int mmc_suspend(struct mmc_host *host) if (!err) mmc_card_set_sleep(host->card); } else if (!mmc_host_is_spi(host)) - mmc_deselect_cards(host); + err = mmc_deselect_cards(host); host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); mmc_release_host(host); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index c272c6868ecf..b2b43f624b9e 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1075,16 +1075,18 @@ static void mmc_sd_detect(struct mmc_host *host) */ static int mmc_sd_suspend(struct mmc_host *host) { + int err = 0; + BUG_ON(!host); BUG_ON(!host->card); mmc_claim_host(host); if (!mmc_host_is_spi(host)) - mmc_deselect_cards(host); + err = mmc_deselect_cards(host); host->card->state &= ~MMC_STATE_HIGHSPEED; mmc_release_host(host); - return 0; + return err; } /* diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 13d0e95380ab..41c5fd8848f4 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -218,6 +218,12 @@ static int sdio_enable_wide(struct mmc_card *card) if (ret) return ret; + if ((ctrl & SDIO_BUS_WIDTH_MASK) == SDIO_BUS_WIDTH_RESERVED) + pr_warning("%s: SDIO_CCCR_IF is invalid: 0x%02x\n", + mmc_hostname(card->host), ctrl); + + /* set as 4-bit bus width */ + ctrl &= ~SDIO_BUS_WIDTH_MASK; ctrl |= SDIO_BUS_WIDTH_4BIT; ret = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_IF, ctrl, NULL); diff --git a/drivers/mmc/host/atmel-mci-regs.h b/drivers/mmc/host/atmel-mci-regs.h index 787aba1682bb..ab56f7db5315 100644 --- a/drivers/mmc/host/atmel-mci-regs.h +++ b/drivers/mmc/host/atmel-mci-regs.h @@ -140,4 +140,18 @@ #define atmci_writel(port,reg,value) \ __raw_writel((value), (port)->regs + reg) +/* + * Fix sconfig's burst size according to atmel MCI. We need to convert them as: + * 1 -> 0, 4 -> 1, 8 -> 2, 16 -> 3. + * + * This can be done by finding most significant bit set. + */ +static inline unsigned int atmci_convert_chksize(unsigned int maxburst) +{ + if (maxburst > 1) + return fls(maxburst) - 2; + else + return 0; +} + #endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */ diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 420aca642b14..f2c115e06438 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -910,6 +910,7 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) enum dma_data_direction direction; enum dma_transfer_direction slave_dirn; unsigned int sglen; + u32 maxburst; u32 iflags; data->error = -EINPROGRESS; @@ -943,17 +944,18 @@ atmci_prepare_data_dma(struct atmel_mci *host, struct mmc_data *data) if (!chan) return -ENODEV; - if (host->caps.has_dma) - atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(3) | ATMCI_DMAEN); - if (data->flags & MMC_DATA_READ) { direction = DMA_FROM_DEVICE; host->dma_conf.direction = slave_dirn = DMA_DEV_TO_MEM; + maxburst = atmci_convert_chksize(host->dma_conf.src_maxburst); } else { direction = DMA_TO_DEVICE; host->dma_conf.direction = slave_dirn = DMA_MEM_TO_DEV; + maxburst = atmci_convert_chksize(host->dma_conf.dst_maxburst); } + atmci_writel(host, ATMCI_DMA, ATMCI_DMA_CHKSIZE(maxburst) | ATMCI_DMAEN); + sglen = dma_map_sg(chan->device->dev, data->sg, data->sg_len, direction); @@ -2314,6 +2316,8 @@ static int __init atmci_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); + setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); + /* We need at least one slot to succeed */ nr_slots = 0; ret = -ENODEV; @@ -2352,8 +2356,6 @@ static int __init atmci_probe(struct platform_device *pdev) } } - setup_timer(&host->timer, atmci_timeout_timer, (unsigned long)host); - dev_info(&pdev->dev, "Atmel MCI controller at 0x%08lx irq %d, %u slots\n", host->mapbase, irq, nr_slots); diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 9bbf45f8c538..1ca5e72ceb65 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -418,6 +418,8 @@ static int dw_mci_idmac_init(struct dw_mci *host) p->des3 = host->sg_dma; p->des0 = IDMAC_DES0_ER; + mci_writel(host, BMOD, SDMMC_IDMAC_SWRESET); + /* Mask out interrupts - get Tx & Rx complete only */ mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI | SDMMC_IDMAC_INT_TI); @@ -615,14 +617,15 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) u32 div; if (slot->clock != host->current_speed) { - if (host->bus_hz % slot->clock) + div = host->bus_hz / slot->clock; + if (host->bus_hz % slot->clock && host->bus_hz > slot->clock) /* * move the + 1 after the divide to prevent * over-clocking the card. */ - div = ((host->bus_hz / slot->clock) >> 1) + 1; - else - div = (host->bus_hz / slot->clock) >> 1; + div += 1; + + div = (host->bus_hz != slot->clock) ? DIV_ROUND_UP(div, 2) : 0; dev_info(&slot->mmc->class_dev, "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ" @@ -939,8 +942,8 @@ static void dw_mci_command_complete(struct dw_mci *host, struct mmc_command *cmd mdelay(20); if (cmd->data) { - host->data = NULL; dw_mci_stop_dma(host); + host->data = NULL; } } } @@ -1623,7 +1626,6 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) { mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI); mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI); - set_bit(EVENT_DATA_COMPLETE, &host->pending_events); host->dma_ops->complete(host); } #endif @@ -1725,7 +1727,8 @@ static void dw_mci_work_routine_card(struct work_struct *work) #ifdef CONFIG_MMC_DW_IDMAC ctrl = mci_readl(host, BMOD); - ctrl |= 0x01; /* Software reset of DMA */ + /* Software reset of DMA */ + ctrl |= SDMMC_IDMAC_SWRESET; mci_writel(host, BMOD, ctrl); #endif @@ -1950,10 +1953,6 @@ int dw_mci_probe(struct dw_mci *host) spin_lock_init(&host->lock); INIT_LIST_HEAD(&host->queue); - - host->dma_ops = host->pdata->dma_ops; - dw_mci_init_dma(host); - /* * Get the host data width - this assumes that HCON has been set with * the correct values. @@ -1981,10 +1980,11 @@ int dw_mci_probe(struct dw_mci *host) } /* Reset all blocks */ - if (!mci_wait_reset(&host->dev, host)) { - ret = -ENODEV; - goto err_dmaunmap; - } + if (!mci_wait_reset(&host->dev, host)) + return -ENODEV; + + host->dma_ops = host->pdata->dma_ops; + dw_mci_init_dma(host); /* Clear the interrupts for the host controller */ mci_writel(host, RINTSTS, 0xFFFFFFFF); @@ -2170,14 +2170,14 @@ int dw_mci_resume(struct dw_mci *host) if (host->vmmc) regulator_enable(host->vmmc); - if (host->dma_ops->init) - host->dma_ops->init(host); - if (!mci_wait_reset(&host->dev, host)) { ret = -ENODEV; return ret; } + if (host->dma_ops->init) + host->dma_ops->init(host); + /* Restore the old value at FIFOTH register */ mci_writel(host, FIFOTH, host->fifoth_val); diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index f0fcce40cd8d..50ff19a62368 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1216,12 +1216,7 @@ static void mmci_dt_populate_generic_pdata(struct device_node *np, int bus_width = 0; pdata->gpio_wp = of_get_named_gpio(np, "wp-gpios", 0); - if (!pdata->gpio_wp) - pdata->gpio_wp = -1; - pdata->gpio_cd = of_get_named_gpio(np, "cd-gpios", 0); - if (!pdata->gpio_cd) - pdata->gpio_cd = -1; if (of_get_property(np, "cd-inverted", NULL)) pdata->cd_invert = true; @@ -1276,6 +1271,12 @@ static int __devinit mmci_probe(struct amba_device *dev, return -EINVAL; } + if (!plat) { + plat = devm_kzalloc(&dev->dev, sizeof(*plat), GFP_KERNEL); + if (!plat) + return -ENOMEM; + } + if (np) mmci_dt_populate_generic_pdata(np, plat); @@ -1424,6 +1425,10 @@ static int __devinit mmci_probe(struct amba_device *dev, writel(0, host->base + MMCIMASK1); writel(0xfff, host->base + MMCICLEAR); + if (plat->gpio_cd == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err_gpio_cd; + } if (gpio_is_valid(plat->gpio_cd)) { ret = gpio_request(plat->gpio_cd, DRIVER_NAME " (cd)"); if (ret == 0) @@ -1447,6 +1452,10 @@ static int __devinit mmci_probe(struct amba_device *dev, if (ret >= 0) host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd); } + if (plat->gpio_wp == -EPROBE_DEFER) { + ret = -EPROBE_DEFER; + goto err_gpio_wp; + } if (gpio_is_valid(plat->gpio_wp)) { ret = gpio_request(plat->gpio_wp, DRIVER_NAME " (wp)"); if (ret == 0) diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 34a90266ab11..277161d279b8 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c @@ -894,8 +894,8 @@ static struct platform_driver mxs_mmc_driver = { .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &mxs_mmc_pm_ops, - .of_match_table = mxs_mmc_dt_ids, #endif + .of_match_table = mxs_mmc_dt_ids, }, }; diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 552196c764d4..3e8dcf8d2e05 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c @@ -1300,7 +1300,7 @@ static const struct mmc_host_ops mmc_omap_ops = { .set_ios = mmc_omap_set_ios, }; -static int __init mmc_omap_new_slot(struct mmc_omap_host *host, int id) +static int __devinit mmc_omap_new_slot(struct mmc_omap_host *host, int id) { struct mmc_omap_slot *slot = NULL; struct mmc_host *mmc; @@ -1485,24 +1485,26 @@ static int __devinit mmc_omap_probe(struct platform_device *pdev) } host->nr_slots = pdata->nr_slots; + host->reg_shift = (cpu_is_omap7xx() ? 1 : 2); + + host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); + if (!host->mmc_omap_wq) + goto err_plat_cleanup; + for (i = 0; i < pdata->nr_slots; i++) { ret = mmc_omap_new_slot(host, i); if (ret < 0) { while (--i >= 0) mmc_omap_remove_slot(host->slots[i]); - goto err_plat_cleanup; + goto err_destroy_wq; } } - host->reg_shift = (cpu_is_omap7xx() ? 1 : 2); - - host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0); - if (!host->mmc_omap_wq) - goto err_plat_cleanup; - return 0; +err_destroy_wq: + destroy_workqueue(host->mmc_omap_wq); err_plat_cleanup: if (pdata->cleanup) pdata->cleanup(&pdev->dev); diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 9a7a60aeb19e..389a3eedfc24 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c @@ -85,7 +85,6 @@ #define BRR_ENABLE (1 << 5) #define DTO_ENABLE (1 << 20) #define INIT_STREAM (1 << 1) -#define ACEN_ACMD12 (1 << 2) #define DP_SELECT (1 << 21) #define DDIR (1 << 4) #define DMA_EN 0x1 @@ -117,7 +116,6 @@ #define OMAP_MMC_MAX_CLOCK 52000000 #define DRIVER_NAME "omap_hsmmc" -#define AUTO_CMD12 (1 << 0) /* Auto CMD12 support */ /* * One controller can have multiple slots, like on some omap boards using * omap.c controller driver. Luckily this is not currently done on any known @@ -177,7 +175,6 @@ struct omap_hsmmc_host { int reqs_blocked; int use_reg; int req_in_progress; - unsigned int flags; struct omap_hsmmc_next next_data; struct omap_mmc_platform_data *pdata; @@ -773,8 +770,6 @@ omap_hsmmc_start_command(struct omap_hsmmc_host *host, struct mmc_command *cmd, cmdtype = 0x3; cmdreg = (cmd->opcode << 24) | (resptype << 16) | (cmdtype << 22); - if ((host->flags & AUTO_CMD12) && mmc_op_multi(cmd->opcode)) - cmdreg |= ACEN_ACMD12; if (data) { cmdreg |= DP_SELECT | MSBS | BCE; @@ -847,14 +842,11 @@ omap_hsmmc_xfer_done(struct omap_hsmmc_host *host, struct mmc_data *data) else data->bytes_xfered = 0; - if (data->stop && ((!(host->flags & AUTO_CMD12)) || data->error)) { - omap_hsmmc_start_command(host, data->stop, NULL); - } else { - if (data->stop) - data->stop->resp[0] = OMAP_HSMMC_READ(host->base, - RSP76); + if (!data->stop) { omap_hsmmc_request_done(host, data->mrq); + return; } + omap_hsmmc_start_command(host, data->stop, NULL); } /* @@ -1859,7 +1851,6 @@ static int __devinit omap_hsmmc_probe(struct platform_device *pdev) host->mapbase = res->start + pdata->reg_offset; host->base = ioremap(host->mapbase, SZ_4K); host->power_mode = MMC_POWER_OFF; - host->flags = AUTO_CMD12; host->next_data.cookie = 1; platform_set_drvdata(pdev, host); diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 55a164fcaa15..a50c205ea208 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -404,7 +404,7 @@ static void sdhci_s3c_setup_card_detect_gpio(struct sdhci_s3c *sc) if (sc->ext_cd_irq && request_threaded_irq(sc->ext_cd_irq, NULL, sdhci_s3c_gpio_card_detect_thread, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, dev_name(dev), sc) == 0) { int status = gpio_get_value(sc->ext_cd_gpio); if (pdata->ext_cd_gpio_invert) diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c index 1fe32dfa7cd4..423da8194cd8 100644 --- a/drivers/mmc/host/sdhci-spear.c +++ b/drivers/mmc/host/sdhci-spear.c @@ -4,7 +4,7 @@ * Support of SDHCI platform devices for spear soc family * * Copyright (C) 2010 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * Inspired by sdhci-pltfm.c * @@ -289,5 +289,5 @@ static struct platform_driver sdhci_driver = { module_platform_driver(sdhci_driver); MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver"); -MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); +MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index e626732aff77..f4b8b4db3a9a 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -680,8 +680,8 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) } if (count >= 0xF) { - pr_warning("%s: Too large timeout 0x%x requested for CMD%d!\n", - mmc_hostname(host->mmc), count, cmd->opcode); + DBG("%s: Too large timeout 0x%x requested for CMD%d!\n", + mmc_hostname(host->mmc), count, cmd->opcode); count = 0xE; } diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index ae36d7e1e913..551e316e4454 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -304,32 +304,17 @@ static void find_next_position(struct mtdoops_context *cxt) } static void mtdoops_do_dump(struct kmsg_dumper *dumper, - enum kmsg_dump_reason reason, const char *s1, unsigned long l1, - const char *s2, unsigned long l2) + enum kmsg_dump_reason reason) { struct mtdoops_context *cxt = container_of(dumper, struct mtdoops_context, dump); - unsigned long s1_start, s2_start; - unsigned long l1_cpy, l2_cpy; - char *dst; - - if (reason != KMSG_DUMP_OOPS && - reason != KMSG_DUMP_PANIC) - return; /* Only dump oopses if dump_oops is set */ if (reason == KMSG_DUMP_OOPS && !dump_oops) return; - dst = cxt->oops_buf + MTDOOPS_HEADER_SIZE; /* Skip the header */ - l2_cpy = min(l2, record_size - MTDOOPS_HEADER_SIZE); - l1_cpy = min(l1, record_size - MTDOOPS_HEADER_SIZE - l2_cpy); - - s2_start = l2 - l2_cpy; - s1_start = l1 - l1_cpy; - - memcpy(dst, s1 + s1_start, l1_cpy); - memcpy(dst + l1_cpy, s2 + s2_start, l2_cpy); + kmsg_dump_get_buffer(dumper, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE, + record_size - MTDOOPS_HEADER_SIZE, NULL); /* Panics must be written immediately */ if (reason != KMSG_DUMP_OOPS) @@ -375,6 +360,7 @@ static void mtdoops_notify_add(struct mtd_info *mtd) return; } + cxt->dump.max_reason = KMSG_DUMP_OOPS; cxt->dump.dump = mtdoops_do_dump; err = kmsg_dump_register(&cxt->dump); if (err) { diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 41371ba1a811..f3f6cfedd69e 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c @@ -102,7 +102,7 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; static int cafe_device_ready(struct mtd_info *mtd) { struct cafe_priv *cafe = mtd->priv; - int result = !!(cafe_readl(cafe, NAND_STATUS) | 0x40000000); + int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000); uint32_t irqs = cafe_readl(cafe, NAND_IRQ); cafe_writel(cafe, irqs, NAND_IRQ); diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index a05b7b444d4f..a6cad5caba78 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 c58e6a93f445..6acc790c2fbb 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/nand_base.c b/drivers/mtd/nand/nand_base.c index d47586cf64ce..a11253a0fcab 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -3501,6 +3501,13 @@ int nand_scan_tail(struct mtd_info *mtd) /* propagate ecc info to mtd_info */ mtd->ecclayout = chip->ecc.layout; mtd->ecc_strength = chip->ecc.strength; + /* + * Initialize bitflip_threshold to its default prior scan_bbt() call. + * scan_bbt() might invoke mtd_read(), thus bitflip_threshold must be + * properly set. + */ + if (!mtd->bitflip_threshold) + mtd->bitflip_threshold = mtd->ecc_strength; /* Check, if we should skip the bad block table scan */ if (chip->options & NAND_SKIP_BBTSCAN) diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 6cc8fbfabb8e..cf0cd3146817 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/mtd/ubi/debug.c b/drivers/mtd/ubi/debug.c index 09d4f8d9d592..7c1380305219 100644 --- a/drivers/mtd/ubi/debug.c +++ b/drivers/mtd/ubi/debug.c @@ -264,7 +264,7 @@ static struct dentry *dfs_rootdir; */ int ubi_debugfs_init(void) { - if (!IS_ENABLED(DEBUG_FS)) + if (!IS_ENABLED(CONFIG_DEBUG_FS)) return 0; dfs_rootdir = debugfs_create_dir("ubi", NULL); @@ -284,7 +284,7 @@ int ubi_debugfs_init(void) */ void ubi_debugfs_exit(void) { - if (IS_ENABLED(DEBUG_FS)) + if (IS_ENABLED(CONFIG_DEBUG_FS)) debugfs_remove(dfs_rootdir); } @@ -407,7 +407,7 @@ int ubi_debugfs_init_dev(struct ubi_device *ubi) struct dentry *dent; struct ubi_debug_info *d = ubi->dbg; - if (!IS_ENABLED(DEBUG_FS)) + if (!IS_ENABLED(CONFIG_DEBUG_FS)) return 0; n = snprintf(d->dfs_dir_name, UBI_DFS_DIR_LEN + 1, UBI_DFS_DIR_NAME, @@ -477,6 +477,6 @@ out: */ void ubi_debugfs_exit_dev(struct ubi_device *ubi) { - if (IS_ENABLED(DEBUG_FS)) + if (IS_ENABLED(CONFIG_DEBUG_FS)) debugfs_remove_recursive(ubi->dbg->dfs_dir); } diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c index ad284baafe87..3cea38d37344 100644 --- a/drivers/net/bonding/bond_procfs.c +++ b/drivers/net/bonding/bond_procfs.c @@ -150,14 +150,25 @@ static void bond_info_show_master(struct seq_file *seq) } } +static const char *bond_slave_link_status(s8 link) +{ + static const char * const status[] = { + [BOND_LINK_UP] = "up", + [BOND_LINK_FAIL] = "going down", + [BOND_LINK_DOWN] = "down", + [BOND_LINK_BACK] = "going back", + }; + + return status[link]; +} + static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave) { struct bonding *bond = seq->private; seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); - seq_printf(seq, "MII Status: %s\n", - (slave->link == BOND_LINK_UP) ? "up" : "down"); + seq_printf(seq, "MII Status: %s\n", bond_slave_link_status(slave->link)); if (slave->speed == SPEED_UNKNOWN) seq_printf(seq, "Speed: %s\n", "Unknown"); else diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 1520814c77c7..4a27adb7ae67 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c @@ -693,8 +693,6 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) */ memcpy(rx_buf, (u8 *)piggy_desc, CFHSI_DESC_SHORT_SZ); - /* Mark no embedded frame here */ - piggy_desc->offset = 0; if (desc_pld_len == -EPROTO) goto out_of_sync; } @@ -737,6 +735,8 @@ static void cfhsi_rx_done(struct cfhsi *cfhsi) /* Extract any payload in piggyback descriptor. */ if (cfhsi_rx_desc(piggy_desc, cfhsi) < 0) goto out_of_sync; + /* Mark no embedded frame after extracting it */ + piggy_desc->offset = 0; } } @@ -1178,6 +1178,7 @@ int cfhsi_probe(struct platform_device *pdev) dev_err(&ndev->dev, "%s: Registration error: %d.\n", __func__, res); free_netdev(ndev); + return -ENODEV; } /* Add CAIF HSI device to list. */ spin_lock(&cfhsi_list_lock); diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 8dc84d66eea1..86cd532c78f9 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -590,8 +590,8 @@ static void c_can_chip_config(struct net_device *dev) priv->write_reg(priv, &priv->regs->control, CONTROL_ENABLE_AR); - if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY & - CAN_CTRLMODE_LOOPBACK)) { + if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) && + (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) { /* loopback + silent mode : useful for hot self-test */ priv->write_reg(priv, &priv->regs->control, CONTROL_EIE | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 38c0690df5c8..81d474102378 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -939,12 +939,12 @@ static int __devinit flexcan_probe(struct platform_device *pdev) return PTR_ERR(pinctrl); if (pdev->dev.of_node) { - const u32 *clock_freq_p; + const __be32 *clock_freq_p; clock_freq_p = of_get_property(pdev->dev.of_node, "clock-frequency", NULL); if (clock_freq_p) - clock_freq = *clock_freq_p; + clock_freq = be32_to_cpup(clock_freq_p); } if (!clock_freq) { diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index cbc56f274e0c..8098eea9704d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -190,7 +190,7 @@ int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata) if ((netif_tx_queue_stopped(txq)) && (bp->state == BNX2X_STATE_OPEN) && - (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3)) + (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4)) netif_tx_wake_queue(txq); __netif_tx_unlock(txq); @@ -2516,8 +2516,6 @@ int bnx2x_poll(struct napi_struct *napi, int budget) /* we split the first BD into headers and data BDs * to ease the pain of our fellow microcode engineers * we use one mapping for both BDs - * So far this has only been observed to happen - * in Other Operating Systems(TM) */ static noinline u16 bnx2x_tx_split(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata, @@ -3171,7 +3169,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) txdata->tx_bd_prod += nbd; - if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 3)) { + if (unlikely(bnx2x_tx_avail(bp, txdata) < MAX_SKB_FRAGS + 4)) { netif_tx_stop_queue(txq); /* paired memory barrier is in bnx2x_tx_int(), we have to keep @@ -3180,7 +3178,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) smp_mb(); fp->eth_q_stats.driver_xoff++; - if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 3) + if (bnx2x_tx_avail(bp, txdata) >= MAX_SKB_FRAGS + 4) netif_tx_wake_queue(txq); } txdata->tx_pkt++; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index a3fb7215cd89..6e7d5c0843b4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -40,6 +40,7 @@ #define I2C_BSC0 0 #define I2C_BSC1 1 #define I2C_WA_RETRY_CNT 3 +#define I2C_WA_PWR_ITER (I2C_WA_RETRY_CNT - 1) #define MCPR_IMC_COMMAND_READ_OP 1 #define MCPR_IMC_COMMAND_WRITE_OP 2 @@ -7659,6 +7660,28 @@ static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, return -EINVAL; } +static void bnx2x_warpcore_power_module(struct link_params *params, + struct bnx2x_phy *phy, + u8 power) +{ + u32 pin_cfg; + struct bnx2x *bp = params->bp; + + pin_cfg = (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[params->port].e3_sfp_ctrl)) & + PORT_HW_CFG_E3_PWR_DIS_MASK) >> + PORT_HW_CFG_E3_PWR_DIS_SHIFT; + + if (pin_cfg == PIN_CFG_NA) + return; + DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n", + power, pin_cfg); + /* Low ==> corresponding SFP+ module is powered + * high ==> the SFP+ module is powered down + */ + bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1); +} static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, struct link_params *params, u16 addr, u8 byte_cnt, @@ -7678,6 +7701,12 @@ static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy, /* 4 byte aligned address */ addr32 = addr & (~0x3); do { + if (cnt == I2C_WA_PWR_ITER) { + bnx2x_warpcore_power_module(params, phy, 0); + /* Note that 100us are not enough here */ + usleep_range(1000,1000); + bnx2x_warpcore_power_module(params, phy, 1); + } rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt, data_array); } while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT)); @@ -8200,29 +8229,6 @@ static void bnx2x_set_sfp_module_fault_led(struct link_params *params, bnx2x_set_e1e2_module_fault_led(params, gpio_mode); } -static void bnx2x_warpcore_power_module(struct link_params *params, - struct bnx2x_phy *phy, - u8 power) -{ - u32 pin_cfg; - struct bnx2x *bp = params->bp; - - pin_cfg = (REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[params->port].e3_sfp_ctrl)) & - PORT_HW_CFG_E3_PWR_DIS_MASK) >> - PORT_HW_CFG_E3_PWR_DIS_SHIFT; - - if (pin_cfg == PIN_CFG_NA) - return; - DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n", - power, pin_cfg); - /* Low ==> corresponding SFP+ module is powered - * high ==> the SFP+ module is powered down - */ - bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1); -} - static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy, struct link_params *params) { @@ -9748,7 +9754,7 @@ static int bnx2x_848x3_config_init(struct bnx2x_phy *phy, msleep(1); - if (!(CHIP_IS_E1(bp))) + if (!(CHIP_IS_E1x(bp))) port = BP_PATH(bp); else port = params->port; diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 8d06ea381741..921c2082af4c 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -122,15 +122,15 @@ static int be_mcc_compl_process(struct be_adapter *adapter, goto done; if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) { - dev_warn(&adapter->pdev->dev, "This domain(VM) is not " - "permitted to execute this cmd (opcode %d)\n", - opcode); + dev_warn(&adapter->pdev->dev, + "opcode %d-%d is not permitted\n", + opcode, subsystem); } else { extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) & CQE_STATUS_EXTD_MASK; - dev_err(&adapter->pdev->dev, "Cmd (opcode %d) failed:" - "status %d, extd-status %d\n", - opcode, compl_status, extd_status); + dev_err(&adapter->pdev->dev, + "opcode %d-%d failed:status %d-%d\n", + opcode, subsystem, compl_status, extd_status); } } done: diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index 9625bf420c16..b3f3fc3d1323 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -1566,7 +1566,7 @@ struct be_hw_stats_v1 { u32 rsvd0[BE_TXP_SW_SZ]; struct be_erx_stats_v1 erx; struct be_pmem_stats pmem; - u32 rsvd1[3]; + u32 rsvd1[18]; }; struct be_cmd_req_get_stats_v1 { diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index fdb50cec6b51..501dfa9c88ec 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3237,7 +3237,7 @@ static void be_netdev_init(struct net_device *netdev) netdev->flags |= IFF_MULTICAST; - netif_set_gso_max_size(netdev, 65535); + netif_set_gso_max_size(netdev, 65535 - ETH_HLEN); netdev->netdev_ops = &be_netdev_ops; diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 0741aded9eb0..f2db8fca46a1 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1804,18 +1804,16 @@ void gfar_configure_coalescing(struct gfar_private *priv, if (priv->mode == MQ_MG_MODE) { baddr = ®s->txic0; for_each_set_bit(i, &tx_mask, priv->num_tx_queues) { - if (likely(priv->tx_queue[i]->txcoalescing)) { - gfar_write(baddr + i, 0); + gfar_write(baddr + i, 0); + if (likely(priv->tx_queue[i]->txcoalescing)) gfar_write(baddr + i, priv->tx_queue[i]->txic); - } } baddr = ®s->rxic0; for_each_set_bit(i, &rx_mask, priv->num_rx_queues) { - if (likely(priv->rx_queue[i]->rxcoalescing)) { - gfar_write(baddr + i, 0); + gfar_write(baddr + i, 0); + if (likely(priv->rx_queue[i]->rxcoalescing)) gfar_write(baddr + i, priv->rx_queue[i]->rxic); - } } } } diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig index 79b07ec6726f..0cafe4fe9406 100644 --- a/drivers/net/ethernet/intel/Kconfig +++ b/drivers/net/ethernet/intel/Kconfig @@ -122,8 +122,10 @@ config IGB_DCA config IGB_PTP bool "PTP Hardware Clock (PHC)" - default y - depends on IGB && PTP_1588_CLOCK + default n + depends on IGB && EXPERIMENTAL + select PPS + select PTP_1588_CLOCK ---help--- Say Y here if you want to use PTP Hardware Clock (PHC) in the driver. Only the basic clock operations have been implemented. @@ -223,7 +225,9 @@ config IXGBE_DCB config IXGBE_PTP bool "PTP Clock Support" default n - depends on IXGBE && PTP_1588_CLOCK + depends on IXGBE && EXPERIMENTAL + select PPS + select PTP_1588_CLOCK ---help--- Say Y here if you want support for 1588 Timestamping with a PHC device, using the PTP 1588 Clock support. This is diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index 351a4097b2ba..76edbc1be33b 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h @@ -103,6 +103,7 @@ #define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ #define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */ #define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */ +#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */ #define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ #define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 31d37a2b5ba8..623e30b9964d 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -496,7 +496,7 @@ static void e1000_receive_skb(struct e1000_adapter *adapter, * @sk_buff: socket buffer with received data **/ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, - __le16 csum, struct sk_buff *skb) + struct sk_buff *skb) { u16 status = (u16)status_err; u8 errors = (u8)(status_err >> 24); @@ -511,8 +511,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, if (status & E1000_RXD_STAT_IXSM) return; - /* TCP/UDP checksum error bit is set */ - if (errors & E1000_RXD_ERR_TCPE) { + /* TCP/UDP checksum error bit or IP checksum error bit is set */ + if (errors & (E1000_RXD_ERR_TCPE | E1000_RXD_ERR_IPE)) { /* let the stack verify checksum errors */ adapter->hw_csum_err++; return; @@ -523,19 +523,7 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, return; /* It must be a TCP or UDP packet with a valid checksum */ - if (status & E1000_RXD_STAT_TCPCS) { - /* TCP checksum is good */ - skb->ip_summed = CHECKSUM_UNNECESSARY; - } else { - /* - * IP fragment with UDP payload - * Hardware complements the payload checksum, so we undo it - * and then put the value in host order for further stack use. - */ - __sum16 sum = (__force __sum16)swab16((__force u16)csum); - skb->csum = csum_unfold(~sum); - skb->ip_summed = CHECKSUM_COMPLETE; - } + skb->ip_summed = CHECKSUM_UNNECESSARY; adapter->hw_csum_good++; } @@ -954,8 +942,7 @@ static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done, skb_put(skb, length); /* Receive Checksum Offload */ - e1000_rx_checksum(adapter, staterr, - rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + e1000_rx_checksum(adapter, staterr, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); @@ -1341,8 +1328,7 @@ copydone: total_rx_bytes += skb->len; total_rx_packets++; - e1000_rx_checksum(adapter, staterr, - rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + e1000_rx_checksum(adapter, staterr, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); @@ -1512,9 +1498,8 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, } } - /* Receive Checksum Offload XXX recompute due to CRC strip? */ - e1000_rx_checksum(adapter, staterr, - rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + /* Receive Checksum Offload */ + e1000_rx_checksum(adapter, staterr, skb); e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); @@ -3098,19 +3083,10 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) /* Enable Receive Checksum Offload for TCP and UDP */ rxcsum = er32(RXCSUM); - if (adapter->netdev->features & NETIF_F_RXCSUM) { + if (adapter->netdev->features & NETIF_F_RXCSUM) rxcsum |= E1000_RXCSUM_TUOFL; - - /* - * IPv4 payload checksum for UDP fragments must be - * used in conjunction with packet-split. - */ - if (adapter->rx_ps_pages) - rxcsum |= E1000_RXCSUM_IPPCSE; - } else { + else rxcsum &= ~E1000_RXCSUM_TUOFL; - /* no need to clear IPPCSE as it defaults to 0 */ - } ew32(RXCSUM, rxcsum); if (adapter->hw.mac.type == e1000_pch2lan) { @@ -5241,22 +5217,10 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; /* Jumbo frame support */ - if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) { - if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { - e_err("Jumbo Frames not supported.\n"); - return -EINVAL; - } - - /* - * IP payload checksum (enabled with jumbos/packet-split when - * Rx checksum is enabled) and generation of RSS hash is - * mutually exclusive in the hardware. - */ - if ((netdev->features & NETIF_F_RXCSUM) && - (netdev->features & NETIF_F_RXHASH)) { - e_err("Jumbo frames cannot be enabled when both receive checksum offload and receive hashing are enabled. Disable one of the receive offload features before enabling jumbos.\n"); - return -EINVAL; - } + if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) && + !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { + e_err("Jumbo Frames not supported.\n"); + return -EINVAL; } /* Supported frame sizes */ @@ -6030,17 +5994,6 @@ static int e1000_set_features(struct net_device *netdev, NETIF_F_RXALL))) return 0; - /* - * IP payload checksum (enabled with jumbos/packet-split when Rx - * checksum is enabled) and generation of RSS hash is mutually - * exclusive in the hardware. - */ - if (adapter->rx_ps_pages && - (features & NETIF_F_RXCSUM) && (features & NETIF_F_RXHASH)) { - e_err("Enabling both receive checksum offload and receive hashing is not possible with jumbo frames. Disable jumbos or enable only one of the receive offload features.\n"); - return -EINVAL; - } - if (changed & NETIF_F_RXFCS) { if (features & NETIF_F_RXFCS) { adapter->flags2 &= ~FLAG2_CRC_STRIPPING; diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index e65083958421..5e84eaac48c1 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -206,8 +206,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) mac->rar_entry_count = E1000_RAR_ENTRIES_82580; break; case e1000_i350: - case e1000_i210: - case e1000_i211: mac->rar_entry_count = E1000_RAR_ENTRIES_I350; break; default: diff --git a/drivers/net/ethernet/intel/igbvf/ethtool.c b/drivers/net/ethernet/intel/igbvf/ethtool.c index 8ce67064b9c5..90eef07943f4 100644 --- a/drivers/net/ethernet/intel/igbvf/ethtool.c +++ b/drivers/net/ethernet/intel/igbvf/ethtool.c @@ -357,21 +357,28 @@ static int igbvf_set_coalesce(struct net_device *netdev, struct igbvf_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - if ((ec->rx_coalesce_usecs > IGBVF_MAX_ITR_USECS) || - ((ec->rx_coalesce_usecs > 3) && - (ec->rx_coalesce_usecs < IGBVF_MIN_ITR_USECS)) || - (ec->rx_coalesce_usecs == 2)) - return -EINVAL; - - /* convert to rate of irq's per second */ - if (ec->rx_coalesce_usecs && ec->rx_coalesce_usecs <= 3) { + if ((ec->rx_coalesce_usecs >= IGBVF_MIN_ITR_USECS) && + (ec->rx_coalesce_usecs <= IGBVF_MAX_ITR_USECS)) { + adapter->current_itr = ec->rx_coalesce_usecs << 2; + adapter->requested_itr = 1000000000 / + (adapter->current_itr * 256); + } else if ((ec->rx_coalesce_usecs == 3) || + (ec->rx_coalesce_usecs == 2)) { adapter->current_itr = IGBVF_START_ITR; adapter->requested_itr = ec->rx_coalesce_usecs; - } else { - adapter->current_itr = ec->rx_coalesce_usecs << 2; + } else if (ec->rx_coalesce_usecs == 0) { + /* + * The user's desire is to turn off interrupt throttling + * altogether, but due to HW limitations, we can't do that. + * Instead we set a very small value in EITR, which would + * allow ~967k interrupts per second, but allow the adapter's + * internal clocking to still function properly. + */ + adapter->current_itr = 4; adapter->requested_itr = 1000000000 / (adapter->current_itr * 256); - } + } else + return -EINVAL; writel(adapter->current_itr, hw->hw_addr + adapter->rx_ring->itr_register); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 3ef3c5284e52..7af291e236bf 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h @@ -196,7 +196,7 @@ enum ixgbe_ring_state_t { __IXGBE_HANG_CHECK_ARMED, __IXGBE_RX_RSC_ENABLED, __IXGBE_RX_CSUM_UDP_ZERO_ERR, - __IXGBE_RX_FCOE_BUFSZ, + __IXGBE_RX_FCOE, }; #define check_for_tx_hang(ring) \ @@ -290,7 +290,7 @@ struct ixgbe_ring_feature { #if defined(IXGBE_FCOE) && (PAGE_SIZE < 8192) static inline unsigned int ixgbe_rx_pg_order(struct ixgbe_ring *ring) { - return test_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state) ? 1 : 0; + return test_bit(__IXGBE_RX_FCOE, &ring->state) ? 1 : 0; } #else #define ixgbe_rx_pg_order(_ring) 0 diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index af1a5314b494..c377706e81a8 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -634,7 +634,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, f = &adapter->ring_feature[RING_F_FCOE]; if ((rxr_idx >= f->mask) && (rxr_idx < f->mask + f->indices)) - set_bit(__IXGBE_RX_FCOE_BUFSZ, &ring->state); + set_bit(__IXGBE_RX_FCOE, &ring->state); } #endif /* IXGBE_FCOE */ diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 17ad6a3c1be1..18ca3bcadf0c 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -1058,17 +1058,17 @@ static inline void ixgbe_rx_hash(struct ixgbe_ring *ring, #ifdef IXGBE_FCOE /** * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type - * @adapter: address of board private structure + * @ring: structure containing ring specific data * @rx_desc: advanced rx descriptor * * Returns : true if it is FCoE pkt */ -static inline bool ixgbe_rx_is_fcoe(struct ixgbe_adapter *adapter, +static inline bool ixgbe_rx_is_fcoe(struct ixgbe_ring *ring, union ixgbe_adv_rx_desc *rx_desc) { __le16 pkt_info = rx_desc->wb.lower.lo_dword.hs_rss.pkt_info; - return (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && + return test_bit(__IXGBE_RX_FCOE, &ring->state) && ((pkt_info & cpu_to_le16(IXGBE_RXDADV_PKTTYPE_ETQF_MASK)) == (cpu_to_le16(IXGBE_ETQF_FILTER_FCOE << IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT))); @@ -1148,7 +1148,7 @@ static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring, /* alloc new page for storage */ if (likely(!page)) { - page = alloc_pages(GFP_ATOMIC | __GFP_COLD, + page = alloc_pages(GFP_ATOMIC | __GFP_COLD | __GFP_COMP, ixgbe_rx_pg_order(rx_ring)); if (unlikely(!page)) { rx_ring->rx_stats.alloc_rx_page_failed++; @@ -1549,6 +1549,12 @@ static bool ixgbe_cleanup_headers(struct ixgbe_ring *rx_ring, skb->truesize -= ixgbe_rx_bufsz(rx_ring); } +#ifdef IXGBE_FCOE + /* do not attempt to pad FCoE Frames as this will disrupt DDP */ + if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) + return false; + +#endif /* if skb_pad returns an error the skb was freed */ if (unlikely(skb->len < 60)) { int pad_len = 60 - skb->len; @@ -1775,7 +1781,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, #ifdef IXGBE_FCOE /* if ddp, not passing to ULD unless for FCP_RSP or error */ - if (ixgbe_rx_is_fcoe(adapter, rx_desc)) { + if (ixgbe_rx_is_fcoe(rx_ring, rx_desc)) { ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb); if (!ddp_bytes) { dev_kfree_skb_any(skb); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index ddc6a4d19302..dcebd128becf 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -708,6 +708,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; u32 incval = 0; + u32 timinca = 0; u32 shift = 0; u32 cycle_speed; unsigned long flags; @@ -730,8 +731,16 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) break; } - /* Bail if the cycle speed didn't change */ - if (adapter->cycle_speed == cycle_speed) + /* + * grab the current TIMINCA value from the register so that it can be + * double checked. If the register value has been cleared, it must be + * reset to the correct value for generating a cyclecounter. If + * TIMINCA is zero, the SYSTIME registers do not increment at all. + */ + timinca = IXGBE_READ_REG(hw, IXGBE_TIMINCA); + + /* Bail if the cycle speed didn't change and TIMINCA is non-zero */ + if (adapter->cycle_speed == cycle_speed && timinca) return; /* disable the SDP clock out */ diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 926d8aac941c..073b85b45fc5 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -929,15 +929,20 @@ void mlx4_en_free_resources(struct mlx4_en_priv *priv) if (priv->rx_cq[i].buf) mlx4_en_destroy_cq(priv, &priv->rx_cq[i]); } + + if (priv->base_tx_qpn) { + mlx4_qp_release_range(priv->mdev->dev, priv->base_tx_qpn, priv->tx_ring_num); + priv->base_tx_qpn = 0; + } } int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) { struct mlx4_en_port_profile *prof = priv->prof; int i; - int base_tx_qpn, err; + int err; - err = mlx4_qp_reserve_range(priv->mdev->dev, priv->tx_ring_num, 256, &base_tx_qpn); + err = mlx4_qp_reserve_range(priv->mdev->dev, priv->tx_ring_num, 256, &priv->base_tx_qpn); if (err) { en_err(priv, "failed reserving range for TX rings\n"); return err; @@ -949,7 +954,7 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) prof->tx_ring_size, i, TX)) goto err; - if (mlx4_en_create_tx_ring(priv, &priv->tx_ring[i], base_tx_qpn + i, + if (mlx4_en_create_tx_ring(priv, &priv->tx_ring[i], priv->base_tx_qpn + i, prof->tx_ring_size, TXBB_SIZE)) goto err; } @@ -969,7 +974,6 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) err: en_err(priv, "Failed to allocate NIC resources\n"); - mlx4_qp_release_range(priv->mdev->dev, base_tx_qpn, priv->tx_ring_num); return -ENOMEM; } @@ -1204,9 +1208,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, en_warn(priv, "Using %d RX rings\n", prof->rx_ring_num); /* Configure port */ + mlx4_en_calc_rx_buf(dev); err = mlx4_SET_PORT_general(mdev->dev, priv->port, - MLX4_EN_MIN_MTU, - 0, 0, 0, 0); + priv->rx_skb_size + ETH_FCS_LEN, + prof->tx_pause, prof->tx_ppp, + prof->rx_pause, prof->rx_ppp); if (err) { en_err(priv, "Failed setting port general configurations " "for port %d, with error %d\n", priv->port, err); diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index ee6f4fe00837..a0313de122de 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1975,6 +1975,8 @@ slave_start: if (err == -EBUSY && (dev->flags & MLX4_FLAG_MSI_X) && !mlx4_is_mfunc(dev)) { dev->flags &= ~MLX4_FLAG_MSI_X; + dev->caps.num_comp_vectors = 1; + dev->caps.comp_pool = 0; pci_disable_msix(pdev); err = mlx4_setup_hca(dev); } diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 6ae350921b1a..225c20d47900 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -495,6 +495,7 @@ struct mlx4_en_priv { int vids[128]; bool wol; struct device *ddev; + int base_tx_qpn; #ifdef CONFIG_MLX4_EN_DCB struct ieee_ets ets; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 46e77a2c5121..ad98f4d7919d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -479,7 +479,7 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { pfn = pci_info[i].id; - if (pfn > QLCNIC_MAX_PCI_FUNC) { + if (pfn >= QLCNIC_MAX_PCI_FUNC) { ret = QL_STATUS_INVALID_PARAM; goto err_eswitch; } diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 7260aa79466a..d7a04e091101 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3894,6 +3894,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_22: case RTL_GIGA_MAC_VER_23: case RTL_GIGA_MAC_VER_24: + case RTL_GIGA_MAC_VER_34: RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); break; default: diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 667169b82526..79bf09b41971 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1011,7 +1011,7 @@ static int sh_eth_txfree(struct net_device *ndev) } /* Packet receive function */ -static int sh_eth_rx(struct net_device *ndev) +static int sh_eth_rx(struct net_device *ndev, u32 intr_status) { struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_rxdesc *rxdesc; @@ -1102,9 +1102,11 @@ static int sh_eth_rx(struct net_device *ndev) /* Restart Rx engine if stopped. */ /* If we don't need to check status, don't. -KDU */ if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) { - /* fix the values for the next receiving */ - mdp->cur_rx = mdp->dirty_rx = (sh_eth_read(ndev, RDFAR) - - sh_eth_read(ndev, RDLAR)) >> 4; + /* fix the values for the next receiving if RDE is set */ + if (intr_status & EESR_RDE) + mdp->cur_rx = mdp->dirty_rx = + (sh_eth_read(ndev, RDFAR) - + sh_eth_read(ndev, RDLAR)) >> 4; sh_eth_write(ndev, EDRRR_R, EDRRR); } @@ -1273,7 +1275,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) EESR_RTSF | /* short frame recv */ EESR_PRE | /* PHY-LSI recv error */ EESR_CERF)){ /* recv frame CRC error */ - sh_eth_rx(ndev); + sh_eth_rx(ndev, intr_status); } /* Tx Check */ diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c index d614c374ed9d..3b5c4571b55e 100644 --- a/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/drivers/net/ethernet/ti/davinci_cpdma.c @@ -15,6 +15,7 @@ #include <linux/kernel.h> #include <linux/spinlock.h> #include <linux/device.h> +#include <linux/module.h> #include <linux/slab.h> #include <linux/err.h> #include <linux/dma-mapping.h> diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 590f902deb6b..9d6c80c8a0cf 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -161,7 +161,7 @@ static struct phy_driver ks8051_driver = { static struct phy_driver ks8001_driver = { .phy_id = PHY_ID_KS8001, .name = "Micrel KS8001 or KS8721", - .phy_id_mask = 0x00fffff0, + .phy_id_mask = 0x00ffffff, .features = (PHY_BASIC_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, @@ -174,7 +174,7 @@ static struct phy_driver ks8001_driver = { static struct phy_driver ksz9021_driver = { .phy_id = PHY_ID_KSZ9021, - .phy_id_mask = 0x000fff10, + .phy_id_mask = 0x000ffffe, .name = "Micrel KSZ9021 Gigabit PHY", .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause | SUPPORTED_Asym_Pause), @@ -240,8 +240,8 @@ MODULE_AUTHOR("David J. Choi"); MODULE_LICENSE("GPL"); static struct mdio_device_id __maybe_unused micrel_tbl[] = { - { PHY_ID_KSZ9021, 0x000fff10 }, - { PHY_ID_KS8001, 0x00fffff0 }, + { PHY_ID_KSZ9021, 0x000ffffe }, + { PHY_ID_KS8001, 0x00ffffff }, { PHY_ID_KS8737, 0x00fffff0 }, { PHY_ID_KS8041, 0x00fffff0 }, { PHY_ID_KS8051, 0x00fffff0 }, diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 964031e3da87..a28a983d465e 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -59,6 +59,7 @@ #define USB_PRODUCT_IPHONE_3G 0x1292 #define USB_PRODUCT_IPHONE_3GS 0x1294 #define USB_PRODUCT_IPHONE_4 0x1297 +#define USB_PRODUCT_IPAD 0x129a #define USB_PRODUCT_IPHONE_4_VZW 0x129c #define USB_PRODUCT_IPHONE_4S 0x12a0 @@ -101,6 +102,10 @@ static struct usb_device_id ipheth_table[] = { IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_PROTO) }, { USB_DEVICE_AND_INTERFACE_INFO( + USB_VENDOR_APPLE, USB_PRODUCT_IPAD, + IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, + IPHETH_USBINTF_PROTO) }, + { USB_DEVICE_AND_INTERFACE_INFO( USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW, IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_PROTO) }, diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 3b206786b5e7..b01960fcfbc9 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -197,6 +197,10 @@ err: static int qmi_wwan_cdc_wdm_manage_power(struct usb_interface *intf, int on) { struct usbnet *dev = usb_get_intfdata(intf); + + /* can be called while disconnecting */ + if (!dev) + return 0; return qmi_wwan_manage_power(dev, on); } @@ -257,29 +261,6 @@ err: return rv; } -/* Gobi devices uses identical class/protocol codes for all interfaces regardless - * of function. Some of these are CDC ACM like and have the exact same endpoints - * we are looking for. This leaves two possible strategies for identifying the - * correct interface: - * a) hardcoding interface number, or - * b) use the fact that the wwan interface is the only one lacking additional - * (CDC functional) descriptors - * - * Let's see if we can get away with the generic b) solution. - */ -static int qmi_wwan_bind_gobi(struct usbnet *dev, struct usb_interface *intf) -{ - int rv = -EINVAL; - - /* ignore any interface with additional descriptors */ - if (intf->cur_altsetting->extralen) - goto err; - - rv = qmi_wwan_bind_shared(dev, intf); -err: - return rv; -} - static void qmi_wwan_unbind_shared(struct usbnet *dev, struct usb_interface *intf) { struct usb_driver *subdriver = (void *)dev->data[0]; @@ -347,15 +328,15 @@ static const struct driver_info qmi_wwan_shared = { .manage_power = qmi_wwan_manage_power, }; -static const struct driver_info qmi_wwan_gobi = { - .description = "Qualcomm Gobi wwan/QMI device", +static const struct driver_info qmi_wwan_force_int0 = { + .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_gobi, + .bind = qmi_wwan_bind_shared, .unbind = qmi_wwan_unbind_shared, .manage_power = qmi_wwan_manage_power, + .data = BIT(0), /* interface whitelist bitmap */ }; -/* ZTE suck at making USB descriptors */ static const struct driver_info qmi_wwan_force_int1 = { .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, @@ -365,6 +346,15 @@ static const struct driver_info qmi_wwan_force_int1 = { .data = BIT(1), /* interface whitelist bitmap */ }; +static const struct driver_info qmi_wwan_force_int3 = { + .description = "Qualcomm WWAN/QMI device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind_shared, + .unbind = qmi_wwan_unbind_shared, + .manage_power = qmi_wwan_manage_power, + .data = BIT(3), /* interface whitelist bitmap */ +}; + static const struct driver_info qmi_wwan_force_int4 = { .description = "Qualcomm WWAN/QMI device", .flags = FLAG_WWAN, @@ -390,16 +380,23 @@ static const struct driver_info qmi_wwan_force_int4 = { static const struct driver_info qmi_wwan_sierra = { .description = "Sierra Wireless wwan/QMI device", .flags = FLAG_WWAN, - .bind = qmi_wwan_bind_gobi, + .bind = qmi_wwan_bind_shared, .unbind = qmi_wwan_unbind_shared, .manage_power = qmi_wwan_manage_power, .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ }; #define HUAWEI_VENDOR_ID 0x12D1 + +/* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ +#define QMI_GOBI1K_DEVICE(vend, prod) \ + USB_DEVICE(vend, prod), \ + .driver_info = (unsigned long)&qmi_wwan_force_int3 + +/* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */ #define QMI_GOBI_DEVICE(vend, prod) \ USB_DEVICE(vend, prod), \ - .driver_info = (unsigned long)&qmi_wwan_gobi + .driver_info = (unsigned long)&qmi_wwan_force_int0 static const struct usb_device_id products[] = { { /* Huawei E392, E398 and possibly others sharing both device id and more... */ @@ -510,20 +507,24 @@ static const struct usb_device_id products[] = { .bInterfaceProtocol = 0xff, .driver_info = (unsigned long)&qmi_wwan_sierra, }, - {QMI_GOBI_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ - {QMI_GOBI_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ - {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ - {QMI_GOBI_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ - {QMI_GOBI_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ - {QMI_GOBI_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ - {QMI_GOBI_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ - {QMI_GOBI_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ + + /* Gobi 1000 devices */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ + {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ + {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ + {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x0b05, 0x1776)}, /* Asus Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x19d2, 0xfff3)}, /* ONDA Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9001)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9002)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9202)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9203)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ + {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ + + /* Gobi 2000 and 3000 devices */ {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 9f58330f1312..aba769d77459 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -796,11 +796,13 @@ int usbnet_open (struct net_device *net) if (info->manage_power) { retval = info->manage_power(dev, 1); if (retval < 0) - goto done; + goto done_manage_power_error; usb_autopm_put_interface(dev->intf); } return retval; +done_manage_power_error: + clear_bit(EVENT_DEV_OPEN, &dev->flags); done: usb_autopm_put_interface(dev->intf); done_nopm: @@ -876,9 +878,9 @@ void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info) { struct usbnet *dev = netdev_priv(net); - strncpy (info->driver, dev->driver_name, sizeof info->driver); - strncpy (info->version, DRIVER_VERSION, sizeof info->version); - strncpy (info->fw_version, dev->driver_info->description, + strlcpy (info->driver, dev->driver_name, sizeof info->driver); + strlcpy (info->version, DRIVER_VERSION, sizeof info->version); + strlcpy (info->fw_version, dev->driver_info->description, sizeof info->fw_version); usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info); } @@ -1202,6 +1204,21 @@ deferred: } EXPORT_SYMBOL_GPL(usbnet_start_xmit); +static void rx_alloc_submit(struct usbnet *dev, gfp_t flags) +{ + struct urb *urb; + int i; + + /* don't refill the queue all at once */ + for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) { + urb = usb_alloc_urb(0, flags); + if (urb != NULL) { + if (rx_submit(dev, urb, flags) == -ENOLINK) + return; + } + } +} + /*-------------------------------------------------------------------------*/ // tasklet (work deferred from completions, in_irq) or timer @@ -1241,26 +1258,14 @@ static void usbnet_bh (unsigned long param) !timer_pending (&dev->delay) && !test_bit (EVENT_RX_HALT, &dev->flags)) { int temp = dev->rxq.qlen; - int qlen = RX_QLEN (dev); - - if (temp < qlen) { - struct urb *urb; - int i; - - // don't refill the queue all at once - for (i = 0; i < 10 && dev->rxq.qlen < qlen; i++) { - urb = usb_alloc_urb (0, GFP_ATOMIC); - if (urb != NULL) { - if (rx_submit (dev, urb, GFP_ATOMIC) == - -ENOLINK) - return; - } - } + + if (temp < RX_QLEN(dev)) { + rx_alloc_submit(dev, GFP_ATOMIC); if (temp != dev->rxq.qlen) netif_dbg(dev, link, dev->net, "rxqlen %d --> %d\n", temp, dev->rxq.qlen); - if (dev->rxq.qlen < qlen) + if (dev->rxq.qlen < RX_QLEN(dev)) tasklet_schedule (&dev->bh); } if (dev->txq.qlen < TX_QLEN (dev)) @@ -1513,6 +1518,7 @@ int usbnet_suspend (struct usb_interface *intf, pm_message_t message) spin_lock_irq(&dev->txq.lock); /* don't autosuspend while transmitting */ if (dev->txq.qlen && PMSG_IS_AUTO(message)) { + dev->suspend_count--; spin_unlock_irq(&dev->txq.lock); return -EBUSY; } else { @@ -1569,6 +1575,13 @@ int usbnet_resume (struct usb_interface *intf) spin_unlock_irq(&dev->txq.lock); if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { + /* handle remote wakeup ASAP */ + if (!dev->wait && + netif_device_present(dev->net) && + !timer_pending(&dev->delay) && + !test_bit(EVENT_RX_HALT, &dev->flags)) + rx_alloc_submit(dev, GFP_KERNEL); + if (!(dev->txq.qlen >= TX_QLEN(dev))) netif_tx_wake_all_queues(dev->net); tasklet_schedule (&dev->bh); diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 520a4b2eb9cc..a747c632597a 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -7233,8 +7233,8 @@ static int airo_get_aplist(struct net_device *dev, } } else { dwrq->flags = 1; /* Should be define'd */ - memcpy(extra + sizeof(struct sockaddr)*i, - &qual, sizeof(struct iw_quality)*i); + memcpy(extra + sizeof(struct sockaddr) * i, qual, + sizeof(struct iw_quality) * i); } dwrq->length = i; diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index c54b7d37bff1..420d69b2674c 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -143,6 +143,7 @@ struct ath_common { u32 keymax; DECLARE_BITMAP(keymap, ATH_KEYMAX); DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); + DECLARE_BITMAP(ccmp_keymap, ATH_KEYMAX); enum ath_crypt_caps crypt_caps; unsigned int clockrate; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index fbaa30930076..44ad6fe0278f 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1045,11 +1045,11 @@ ath5k_drain_tx_buffs(struct ath5k_hw *ah) ath5k_txbuf_free_skb(ah, bf); - spin_lock_bh(&ah->txbuflock); + spin_lock(&ah->txbuflock); list_move_tail(&bf->list, &ah->txbuf); ah->txbuf_len++; txq->txq_len--; - spin_unlock_bh(&ah->txbuflock); + spin_unlock(&ah->txbuflock); } txq->link = NULL; txq->txq_poll_mark = false; diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index a277cf6f339d..4866550ddd96 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -214,6 +214,7 @@ struct ath_frame_info { enum ath9k_key_type keytype; u8 keyix; u8 retries; + u8 rtscts_rate; }; struct ath_buf_state { diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 2b8f61c210e1..abbd6effd60d 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1496,6 +1496,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--; if (priv->ah->opmode == NL80211_IFTYPE_STATION) { + ath9k_htc_choose_set_bssid(priv); if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1)) ath9k_htc_start_ani(priv); else if (priv->num_sta_assoc_vif == 0) @@ -1503,13 +1504,11 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, } } - if (changed & BSS_CHANGED_BSSID) { + if (changed & BSS_CHANGED_IBSS) { if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { common->curaid = bss_conf->aid; memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); ath9k_htc_set_bssid(priv); - } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) { - ath9k_htc_choose_set_bssid(priv); } } diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 7db1890448f2..995ca8e1302e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -622,7 +622,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || - ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && + ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) && !ah->is_pciexpress)) { ah->config.serialize_regmode = SER_REG_MODE_ON; @@ -784,13 +784,25 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) { + struct ath_common *common = ath9k_hw_common(ah); + int i = 0; + REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); udelay(100); REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); - while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) + while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) { + udelay(100); + if (WARN_ON_ONCE(i >= 100)) { + ath_err(common, "PLL4 meaurement not done\n"); + break; + } + + i++; + } + return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; } EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4de4473776ac..dac1a2709e3c 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -971,6 +971,15 @@ void ath_hw_pll_work(struct work_struct *work) hw_pll_work.work); u32 pll_sqsum; + /* + * ensure that the PLL WAR is executed only + * after the STA is associated (or) if the + * beaconing had started in interfaces that + * uses beacons. + */ + if (!(sc->sc_flags & SC_OP_BEACONS)) + return; + if (AR_SREV_9485(sc->sc_ah)) { ath9k_ps_wakeup(sc); @@ -1443,15 +1452,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, } } - if ((ah->opmode == NL80211_IFTYPE_ADHOC) || - ((vif->type == NL80211_IFTYPE_ADHOC) && - sc->nvifs > 0)) { - ath_err(common, "Cannot create ADHOC interface when other" - " interfaces already exist.\n"); - ret = -EINVAL; - goto out; - } - ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); sc->nvifs++; @@ -1476,15 +1476,6 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); ath9k_ps_wakeup(sc); - /* See if new interface type is valid. */ - if ((new_type == NL80211_IFTYPE_ADHOC) && - (sc->nvifs > 1)) { - ath_err(common, "When using ADHOC, it must be the only" - " interface.\n"); - ret = -EINVAL; - goto out; - } - if (ath9k_uses_beacons(new_type) && !ath9k_uses_beacons(vif->type)) { if (sc->nbcnvifs >= ATH_BCBUF) { diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index e1fcc68124dc..0735aeb3b26c 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -695,9 +695,9 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, __skb_unlink(skb, &rx_edma->rx_fifo); list_add_tail(&bf->list, &sc->rx.rxbuf); ath_rx_edma_buf_link(sc, qtype); - } else { - bf = NULL; } + + bf = NULL; } *dest = bf; @@ -822,7 +822,8 @@ static bool ath9k_rx_accept(struct ath_common *common, * descriptor does contain a valid key index. This has been observed * mostly with CCMP encryption. */ - if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID) + if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID || + !test_bit(rx_stats->rs_keyix, common->ccmp_keymap)) rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS; if (!rx_stats->rs_datalen) { diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index d59dd01d6cde..4d571394c7a8 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -938,6 +938,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, struct ieee80211_tx_rate *rates; const struct ieee80211_rate *rate; struct ieee80211_hdr *hdr; + struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); int i; u8 rix = 0; @@ -948,18 +949,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, /* set dur_update_en for l-sig computation except for PS-Poll frames */ info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); - - /* - * We check if Short Preamble is needed for the CTS rate by - * checking the BSS's global flag. - * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. - */ - rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); - info->rtscts_rate = rate->hw_value; - - if (tx_info->control.vif && - tx_info->control.vif->bss_conf.use_short_preamble) - info->rtscts_rate |= rate->hw_value_short; + info->rtscts_rate = fi->rtscts_rate; for (i = 0; i < 4; i++) { bool is_40, is_sgi, is_sp; @@ -1001,13 +991,13 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, } /* legacy rates */ + rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; if ((tx_info->band == IEEE80211_BAND_2GHZ) && !(rate->flags & IEEE80211_RATE_ERP_G)) phy = WLAN_RC_PHY_CCK; else phy = WLAN_RC_PHY_OFDM; - rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; info->rates[i].Rate = rate->hw_value; if (rate->hw_value_short) { if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) @@ -1776,10 +1766,22 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + const struct ieee80211_rate *rate; struct ath_frame_info *fi = get_frame_info(skb); struct ath_node *an = NULL; enum ath9k_key_type keytype; + bool short_preamble = false; + + /* + * We check if Short Preamble is needed for the CTS rate by + * checking the BSS's global flag. + * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. + */ + if (tx_info->control.vif && + tx_info->control.vif->bss_conf.use_short_preamble) + short_preamble = true; + rate = ieee80211_get_rts_cts_rate(hw, tx_info); keytype = ath9k_cmn_get_hw_crypto_keytype(skb); if (sta) @@ -1794,6 +1796,9 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, fi->keyix = ATH9K_TXKEYIX_INVALID; fi->keytype = keytype; fi->framelen = framelen; + fi->rtscts_rate = rate->hw_value; + if (short_preamble) + fi->rtscts_rate |= rate->hw_value_short; } u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c index 0e81904956cf..5c54aa43ca2d 100644 --- a/drivers/net/wireless/ath/key.c +++ b/drivers/net/wireless/ath/key.c @@ -556,6 +556,9 @@ int ath_key_config(struct ath_common *common, return -EIO; set_bit(idx, common->keymap); + if (key->cipher == WLAN_CIPHER_SUITE_CCMP) + set_bit(idx, common->ccmp_keymap); + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { set_bit(idx + 64, common->keymap); set_bit(idx, common->tkip_keymap); @@ -582,6 +585,7 @@ void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) return; clear_bit(key->hw_key_idx, common->keymap); + clear_bit(key->hw_key_idx, common->ccmp_keymap); if (key->cipher != WLAN_CIPHER_SUITE_TKIP) return; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index acd03a4f9730..1b988f26bdf1 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -3767,7 +3767,7 @@ static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan) if (prev_status >= B43_STAT_STARTED) { err = b43_wireless_core_start(up_dev); if (err) { - b43err(wl, "Fatal: Coult not start device for " + b43err(wl, "Fatal: Could not start device for " "selected %s-GHz band\n", band_to_string(chan->band)); b43_wireless_core_exit(up_dev); diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index cd9c9bc186d9..eae691e2f7dd 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -2633,7 +2633,7 @@ static int b43legacy_switch_phymode(struct b43legacy_wl *wl, if (prev_status >= B43legacy_STAT_STARTED) { err = b43legacy_wireless_core_start(up_dev); if (err) { - b43legacyerr(wl, "Fatal: Coult not start device for " + b43legacyerr(wl, "Fatal: Could not start device for " "newly selected %s-PHY mode\n", phymode_to_string(new_mode)); b43legacy_wireless_core_exit(up_dev); diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index e7c157e5ebeb..7f97dec8534d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2239,6 +2239,7 @@ static ssize_t iwl_dbgfs_echo_test_write(struct file *file, return count; } +#ifdef CONFIG_IWLWIFI_DEBUG static ssize_t iwl_dbgfs_log_event_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -2276,6 +2277,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, return count; } +#endif static ssize_t iwl_dbgfs_calib_disabled_read(struct file *file, char __user *user_buf, @@ -2345,7 +2347,9 @@ DEBUGFS_READ_FILE_OPS(bt_traffic); DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); DEBUGFS_READ_FILE_OPS(reply_tx_error); DEBUGFS_WRITE_FILE_OPS(echo_test); +#ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_READ_WRITE_FILE_OPS(log_event); +#endif DEBUGFS_READ_WRITE_FILE_OPS(calib_disabled); /* @@ -2405,7 +2409,9 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); +#ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); +#endif if (iwl_advanced_bt_coexist(priv)) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 3ee23134c02b..013680332f07 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -796,6 +796,18 @@ int iwlagn_mac_sta_state(struct ieee80211_hw *hw, switch (op) { case ADD: ret = iwlagn_mac_sta_add(hw, vif, sta); + if (ret) + break; + /* + * Clear the in-progress flag, the AP station entry was added + * but we'll initialize LQ only when we've associated (which + * would also clear the in-progress flag). This is necessary + * in case we never initialize LQ because association fails. + */ + spin_lock_bh(&priv->sta_lock); + priv->stations[iwl_sta_id(sta)].used &= + ~IWL_STA_UCODE_INPROGRESS; + spin_unlock_bh(&priv->sta_lock); break; case REMOVE: ret = iwlagn_mac_sta_remove(hw, vif, sta); diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 9c44088054dd..900ee129e825 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -256,7 +256,8 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, else last_seq = priv->rx_seq[tid]; - if (last_seq >= new_node->start_win) + if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM && + last_seq >= new_node->start_win) new_node->start_win = last_seq + 1; new_node->win_size = win_size; @@ -596,5 +597,5 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); - memset(priv->rx_seq, 0, sizeof(priv->rx_seq)); + mwifiex_reset_11n_rx_seq_num(priv); } diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.h b/drivers/net/wireless/mwifiex/11n_rxreorder.h index f1bffebabc60..6c9815a0f5d8 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -37,6 +37,13 @@ #define ADDBA_RSP_STATUS_ACCEPT 0 +#define MWIFIEX_DEF_11N_RX_SEQ_NUM 0xffff + +static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) +{ + memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq)); +} + int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, u16 seqNum, u16 tid, u8 *ta, diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 015fec3371a0..ce61b6fae1c9 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1484,7 +1484,7 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev; if (!adapter) - return NULL; + return ERR_PTR(-EFAULT); switch (type) { case NL80211_IFTYPE_UNSPECIFIED: @@ -1494,12 +1494,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, if (priv->bss_mode) { wiphy_err(wiphy, "cannot create multiple sta/adhoc ifaces\n"); - return NULL; + return ERR_PTR(-EINVAL); } wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) - return NULL; + return ERR_PTR(-ENOMEM); wdev->wiphy = wiphy; priv->wdev = wdev; @@ -1522,12 +1522,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, if (priv->bss_mode) { wiphy_err(wiphy, "Can't create multiple AP interfaces"); - return NULL; + return ERR_PTR(-EINVAL); } wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) - return NULL; + return ERR_PTR(-ENOMEM); priv->wdev = wdev; wdev->wiphy = wiphy; @@ -1544,14 +1544,15 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, break; default: wiphy_err(wiphy, "type not supported\n"); - return NULL; + return ERR_PTR(-EINVAL); } dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name, ether_setup, 1); if (!dev) { wiphy_err(wiphy, "no memory available for netdevice\n"); - goto error; + priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; + return ERR_PTR(-ENOMEM); } mwifiex_init_priv_params(priv, dev); @@ -1582,7 +1583,9 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, /* Register network device */ if (register_netdevice(dev)) { wiphy_err(wiphy, "cannot register virtual network device\n"); - goto error; + free_netdev(dev); + priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; + return ERR_PTR(-EFAULT); } sema_init(&priv->async_sem, 1); @@ -1594,12 +1597,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, mwifiex_dev_debugfs_init(priv); #endif return dev; -error: - if (dev && (dev->reg_state == NETREG_UNREGISTERED)) - free_netdev(dev); - priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; - - return NULL; } EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c index ceb82cd749cc..383820a52beb 100644 --- a/drivers/net/wireless/mwifiex/ie.c +++ b/drivers/net/wireless/mwifiex/ie.c @@ -213,6 +213,7 @@ mwifiex_update_uap_custom_ie(struct mwifiex_private *priv, /* save assoc resp ie index after auto-indexing */ *assoc_idx = *((u16 *)pos); + kfree(ap_custom_ie); return ret; } diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index e0377473282f..fc8a9bfa1248 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -978,10 +978,10 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, dev_dbg(adapter->dev, "info: --- Rx: Event ---\n"); adapter->event_cause = *(u32 *) skb->data; - skb_pull(skb, MWIFIEX_EVENT_HEADER_LEN); - if ((skb->len > 0) && (skb->len < MAX_EVENT_SIZE)) - memcpy(adapter->event_body, skb->data, skb->len); + memcpy(adapter->event_body, + skb->data + MWIFIEX_EVENT_HEADER_LEN, + skb->len); /* event cause has been saved to adapter->event_cause */ adapter->event_received = true; diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 4ace5a3dcd23..11e731f3581c 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c @@ -406,9 +406,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; case EVENT_UAP_STA_ASSOC: - skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER); memset(&sinfo, 0, sizeof(sinfo)); - event = (struct mwifiex_assoc_event *)adapter->event_skb->data; + event = (struct mwifiex_assoc_event *) + (adapter->event_body + MWIFIEX_UAP_EVENT_EXTRA_HEADER); if (le16_to_cpu(event->type) == TLV_TYPE_UAP_MGMT_FRAME) { len = -1; @@ -433,9 +433,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) GFP_KERNEL); break; case EVENT_UAP_STA_DEAUTH: - skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER); - cfg80211_del_sta(priv->netdev, adapter->event_skb->data, - GFP_KERNEL); + cfg80211_del_sta(priv->netdev, adapter->event_body + + MWIFIEX_UAP_EVENT_EXTRA_HEADER, GFP_KERNEL); break; case EVENT_UAP_BSS_IDLE: priv->media_connected = false; diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index e2faec4db108..cecb27283196 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -161,15 +161,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, goto done; for (i = 0; i < adapter->priv_num; i++) { - tpriv = adapter->priv[i]; - if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) && - (tpriv->media_connected)) { - if (netif_queue_stopped(tpriv->netdev)) - mwifiex_wake_up_net_dev_queue(tpriv->netdev, - adapter); - } + if (tpriv->media_connected && + netif_queue_stopped(tpriv->netdev)) + mwifiex_wake_up_net_dev_queue(tpriv->netdev, adapter); } done: dev_kfree_skb_any(skb); diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c index 8173ab66066d..89f9a2a45de3 100644 --- a/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/drivers/net/wireless/mwifiex/uap_cmd.c @@ -27,6 +27,17 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, struct cfg80211_ap_settings *params) { int i; + if (!params->privacy) { + bss_config->protocol = PROTOCOL_NO_SECURITY; + bss_config->key_mgmt = KEY_MGMT_NONE; + bss_config->wpa_cfg.length = 0; + priv->sec_info.wep_enabled = 0; + priv->sec_info.wpa_enabled = 0; + priv->sec_info.wpa2_enabled = 0; + + return 0; + } + switch (params->auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: bss_config->auth_mode = WLAN_AUTH_OPEN; diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index 49ebf20c56eb..22a5916564b8 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c @@ -49,6 +49,7 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, struct device *dev = adapter->dev; u32 recv_type; __le32 tmp; + int ret; if (adapter->hs_activated) mwifiex_process_hs_config(adapter); @@ -69,16 +70,19 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, case MWIFIEX_USB_TYPE_CMD: if (skb->len > MWIFIEX_SIZE_OF_CMD_BUFFER) { dev_err(dev, "CMD: skb->len too large\n"); - return -1; + ret = -1; + goto exit_restore_skb; } else if (!adapter->curr_cmd) { dev_dbg(dev, "CMD: no curr_cmd\n"); if (adapter->ps_state == PS_STATE_SLEEP_CFM) { mwifiex_process_sleep_confirm_resp( adapter, skb->data, skb->len); - return 0; + ret = 0; + goto exit_restore_skb; } - return -1; + ret = -1; + goto exit_restore_skb; } adapter->curr_cmd->resp_skb = skb; @@ -87,20 +91,22 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, case MWIFIEX_USB_TYPE_EVENT: if (skb->len < sizeof(u32)) { dev_err(dev, "EVENT: skb->len too small\n"); - return -1; + ret = -1; + goto exit_restore_skb; } skb_copy_from_linear_data(skb, &tmp, sizeof(u32)); adapter->event_cause = le32_to_cpu(tmp); - skb_pull(skb, sizeof(u32)); dev_dbg(dev, "event_cause %#x\n", adapter->event_cause); if (skb->len > MAX_EVENT_SIZE) { dev_err(dev, "EVENT: event body too large\n"); - return -1; + ret = -1; + goto exit_restore_skb; } - skb_copy_from_linear_data(skb, adapter->event_body, - skb->len); + memcpy(adapter->event_body, skb->data + + MWIFIEX_EVENT_HEADER_LEN, skb->len); + adapter->event_received = true; adapter->event_skb = skb; break; @@ -124,6 +130,12 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, } return -EINPROGRESS; + +exit_restore_skb: + /* The buffer will be reused for further cmds/events */ + skb_push(skb, INTF_HEADER_LEN); + + return ret; } static void mwifiex_usb_rx_complete(struct urb *urb) diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index f3fc65515857..3fa4d4176993 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -404,6 +404,8 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; + mwifiex_reset_11n_rx_seq_num(priv); + atomic_set(&priv->wmm.tx_pkts_queued, 0); atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); } @@ -1221,6 +1223,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid) || + priv->wps.session_enable || ((priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set)) { diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 2e9e6af21362..dfcd02ab6cae 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -2110,7 +2110,7 @@ resize_buf: while (check_bssid_list_item(bssid, bssid_len, buf, len)) { if (rndis_bss_info_update(usbdev, bssid) && match_bssid && matched) { - if (!ether_addr_equal(bssid->mac, match_bssid)) + if (ether_addr_equal(bssid->mac, match_bssid)) *matched = true; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index d228358e6a40..9970c2b1b199 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -301,9 +301,11 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ + {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ + {RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/ /* HP - Lite-On ,8188CUS Slim Combo */ {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ @@ -346,6 +348,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/ {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ + {RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/ {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/ {RTL_USB_DEVICE(0x0e66, 0x0019, rtl92cu_hal_cfg)}, /*Hawking-Edimax*/ {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c index ad87a1ac6462..db6430c1a084 100644 --- a/drivers/net/wireless/ti/wl1251/acx.c +++ b/drivers/net/wireless/ti/wl1251/acx.c @@ -869,7 +869,7 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime) } *mactime = tsf_info->current_tsf_lsb | - (tsf_info->current_tsf_msb << 31); + ((u64)tsf_info->current_tsf_msb << 32); out: kfree(tsf_info); diff --git a/drivers/net/wireless/ti/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c index 9f15ccaf8f05..5ec50a476a69 100644 --- a/drivers/net/wireless/ti/wl1251/event.c +++ b/drivers/net/wireless/ti/wl1251/event.c @@ -76,8 +76,7 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) } } - if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && - wl->station_mode != STATION_ACTIVE_MODE) { + if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) { wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); /* indicate to the stack, that beacons have been lost */ diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c index 87f6305bda2c..567660cd2fcd 100644 --- a/drivers/net/wireless/ti/wl1251/spi.c +++ b/drivers/net/wireless/ti/wl1251/spi.c @@ -73,6 +73,8 @@ static void wl1251_spi_reset(struct wl1251 *wl) spi_sync(wl_to_spi(wl), &m); wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); + + kfree(cmd); } static void wl1251_spi_wake(struct wl1251 *wl) @@ -127,6 +129,8 @@ static void wl1251_spi_wake(struct wl1251 *wl) spi_sync(wl_to_spi(wl), &m); wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); + + kfree(cmd); } static void wl1251_spi_reset_wake(struct wl1251 *wl) diff --git a/drivers/net/wireless/ti/wlcore/Kconfig b/drivers/net/wireless/ti/wlcore/Kconfig index 54156b0b5c2d..d7b907e67170 100644 --- a/drivers/net/wireless/ti/wlcore/Kconfig +++ b/drivers/net/wireless/ti/wlcore/Kconfig @@ -1,7 +1,6 @@ config WLCORE tristate "TI wlcore support" depends on WL_TI && GENERIC_HARDIRQS && MAC80211 - depends on INET select FW_LOADER ---help--- This module contains the main code for TI WLAN chips. It abstracts diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 2027afe405fe..30899901aef5 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1935,14 +1935,14 @@ static int __devexit xennet_remove(struct xenbus_device *dev) dev_dbg(&dev->dev, "%s\n", dev->nodename); - unregister_netdev(info->netdev); - xennet_disconnect_backend(info); - del_timer_sync(&info->rx_refill_timer); - xennet_sysfs_delif(info->netdev); + unregister_netdev(info->netdev); + + del_timer_sync(&info->rx_refill_timer); + free_percpu(info->stats); free_netdev(info->netdev); diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 343ad29e211c..e44f8c2d239d 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; } @@ -462,4 +461,5 @@ int of_platform_populate(struct device_node *root, of_node_put(root); return rc; } +EXPORT_SYMBOL_GPL(of_platform_populate); #endif /* CONFIG_OF_ADDRESS */ diff --git a/drivers/oprofile/oprofile_perf.c b/drivers/oprofile/oprofile_perf.c index da14432806c6..efc4b7f308cf 100644 --- a/drivers/oprofile/oprofile_perf.c +++ b/drivers/oprofile/oprofile_perf.c @@ -25,7 +25,7 @@ static int oprofile_perf_enabled; static DEFINE_MUTEX(oprofile_perf_mutex); static struct op_counter_config *counter_config; -static struct perf_event **perf_events[nr_cpumask_bits]; +static struct perf_event **perf_events[NR_CPUS]; static int num_counters; /* diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index bf0cee629b60..099f46cd8e87 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 77cb54a65cde..447e83472c01 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 194b243a2817..2a7521677541 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/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c index afb50ee64598..4ba4636b6a4a 100644 --- a/drivers/pinctrl/pinctrl-mxs.c +++ b/drivers/pinctrl/pinctrl-mxs.c @@ -137,7 +137,7 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, free_group: if (!purecfg) - free(group); + kfree(group); free: kfree(new_map); return ret; diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index e8937e7e4999..3e7e47d6b385 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -1438,7 +1438,27 @@ static int nmk_pmx_enable(struct pinctrl_dev *pctldev, unsigned function, dev_dbg(npct->dev, "enable group %s, %u pins\n", g->name, g->npins); - /* Handle this special glitch on altfunction C */ + /* + * If we're setting altfunc C by setting both AFSLA and AFSLB to 1, + * we may pass through an undesired state. In this case we take + * some extra care. + * + * Safe sequence used to switch IOs between GPIO and Alternate-C mode: + * - Save SLPM registers (since we have a shadow register in the + * nmk_chip we're using that as backup) + * - Set SLPM=0 for the IOs you want to switch and others to 1 + * - Configure the GPIO registers for the IOs that are being switched + * - Set IOFORCE=1 + * - Modify the AFLSA/B registers for the IOs that are being switched + * - Set IOFORCE=0 + * - Restore SLPM registers + * - Any spurious wake up event during switch sequence to be ignored + * and cleared + * + * We REALLY need to save ALL slpm registers, because the external + * IOFORCE will switch *all* ports to their sleepmode setting to as + * to avoid glitches. (Not just one port!) + */ glitch = (g->altsetting == NMK_GPIO_ALT_C); if (glitch) { diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index 5ae50aadf885..b3f6b2873fdd 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * Inspired from: * - U300 Pinctl drivers diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h index 9155783bb47f..d950eb78d939 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.h +++ b/drivers/pinctrl/spear/pinctrl-spear.h @@ -2,7 +2,7 @@ * Driver header file for the ST Microelectronics SPEAr pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/pinctrl/spear/pinctrl-spear1310.c b/drivers/pinctrl/spear/pinctrl-spear1310.c index fff168be7f00..d6cca8c81b92 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1310.c +++ b/drivers/pinctrl/spear/pinctrl-spear1310.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr1310 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -2192,7 +2192,7 @@ static void __exit spear1310_pinctrl_exit(void) } module_exit(spear1310_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); +MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); MODULE_DESCRIPTION("ST Microelectronics SPEAr1310 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear1310_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c index a8ab2a6f51bf..a0eb057e55bd 100644 --- a/drivers/pinctrl/spear/pinctrl-spear1340.c +++ b/drivers/pinctrl/spear/pinctrl-spear1340.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr1340 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -1983,7 +1983,7 @@ static void __exit spear1340_pinctrl_exit(void) } module_exit(spear1340_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); +MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); MODULE_DESCRIPTION("ST Microelectronics SPEAr1340 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear1340_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear300.c b/drivers/pinctrl/spear/pinctrl-spear300.c index 9c82a35e4e78..4dfc2849b172 100644 --- a/drivers/pinctrl/spear/pinctrl-spear300.c +++ b/drivers/pinctrl/spear/pinctrl-spear300.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr300 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -702,7 +702,7 @@ static void __exit spear300_pinctrl_exit(void) } module_exit(spear300_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); +MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); MODULE_DESCRIPTION("ST Microelectronics SPEAr300 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear300_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear310.c b/drivers/pinctrl/spear/pinctrl-spear310.c index 1a9707605125..96883693fb7e 100644 --- a/drivers/pinctrl/spear/pinctrl-spear310.c +++ b/drivers/pinctrl/spear/pinctrl-spear310.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr310 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -425,7 +425,7 @@ static void __exit spear310_pinctrl_exit(void) } module_exit(spear310_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); +MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); MODULE_DESCRIPTION("ST Microelectronics SPEAr310 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, SPEAr310_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear320.c b/drivers/pinctrl/spear/pinctrl-spear320.c index de726e6c283a..020b1e0bdb3e 100644 --- a/drivers/pinctrl/spear/pinctrl-spear320.c +++ b/drivers/pinctrl/spear/pinctrl-spear320.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr320 pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -3462,7 +3462,7 @@ static void __exit spear320_pinctrl_exit(void) } module_exit(spear320_pinctrl_exit); -MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); +MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); MODULE_DESCRIPTION("ST Microelectronics SPEAr320 pinctrl driver"); MODULE_LICENSE("GPL v2"); MODULE_DEVICE_TABLE(of, spear320_pinctrl_of_match); diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.c b/drivers/pinctrl/spear/pinctrl-spear3xx.c index 91c883bc46a6..0242378f7cb8 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.c +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.c @@ -2,7 +2,7 @@ * Driver for the ST Microelectronics SPEAr3xx pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/pinctrl/spear/pinctrl-spear3xx.h b/drivers/pinctrl/spear/pinctrl-spear3xx.h index 5d5fdd8df7b8..31f44347f17c 100644 --- a/drivers/pinctrl/spear/pinctrl-spear3xx.h +++ b/drivers/pinctrl/spear/pinctrl-spear3xx.h @@ -2,7 +2,7 @@ * Header file for the ST Microelectronics SPEAr3xx pinmux * * Copyright (C) 2012 ST Microelectronics - * Viresh Kumar <viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index e1b8c54ace5a..a739f5ca936a 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -794,17 +794,17 @@ static __devinit int ab8500_regulator_register(struct platform_device *pdev, } static struct of_regulator_match ab8500_regulator_matches[] = { - { .name = "LDO-AUX1", .driver_data = (void *) AB8500_LDO_AUX1, }, - { .name = "LDO-AUX2", .driver_data = (void *) AB8500_LDO_AUX2, }, - { .name = "LDO-AUX3", .driver_data = (void *) AB8500_LDO_AUX3, }, - { .name = "LDO-INTCORE", .driver_data = (void *) AB8500_LDO_INTCORE, }, - { .name = "LDO-TVOUT", .driver_data = (void *) AB8500_LDO_TVOUT, }, - { .name = "LDO-USB", .driver_data = (void *) AB8500_LDO_USB, }, - { .name = "LDO-AUDIO", .driver_data = (void *) AB8500_LDO_AUDIO, }, - { .name = "LDO-ANAMIC1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, - { .name = "LDO-ANAMIC2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, - { .name = "LDO-DMIC", .driver_data = (void *) AB8500_LDO_DMIC, }, - { .name = "LDO-ANA", .driver_data = (void *) AB8500_LDO_ANA, }, + { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, }, + { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, }, + { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, }, + { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, }, + { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, }, + { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, }, + { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, }, + { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, }, + { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, + { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, }, + { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, }, }; static __devinit int diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 09a737c868b5..8b4b3829d9e7 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/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 968f97f3cb3d..9dbb491b6efa 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -452,26 +452,26 @@ static __devinit int db8500_regulator_register(struct platform_device *pdev, } static struct of_regulator_match db8500_regulator_matches[] = { - { .name = "db8500-vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, - { .name = "db8500-varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, - { .name = "db8500-vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, - { .name = "db8500-vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, - { .name = "db8500-vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, - { .name = "db8500-vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, - { .name = "db8500-vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, - { .name = "db8500-vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, - { .name = "db8500-sva-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, - { .name = "db8500-sva-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, - { .name = "db8500-sva-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, - { .name = "db8500-sia-mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, - { .name = "db8500-sia-mmdsp-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, - { .name = "db8500-sia-pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, - { .name = "db8500-sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, - { .name = "db8500-b2r2-mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, - { .name = "db8500-esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, - { .name = "db8500-esram12-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, - { .name = "db8500-esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, - { .name = "db8500-esram34-ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, + { .name = "db8500_vape", .driver_data = (void *) DB8500_REGULATOR_VAPE, }, + { .name = "db8500_varm", .driver_data = (void *) DB8500_REGULATOR_VARM, }, + { .name = "db8500_vmodem", .driver_data = (void *) DB8500_REGULATOR_VMODEM, }, + { .name = "db8500_vpll", .driver_data = (void *) DB8500_REGULATOR_VPLL, }, + { .name = "db8500_vsmps1", .driver_data = (void *) DB8500_REGULATOR_VSMPS1, }, + { .name = "db8500_vsmps2", .driver_data = (void *) DB8500_REGULATOR_VSMPS2, }, + { .name = "db8500_vsmps3", .driver_data = (void *) DB8500_REGULATOR_VSMPS3, }, + { .name = "db8500_vrf1", .driver_data = (void *) DB8500_REGULATOR_VRF1, }, + { .name = "db8500_sva_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSP, }, + { .name = "db8500_sva_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAMMDSPRET, }, + { .name = "db8500_sva_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SVAPIPE, }, + { .name = "db8500_sia_mmdsp", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSP, }, + { .name = "db8500_sia_mmdsp_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAMMDSPRET, }, + { .name = "db8500_sia_pipe", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SIAPIPE, }, + { .name = "db8500_sga", .driver_data = (void *) DB8500_REGULATOR_SWITCH_SGA, }, + { .name = "db8500_b2r2_mcde", .driver_data = (void *) DB8500_REGULATOR_SWITCH_B2R2_MCDE, }, + { .name = "db8500_esram12", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12, }, + { .name = "db8500_esram12_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM12RET, }, + { .name = "db8500_esram34", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34, }, + { .name = "db8500_esram34_ret", .driver_data = (void *) DB8500_REGULATOR_SWITCH_ESRAM34RET, }, }; static __devinit int diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 9b7ca90057d5..795f75a6ac33 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -673,7 +673,9 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].ops = &palmas_ops_smps10; pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL; pmic->desc[id].vsel_mask = SMPS10_VSEL; - pmic->desc[id].enable_reg = PALMAS_SMPS10_STATUS; + pmic->desc[id].enable_reg = + PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + PALMAS_SMPS10_STATUS); pmic->desc[id].enable_mask = SMPS10_BOOST_EN; } @@ -739,7 +741,8 @@ static __devinit int palmas_probe(struct platform_device *pdev) pmic->desc[id].type = REGULATOR_VOLTAGE; pmic->desc[id].owner = THIS_MODULE; - pmic->desc[id].enable_reg = palmas_regs_info[id].ctrl_addr; + pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + palmas_regs_info[id].ctrl_addr); pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; if (pdata && pdata->reg_data) diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 290d6fc01029..9caadb482178 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -451,7 +451,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, desc = reg_voltage_map[reg_id]; - if (old_sel < new_sel) + if ((old_sel < new_sel) && s5m8767->ramp_delay) return DIV_ROUND_UP(desc->step * (new_sel - old_sel), s5m8767->ramp_delay * 1000); return 0; diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index f841bd0db6aa..8f1be8586c72 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -71,7 +71,7 @@ /* LDO_CTRL bitfields */ #define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4) -#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x0F << ((ldo_id)*4)) +#define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0x07 << ((ldo_id)*4)) /* Number of step-down converters available */ #define TPS65023_NUM_DCDC 3 diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index b88b3df82381..1b299aacf22f 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c @@ -482,7 +482,7 @@ static int get_voltage_sel(struct regulator_dev *rdev) info = &supply_info[rdev_get_id(rdev)]; if (info->flags & FIXED_VOLTAGE) - return info->fixed_voltage; + return 0; ret = read_field(hw, &info->voltage); if (ret < 0) diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 24d880e78ec6..f8d818abf98c 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/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index 69425c4e86f3..de138e30d3e6 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c @@ -182,7 +182,7 @@ static int __devinit omap_rproc_probe(struct platform_device *pdev) ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); if (ret) { - dev_err(pdev->dev.parent, "dma_set_coherent_mask: %d\n", ret); + dev_err(&pdev->dev, "dma_set_coherent_mask: %d\n", ret); return ret; } diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 8ea7bccc7100..66324ee4678f 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -247,7 +247,7 @@ rproc_load_segments(struct rproc *rproc, const u8 *elf_data, size_t len) } if (offset + filesz > len) { - dev_err(dev, "truncated fw: need 0x%x avail 0x%x\n", + dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n", offset + filesz, len); ret = -EINVAL; break; @@ -934,7 +934,7 @@ static void rproc_resource_cleanup(struct rproc *rproc) unmapped = iommu_unmap(rproc->domain, entry->da, entry->len); if (unmapped != entry->len) { /* nothing much to do besides complaining */ - dev_err(dev, "failed to unmap %u/%u\n", entry->len, + dev_err(dev, "failed to unmap %u/%zu\n", entry->len, unmapped); } @@ -1020,7 +1020,7 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) ehdr = (struct elf32_hdr *)fw->data; - dev_info(dev, "Booting fw image %s, size %d\n", name, fw->size); + dev_info(dev, "Booting fw image %s, size %zd\n", name, fw->size); /* * if enabling an IOMMU isn't relevant for this rproc, this is @@ -1041,8 +1041,10 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) /* look for the resource table */ table = rproc_find_rsc_table(rproc, fw->data, fw->size, &tablesz); - if (!table) + if (!table) { + ret = -EINVAL; goto clean_up; + } /* handle fw resources which are required to boot rproc */ ret = rproc_handle_boot_rsc(rproc, table, tablesz); diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 75506ec2840e..39d3aa41adda 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 4bcf9ca2818a..370889d0489b 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 5e1d64ee5228..e3e50d69baf8 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 1f76320e545b..e2785479113c 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 258abeabf624..c5d06fe83bba 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 532d212b6b2c..393e7ce8e95a 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 0c53c28dc3d3..7e77cf620291 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 ece47e502282..86a12b48e477 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 f8d516b53161..621538b8b544 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 441d88ad99a7..d109cc3a17b6 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/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 6986552b47e6..77759c78cc21 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -3960,7 +3960,7 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha, { struct qla_hw_data *ha = vha->hw; struct qla_tgt *tgt = ha->tgt.qla_tgt; - int reason_code; + int login_code; ql_dbg(ql_dbg_tgt, vha, 0xe039, "scsi(%ld): ha state %d init_done %d oper_mode %d topo %d\n", @@ -4003,9 +4003,9 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha, { ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03b, "qla_target(%d): Async LOOP_UP occured " - "(m[1]=%x, m[2]=%x, m[3]=%x, m[4]=%x)", vha->vp_idx, - le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), - le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); + "(m[0]=%x, m[1]=%x, m[2]=%x, m[3]=%x)", vha->vp_idx, + le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]), + le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3])); if (tgt->link_reinit_iocb_pending) { qlt_send_notify_ack(vha, (void *)&tgt->link_reinit_iocb, 0, 0, 0, 0, 0, 0); @@ -4020,23 +4020,24 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha, case MBA_RSCN_UPDATE: ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03c, "qla_target(%d): Async event %#x occured " - "(m[1]=%x, m[2]=%x, m[3]=%x, m[4]=%x)", vha->vp_idx, code, - le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), - le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); + "(m[0]=%x, m[1]=%x, m[2]=%x, m[3]=%x)", vha->vp_idx, code, + le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]), + le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3])); break; case MBA_PORT_UPDATE: ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03d, "qla_target(%d): Port update async event %#x " - "occured: updating the ports database (m[1]=%x, m[2]=%x, " - "m[3]=%x, m[4]=%x)", vha->vp_idx, code, - le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), - le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); - reason_code = le16_to_cpu(mailbox[2]); - if (reason_code == 0x4) + "occured: updating the ports database (m[0]=%x, m[1]=%x, " + "m[2]=%x, m[3]=%x)", vha->vp_idx, code, + le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]), + le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3])); + + login_code = le16_to_cpu(mailbox[2]); + if (login_code == 0x4) ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03e, "Async MB 2: Got PLOGI Complete\n"); - else if (reason_code == 0x7) + else if (login_code == 0x7) ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03f, "Async MB 2: Port Logged Out\n"); break; @@ -4044,9 +4045,9 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha, default: ql_dbg(ql_dbg_tgt_mgt, vha, 0xf040, "qla_target(%d): Async event %#x occured: " - "ignore (m[1]=%x, m[2]=%x, m[3]=%x, m[4]=%x)", vha->vp_idx, - code, le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), - le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); + "ignore (m[0]=%x, m[1]=%x, m[2]=%x, m[3]=%x)", vha->vp_idx, + code, le16_to_cpu(mailbox[0]), le16_to_cpu(mailbox[1]), + le16_to_cpu(mailbox[2]), le16_to_cpu(mailbox[3])); break; } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 6f0a4c612b3b..6f72b80121a0 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1899,6 +1899,8 @@ static int sd_try_rc16_first(struct scsi_device *sdp) { if (sdp->host->max_cmd_len < 16) return 0; + if (sdp->try_rc_10_first) + return 0; if (sdp->scsi_level > SCSI_SPC_2) return 1; if (scsi_device_protection(sdp)) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 46ef5fe51db5..0c73dd4f43a0 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -801,7 +801,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) mcspi_dma = &mcspi->dma_channels[spi->chip_select]; if (!cs) { - cs = devm_kzalloc(&spi->dev , sizeof *cs, GFP_KERNEL); + cs = kzalloc(sizeof *cs, GFP_KERNEL); if (!cs) return -ENOMEM; cs->base = mcspi->base + spi->chip_select * 0x14; @@ -842,6 +842,7 @@ static void omap2_mcspi_cleanup(struct spi_device *spi) cs = spi->controller_state; list_del(&cs->node); + kfree(cs); } if (spi->chip_select < spi->master->num_chipselect) { diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 1c3d6386ea36..aeac1caba3f9 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -30,6 +30,7 @@ #include <linux/pci.h> #include <linux/usb.h> #include <linux/errno.h> +#include <linux/kconfig.h> #include <linux/kernel.h> #include <linux/sched.h> #include <linux/fcntl.h> @@ -981,6 +982,8 @@ void comedi_pci_driver_unregister(struct comedi_driver *comedi_driver, } EXPORT_SYMBOL_GPL(comedi_pci_driver_unregister); +#if IS_ENABLED(CONFIG_USB) + static int comedi_old_usb_auto_config(struct usb_interface *intf, struct comedi_driver *driver) { @@ -1043,3 +1046,5 @@ void comedi_usb_driver_unregister(struct comedi_driver *comedi_driver, comedi_driver_unregister(comedi_driver); } EXPORT_SYMBOL_GPL(comedi_usb_driver_unregister); + +#endif diff --git a/drivers/staging/gdm72xx/netlink_k.c b/drivers/staging/gdm72xx/netlink_k.c index 292af0f7f451..51665132c61b 100644 --- a/drivers/staging/gdm72xx/netlink_k.c +++ b/drivers/staging/gdm72xx/netlink_k.c @@ -104,7 +104,7 @@ struct sock *netlink_init(int unit, void (*cb)(struct net_device *dev, u16 type, void netlink_exit(struct sock *sock) { - sock_release(sock->sk_socket); + netlink_kernel_release(sock); } int netlink_send(struct sock *sock, int group, u16 type, void *msg, int len) diff --git a/drivers/staging/iio/Documentation/device.txt b/drivers/staging/iio/Documentation/device.txt index 0338c7cd0a8b..f03fbd3bb454 100644 --- a/drivers/staging/iio/Documentation/device.txt +++ b/drivers/staging/iio/Documentation/device.txt @@ -29,8 +29,6 @@ Then fill in the following: * info->driver_module: Set to THIS_MODULE. Used to ensure correct ownership of various resources allocate by the core. - * info->num_interrupt_lines: - Number of event triggering hardware lines the device has. * info->event_attrs: Attributes used to enable / disable hardware events. * info->attrs: diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 2490dd25093b..8f1b3af02f29 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -13,6 +13,7 @@ config AD7291 config AD7298 tristate "Analog Devices AD7298 ADC driver" depends on SPI + select IIO_KFIFO_BUF if IIO_BUFFER help Say yes here to build support for Analog Devices AD7298 8 Channel ADC with temperature sensor. diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index 10ab6dc823b9..a13afff2dfe6 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -235,7 +235,8 @@ static const struct attribute_group ad7606_attribute_group_range = { .indexed = 1, \ .channel = num, \ .address = num, \ - .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT, \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT, \ .scan_index = num, \ .scan_type = IIO_ST('s', 16, 16, 0), \ } diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c index 3295ea63f3eb..97ef67036e3f 100644 --- a/drivers/staging/media/lirc/lirc_serial.c +++ b/drivers/staging/media/lirc/lirc_serial.c @@ -129,6 +129,7 @@ static void send_space_homebrew(long length); static struct lirc_serial hardware[] = { [LIRC_HOMEBREW] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_HOMEBREW].lock), .signal_pin = UART_MSR_DCD, .signal_pin_change = UART_MSR_DDCD, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), @@ -145,6 +146,7 @@ static struct lirc_serial hardware[] = { }, [LIRC_IRDEO] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IRDEO].lock), .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = UART_MCR_OUT2, @@ -156,6 +158,7 @@ static struct lirc_serial hardware[] = { }, [LIRC_IRDEO_REMOTE] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IRDEO_REMOTE].lock), .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = (UART_MCR_RTS | UART_MCR_DTR | UART_MCR_OUT2), @@ -167,6 +170,7 @@ static struct lirc_serial hardware[] = { }, [LIRC_ANIMAX] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_ANIMAX].lock), .signal_pin = UART_MSR_DCD, .signal_pin_change = UART_MSR_DDCD, .on = 0, @@ -177,6 +181,7 @@ static struct lirc_serial hardware[] = { }, [LIRC_IGOR] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_IGOR].lock), .signal_pin = UART_MSR_DSR, .signal_pin_change = UART_MSR_DDSR, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), @@ -201,6 +206,7 @@ static struct lirc_serial hardware[] = { * See also http://www.nslu2-linux.org for this device */ [LIRC_NSLU2] = { + .lock = __SPIN_LOCK_UNLOCKED(hardware[LIRC_NSLU2].lock), .signal_pin = UART_MSR_CTS, .signal_pin_change = UART_MSR_DCTS, .on = (UART_MCR_RTS | UART_MCR_OUT2 | UART_MCR_DTR), diff --git a/drivers/staging/omapdrm/omap_fbdev.c b/drivers/staging/omapdrm/omap_fbdev.c index 11acd4c35ed2..8c6ed3b0c6f6 100644 --- a/drivers/staging/omapdrm/omap_fbdev.c +++ b/drivers/staging/omapdrm/omap_fbdev.c @@ -208,7 +208,8 @@ static int omap_fbdev_create(struct drm_fb_helper *helper, */ ret = omap_gem_get_paddr(fbdev->bo, &paddr, true); if (ret) { - dev_err(dev->dev, "could not map (paddr)!\n"); + dev_err(dev->dev, + "could not map (paddr)! Skipping framebuffer alloc\n"); ret = -ENOMEM; goto fail; } @@ -388,8 +389,11 @@ void omap_fbdev_free(struct drm_device *dev) fbi = helper->fbdev; - unregister_framebuffer(fbi); - framebuffer_release(fbi); + /* only cleanup framebuffer if it is present */ + if (fbi) { + unregister_framebuffer(fbi); + framebuffer_release(fbi); + } drm_fb_helper_fini(helper); diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index 9bd18e2d0513..69f616c6964e 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -102,6 +102,8 @@ static struct usb_device_id rtl871x_usb_id_tbl[] = { /* - */ {USB_DEVICE(0x20F4, 0x646B)}, {USB_DEVICE(0x083A, 0xC512)}, + {USB_DEVICE(0x25D4, 0x4CA1)}, + {USB_DEVICE(0x25D4, 0x4CAB)}, /* RTL8191SU */ /* Realtek */ diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index cb99da920068..87901fa74dd7 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c @@ -58,7 +58,8 @@ static struct ft_tport *ft_tport_create(struct fc_lport *lport) struct ft_tport *tport; int i; - tport = rcu_dereference(lport->prov[FC_TYPE_FCP]); + tport = rcu_dereference_protected(lport->prov[FC_TYPE_FCP], + lockdep_is_held(&ft_lport_lock)); if (tport && tport->tpg) return tport; diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c index ced26c8ccd57..0d2ea0c224c3 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/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 47d061b9ad4d..6e1958a325bd 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c @@ -3113,7 +3113,7 @@ static struct uart_8250_port *serial8250_find_match_or_unused(struct uart_port * /** * serial8250_register_8250_port - register a serial port - * @port: serial port template + * @up: serial port template * * Configure the serial port specified by the request. If the * port exists and is in use, it is hung up and unregistered diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index 4ad721fb8405..c17923ec6e95 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -133,6 +133,10 @@ struct pl011_dmatx_data { struct uart_amba_port { struct uart_port port; struct clk *clk; + /* Two optional pin states - default & sleep */ + struct pinctrl *pinctrl; + struct pinctrl_state *pins_default; + struct pinctrl_state *pins_sleep; const struct vendor_data *vendor; unsigned int dmacr; /* dma control reg */ unsigned int im; /* interrupt mask */ @@ -1312,6 +1316,14 @@ static int pl011_startup(struct uart_port *port) unsigned int cr; int retval; + /* Optionaly enable pins to be muxed in and configured */ + if (!IS_ERR(uap->pins_default)) { + retval = pinctrl_select_state(uap->pinctrl, uap->pins_default); + if (retval) + dev_err(port->dev, + "could not set default pins\n"); + } + retval = clk_prepare(uap->clk); if (retval) goto out; @@ -1420,6 +1432,7 @@ static void pl011_shutdown(struct uart_port *port) { struct uart_amba_port *uap = (struct uart_amba_port *)port; unsigned int cr; + int retval; /* * disable all interrupts @@ -1462,6 +1475,14 @@ static void pl011_shutdown(struct uart_port *port) */ clk_disable(uap->clk); clk_unprepare(uap->clk); + /* Optionally let pins go into sleep states */ + if (!IS_ERR(uap->pins_sleep)) { + retval = pinctrl_select_state(uap->pinctrl, uap->pins_sleep); + if (retval) + dev_err(port->dev, + "could not set pins to sleep state\n"); + } + if (uap->port.dev->platform_data) { struct amba_pl011_data *plat; @@ -1792,6 +1813,14 @@ static int __init pl011_console_setup(struct console *co, char *options) if (!uap) return -ENODEV; + /* Allow pins to be muxed in and configured */ + if (!IS_ERR(uap->pins_default)) { + ret = pinctrl_select_state(uap->pinctrl, uap->pins_default); + if (ret) + dev_err(uap->port.dev, + "could not set default pins\n"); + } + ret = clk_prepare(uap->clk); if (ret) return ret; @@ -1844,7 +1873,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) { struct uart_amba_port *uap; struct vendor_data *vendor = id->data; - struct pinctrl *pinctrl; void __iomem *base; int i, ret; @@ -1869,11 +1897,20 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) goto free; } - pinctrl = devm_pinctrl_get_select_default(&dev->dev); - if (IS_ERR(pinctrl)) { - ret = PTR_ERR(pinctrl); + uap->pinctrl = devm_pinctrl_get(&dev->dev); + if (IS_ERR(uap->pinctrl)) { + ret = PTR_ERR(uap->pinctrl); goto unmap; } + uap->pins_default = pinctrl_lookup_state(uap->pinctrl, + PINCTRL_STATE_DEFAULT); + if (IS_ERR(uap->pins_default)) + dev_err(&dev->dev, "could not get default pinstate\n"); + + uap->pins_sleep = pinctrl_lookup_state(uap->pinctrl, + PINCTRL_STATE_SLEEP); + if (IS_ERR(uap->pins_sleep)) + dev_dbg(&dev->dev, "could not get sleep pinstate\n"); uap->clk = clk_get(&dev->dev, NULL); if (IS_ERR(uap->clk)) { diff --git a/drivers/tty/serial/serial_txx9.c b/drivers/tty/serial/serial_txx9.c index 34bd345da775..6ae2a58d62f2 100644 --- a/drivers/tty/serial/serial_txx9.c +++ b/drivers/tty/serial/serial_txx9.c @@ -466,7 +466,7 @@ static void serial_txx9_break_ctl(struct uart_port *port, int break_state) spin_unlock_irqrestore(&up->port.lock, flags); } -#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || (CONFIG_CONSOLE_POLL) +#if defined(CONFIG_SERIAL_TXX9_CONSOLE) || defined(CONFIG_CONSOLE_POLL) /* * Wait for transmitter & holding register to empty */ diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index c691eea51537..f5ed3d75fa5a 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -46,7 +46,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/ obj-$(CONFIG_USB_SERIAL) += serial/ obj-$(CONFIG_USB) += misc/ -obj-$(CONFIG_USB) += phy/ +obj-$(CONFIG_USB_COMMON) += phy/ obj-$(CONFIG_EARLY_PRINTK_DBGP) += early/ obj-$(CONFIG_USB_ATM) += atm/ diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 8fd398dffced..ee469274a3fe 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 25a7422ee657..8fb484984c86 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/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 3df1a1973b05..ec70df7aba17 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1091,7 +1091,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, if (r == req) { /* wait until it is processed */ dwc3_stop_active_transfer(dwc, dep->number); - goto out0; + goto out1; } dev_err(dwc->dev, "request %p was not queued to %s\n", request, ep->name); @@ -1099,6 +1099,7 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep, goto out0; } +out1: /* giveback the request */ dwc3_gadget_giveback(dep, req, -ECONNRESET); diff --git a/drivers/usb/gadget/fsl_qe_udc.h b/drivers/usb/gadget/fsl_qe_udc.h index 4c07ca9cebf3..7026919fc901 100644 --- a/drivers/usb/gadget/fsl_qe_udc.h +++ b/drivers/usb/gadget/fsl_qe_udc.h @@ -153,10 +153,10 @@ struct usb_ep_para{ #define USB_BUSMODE_DTB 0x02 /* Endpoint basic handle */ -#define ep_index(EP) ((EP)->desc->bEndpointAddress & 0xF) +#define ep_index(EP) ((EP)->ep.desc->bEndpointAddress & 0xF) #define ep_maxpacket(EP) ((EP)->ep.maxpacket) #define ep_is_in(EP) ((ep_index(EP) == 0) ? (EP->udc->ep0_dir == \ - USB_DIR_IN) : ((EP)->desc->bEndpointAddress \ + USB_DIR_IN) : ((EP)->ep.desc->bEndpointAddress \ & USB_DIR_IN) == USB_DIR_IN) /* ep0 transfer state */ diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index 262acfd53e32..2ab0388d93eb 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -61,6 +61,7 @@ #include <mach/irqs.h> #include <mach/board.h> #ifdef CONFIG_USB_GADGET_DEBUG_FILES +#include <linux/debugfs.h> #include <linux/seq_file.h> #endif diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 17cfb8a1131c..c30435499a02 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 2732ef660c5c..7b01094d7993 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 23b4aefd1036..8275645889da 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 de3d6e3e57be..55c0785810c9 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/musb/musb_host.c b/drivers/usb/musb/musb_host.c index ef8d744800ac..e090c799d87b 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -375,11 +375,21 @@ static void musb_advance_schedule(struct musb *musb, struct urb *urb, */ if (list_empty(&qh->hep->urb_list)) { struct list_head *head; + struct dma_controller *dma = musb->dma_controller; - if (is_in) + if (is_in) { ep->rx_reinit = 1; - else + if (ep->rx_channel) { + dma->channel_release(ep->rx_channel); + ep->rx_channel = NULL; + } + } else { ep->tx_reinit = 1; + if (ep->tx_channel) { + dma->channel_release(ep->tx_channel); + ep->tx_channel = NULL; + } + } /* Clobber old pointers to this qh */ musb_ep_set_qh(ep, is_in, NULL); diff --git a/drivers/usb/otg/twl6030-usb.c b/drivers/usb/otg/twl6030-usb.c index d2a9a8e691b9..0eabb049b6a9 100644 --- a/drivers/usb/otg/twl6030-usb.c +++ b/drivers/usb/otg/twl6030-usb.c @@ -305,9 +305,8 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) regulator_enable(twl->usb3v3); twl->asleep = 1; - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, 0x1); - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, - 0x10); + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_CLR); + twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_SET); status = USB_EVENT_ID; otg->default_a = true; twl->phy.state = OTG_STATE_A_IDLE; @@ -316,12 +315,10 @@ static irqreturn_t twl6030_usbotg_irq(int irq, void *_twl) atomic_notifier_call_chain(&twl->phy.notifier, status, otg->gadget); } else { - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_CLR, - 0x10); - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, - 0x1); + twl6030_writeb(twl, TWL_MODULE_USB, 0x10, USB_ID_INT_EN_HI_CLR); + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); } - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_LATCH_CLR, status); + twl6030_writeb(twl, TWL_MODULE_USB, status, USB_ID_INT_LATCH_CLR); return IRQ_HANDLED; } @@ -343,7 +340,7 @@ static int twl6030_enable_irq(struct usb_phy *x) { struct twl6030_usb *twl = phy_to_twl(x); - twl6030_writeb(twl, TWL_MODULE_USB, USB_ID_INT_EN_HI_SET, 0x1); + twl6030_writeb(twl, TWL_MODULE_USB, 0x1, USB_ID_INT_EN_HI_SET); twl6030_interrupt_unmask(0x05, REG_INT_MSK_LINE_C); twl6030_interrupt_unmask(0x05, REG_INT_MSK_STS_C); diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig index 3cfabcba7447..e7cf84f0751a 100644 --- a/drivers/usb/phy/Kconfig +++ b/drivers/usb/phy/Kconfig @@ -2,11 +2,11 @@ # Physical Layer USB driver configuration # comment "USB Physical Layer drivers" - depends on USB + depends on USB || USB_GADGET config USB_ISP1301 tristate "NXP ISP1301 USB transceiver support" - depends on USB + depends on USB || USB_GADGET depends on I2C help Say Y here to add support for the NXP ISP1301 USB transceiver driver. diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 73d25cd8cba5..1e71079ce33b 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -93,6 +93,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ + { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */ { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */ { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ @@ -134,7 +135,13 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */ + { USB_DEVICE(0x166A, 0x0201) }, /* Clipsal 5500PACA C-Bus Pascal Automation Controller */ + { USB_DEVICE(0x166A, 0x0301) }, /* Clipsal 5800PC C-Bus Wireless PC Interface */ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ + { USB_DEVICE(0x166A, 0x0304) }, /* Clipsal 5000CT2 C-Bus Black and White Touchscreen */ + { USB_DEVICE(0x166A, 0x0305) }, /* Clipsal C-5000CT2 C-Bus Spectrum Colour Touchscreen */ + { USB_DEVICE(0x166A, 0x0401) }, /* Clipsal L51xx C-Bus Architectural Dimmer */ + { USB_DEVICE(0x166A, 0x0101) }, /* Clipsal 5560884 C-Bus Multi-room Audio Matrix Switcher */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ { USB_DEVICE(0x16DC, 0x0010) }, /* W-IE-NE-R Plein & Baus GmbH PL512 Power Supply */ { USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */ @@ -146,7 +153,11 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ + { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ + { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ + { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ + { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */ { } /* Terminating Entry */ }; diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index 81423f7361db..d47eb06fe463 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 e668a2460bd4..417ab1b0aa30 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -236,6 +236,7 @@ static void option_instat_callback(struct urb *urb); #define NOVATELWIRELESS_PRODUCT_G1 0xA001 #define NOVATELWIRELESS_PRODUCT_G1_M 0xA002 #define NOVATELWIRELESS_PRODUCT_G2 0xA010 +#define NOVATELWIRELESS_PRODUCT_MC551 0xB001 /* AMOI PRODUCTS */ #define AMOI_VENDOR_ID 0x1614 @@ -496,6 +497,19 @@ 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 +#define CELLIENT_PRODUCT_MEN200 0x9005 /* some devices interfaces need special handling due to a number of reasons */ enum option_blacklist_reason { @@ -549,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), }; @@ -734,6 +752,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G1_M) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) }, + /* Novatel Ovation MC551 a.k.a. Verizon USB551L */ + { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, @@ -1092,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) }, @@ -1233,6 +1255,18 @@ 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 */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index a324a5d21e99..11418da9bc09 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -202,6 +202,12 @@ static int slave_configure(struct scsi_device *sdev) if (us->fflags & US_FL_NO_READ_CAPACITY_16) sdev->no_read_capacity_16 = 1; + /* + * Many devices do not respond properly to READ_CAPACITY_16. + * Tell the SCSI layer to try READ_CAPACITY_10 first. + */ + sdev->try_rc_10_first = 1; + /* assume SPC3 or latter devices support sense size > 18 */ if (sdev->scsi_level > SCSI_SPC_2) us->fflags |= US_FL_SANE_SENSE; diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index caf22bf5f822..1719886bb9be 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1107,13 +1107,6 @@ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, USB_SC_RBC, USB_PR_BULK, NULL, 0 ), -/* Feiya QDI U2 DISK, reported by Hans de Goede <hdegoede@redhat.com> */ -UNUSUAL_DEV( 0x090c, 0x1000, 0x0000, 0xffff, - "Feiya", - "QDI U2 DISK", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_NO_READ_CAPACITY_16 ), - /* aeb */ UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, "Feiya", diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 94dbd25caa30..112156f68afb 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -191,7 +191,9 @@ static int vhost_worker(void *data) struct vhost_dev *dev = data; struct vhost_work *work = NULL; unsigned uninitialized_var(seq); + mm_segment_t oldfs = get_fs(); + set_fs(USER_DS); use_mm(dev->mm); for (;;) { @@ -229,6 +231,7 @@ static int vhost_worker(void *data) } unuse_mm(dev->mm); + set_fs(oldfs); return 0; } diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 5066eee10ccf..58bd9c27369d 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 4749ac356469..397d4eee11bb 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 ca8382d346e9..14ce8cc079e3 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 770632359a17..d2b57197b292 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 8195c7166d20..26a2430a7028 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 3d8c206e90e5..7985fa12b9b4 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 2b8973931ff4..3907c8b6ecbc 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 bfbc15ca38dd..0908e6044333 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; diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 2b763815aeec..1eff743ec497 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c @@ -146,7 +146,7 @@ struct cmn_registers { } __attribute__((packed)); static unsigned int hpwdt_nmi_decoding; -static unsigned int allow_kdump; +static unsigned int allow_kdump = 1; static unsigned int is_icru; static DEFINE_SPINLOCK(rom_lock); static void *cru_rom_addr; @@ -756,6 +756,8 @@ error: static void hpwdt_exit_nmi_decoding(void) { unregister_nmi_handler(NMI_UNKNOWN, "hpwdt"); + unregister_nmi_handler(NMI_SERR, "hpwdt"); + unregister_nmi_handler(NMI_IO_CHECK, "hpwdt"); if (cru_rom_addr) iounmap(cru_rom_addr); } diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index bc47e9012f37..9c2c27c3b424 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -699,3 +699,4 @@ MODULE_DESCRIPTION("Intel TCO WatchDog Timer Driver"); MODULE_VERSION(DRV_VERSION); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); +MODULE_ALIAS("platform:" DRV_NAME); diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index afcd13676542..e4841c36798b 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c @@ -4,7 +4,7 @@ * Watchdog driver for ARM SP805 watchdog module * * Copyright (C) 2010 ST Microelectronics - * Viresh Kumar<viresh.kumar@st.com> + * Viresh Kumar <viresh.linux@gmail.com> * * This file is licensed under the terms of the GNU General Public * License version 2 or later. This program is licensed "as is" without any @@ -331,6 +331,6 @@ static struct amba_driver sp805_wdt_driver = { module_amba_driver(sp805_wdt_driver); -MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); +MODULE_AUTHOR("Viresh Kumar <viresh.linux@gmail.com>"); MODULE_DESCRIPTION("ARM SP805 Watchdog Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 672d169bf1da..ef8edecfc526 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -349,7 +349,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, sizeof(struct watchdog_info)) ? -EFAULT : 0; case WDIOC_GETSTATUS: err = watchdog_get_status(wdd, &val); - if (err) + if (err == -ENODEV) return err; return put_user(val, p); case WDIOC_GETBOOTSTATUS: |