From 4e38b745af76cdd93bca33258e1e33a23458f92c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 31 Oct 2012 16:07:43 +0800 Subject: ASoC: si476x: Add missing break for SNDRV_PCM_FORMAT_S8 switch case Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/codecs/si476x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index f2d61a187830..566ea3256e2d 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c @@ -159,6 +159,7 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream, switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: width = SI476X_PCM_FORMAT_S8; + break; case SNDRV_PCM_FORMAT_S16_LE: width = SI476X_PCM_FORMAT_S16_LE; break; -- cgit v1.2.3-55-g7522 From 85dfb745ee40232876663ae206cba35f24ab2a40 Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Mon, 18 Feb 2013 16:24:20 +0100 Subject: af_key: initialize satype in key_notify_policy_flush() This field was left uninitialized. Some user daemons perform check against this field. Signed-off-by: Nicolas Dichtel Signed-off-by: Steffen Klassert --- net/key/af_key.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/key/af_key.c b/net/key/af_key.c index 9ef79851f297..d5a4a796f025 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -2694,6 +2694,7 @@ static int key_notify_policy_flush(const struct km_event *c) hdr->sadb_msg_pid = c->portid; hdr->sadb_msg_version = PF_KEY_V2; hdr->sadb_msg_errno = (uint8_t) 0; + hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; hdr->sadb_msg_len = (sizeof(struct sadb_msg) / sizeof(uint64_t)); pfkey_broadcast(skb_out, GFP_ATOMIC, BROADCAST_ALL, NULL, c->net); return 0; -- cgit v1.2.3-55-g7522 From 75da01e127f7db3b23effa6118336d303e7572a7 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Thu, 31 Jan 2013 11:25:52 +0000 Subject: ARM: KVM: vgic: force EOIed LRs to the empty state The VGIC doesn't guarantee that an EOIed LR that has been configured to generate a maintenance interrupt will appear as empty. While the code recovers from this situation, it is better to clean the LR and flag it as empty so it can be quickly recycled. Signed-off-by: Marc Zyngier --- arch/arm/kvm/vgic.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c index c9a17316e9fe..76ea1aa5e7d2 100644 --- a/arch/arm/kvm/vgic.c +++ b/arch/arm/kvm/vgic.c @@ -883,8 +883,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) lr, irq, vgic_cpu->vgic_lr[lr]); BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); vgic_cpu->vgic_lr[lr] |= GICH_LR_PENDING_BIT; - - goto out; + return true; } /* Try to use another LR for this interrupt */ @@ -898,7 +897,6 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) vgic_cpu->vgic_irq_lr_map[irq] = lr; set_bit(lr, vgic_cpu->lr_used); -out: if (!vgic_irq_is_edge(vcpu, irq)) vgic_cpu->vgic_lr[lr] |= GICH_LR_EOI; @@ -1054,6 +1052,13 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) } else { vgic_cpu_irq_clear(vcpu, irq); } + + /* + * Despite being EOIed, the LR may not have + * been marked as empty. + */ + set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr); + vgic_cpu->vgic_lr[lr] &= ~GICH_LR_ACTIVE_BIT; } } -- cgit v1.2.3-55-g7522 From 33c83cb3c1d84b76c8270abe5487e77f83a81b22 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 1 Feb 2013 18:28:30 +0000 Subject: ARM: KVM: vgic: take distributor lock on sync_hwstate path Now that the maintenance interrupt handling is actually out of the handler itself, the code becomes quite racy as we can get preempted while we process the state. Wrapping this code around the distributor lock ensures that we're not preempted and relatively race-free. Signed-off-by: Marc Zyngier --- arch/arm/kvm/vgic.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/arch/arm/kvm/vgic.c b/arch/arm/kvm/vgic.c index 76ea1aa5e7d2..0e4cfe123b38 100644 --- a/arch/arm/kvm/vgic.c +++ b/arch/arm/kvm/vgic.c @@ -1016,21 +1016,6 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) kvm_debug("MISR = %08x\n", vgic_cpu->vgic_misr); - /* - * We do not need to take the distributor lock here, since the only - * action we perform is clearing the irq_active_bit for an EOIed - * level interrupt. There is a potential race with - * the queuing of an interrupt in __kvm_vgic_flush_hwstate(), where we - * check if the interrupt is already active. Two possibilities: - * - * - The queuing is occurring on the same vcpu: cannot happen, - * as we're already in the context of this vcpu, and - * executing the handler - * - The interrupt has been migrated to another vcpu, and we - * ignore this interrupt for this run. Big deal. It is still - * pending though, and will get considered when this vcpu - * exits. - */ if (vgic_cpu->vgic_misr & GICH_MISR_EOI) { /* * Some level interrupts have been EOIed. Clear their @@ -1069,9 +1054,8 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) } /* - * Sync back the VGIC state after a guest run. We do not really touch - * the distributor here (the irq_pending_on_cpu bit is safe to set), - * so there is no need for taking its lock. + * Sync back the VGIC state after a guest run. The distributor lock is + * needed so we don't get preempted in the middle of the state processing. */ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) { @@ -1117,10 +1101,14 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) { + struct vgic_dist *dist = &vcpu->kvm->arch.vgic; + if (!irqchip_in_kernel(vcpu->kvm)) return; + spin_lock(&dist->lock); __kvm_vgic_sync_hwstate(vcpu); + spin_unlock(&dist->lock); } int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu) -- cgit v1.2.3-55-g7522 From 8af294b472067e9034fe288d912455cc0961d1b9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 22 Feb 2013 17:48:15 +0000 Subject: ASoC: dapm: Fix handling of loops Currently if a path loops back on itself we correctly skip over it to avoid going into an infinite loop but this causes us to ignore the need to power up the path as we don't count the loop for the purposes of counting inputs and outputs. This means that internal loopbacks within a device that have powered devices on them won't be powered up. Fix this by treating any path that is currently in the process of being recursed as having a single input or output so that it is counted for the purposes of power decisions. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/soc-dapm.h | 1 + sound/soc/soc-dapm.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index e1ef63d4a5c4..44a30b108683 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -488,6 +488,7 @@ struct snd_soc_dapm_path { /* status */ u32 connect:1; /* source and sink widgets are connected */ u32 walked:1; /* path has been walked */ + u32 walking:1; /* path is in the process of being walked */ u32 weak:1; /* path ignored for power management */ int (*connected)(struct snd_soc_dapm_widget *source, diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 258acadb9e7d..f3255517de79 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -821,6 +821,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources))) { widget->outputs = snd_soc_dapm_suspend_check(widget); + path->walking = 0; return widget->outputs; } } @@ -831,6 +832,9 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, if (path->weak) continue; + if (path->walking) + return 1; + if (path->walked) continue; @@ -838,6 +842,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, if (path->sink && path->connect) { path->walked = 1; + path->walking = 1; /* do we need to add this widget to the list ? */ if (list) { @@ -847,11 +852,14 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, dev_err(widget->dapm->dev, "ASoC: could not add widget %s\n", widget->name); + path->walking = 0; return con; } } con += is_connected_output_ep(path->sink, list); + + path->walking = 0; } } @@ -931,6 +939,9 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, if (path->weak) continue; + if (path->walking) + return 1; + if (path->walked) continue; @@ -938,6 +949,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, if (path->source && path->connect) { path->walked = 1; + path->walking = 1; /* do we need to add this widget to the list ? */ if (list) { @@ -947,11 +959,14 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget, dev_err(widget->dapm->dev, "ASoC: could not add widget %s\n", widget->name); + path->walking = 0; return con; } } con += is_connected_input_ep(path->source, list); + + path->walking = 0; } } -- cgit v1.2.3-55-g7522 From 27a737ff7cb062fb9cbceba9b44d60aa74862bfa Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 6 Mar 2013 23:17:08 +0100 Subject: mac80211: always synchronize_net() during station removal If there are keys left during station removal, then a synchronize_net() will be done (for each key, I have a patch to address this for 3.10), otherwise it won't be done at all which causes issues because the station could be used for TX while it's being removed from the driver -- that might confuse the driver. Fix this by always doing synchronize_net() if no key was present any more. Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg --- net/mac80211/sta_info.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index a79ce820cb50..238a0cca320e 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -766,6 +766,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta) struct ieee80211_local *local; struct ieee80211_sub_if_data *sdata; int ret, i; + bool have_key = false; might_sleep(); @@ -793,12 +794,19 @@ int __must_check __sta_info_destroy(struct sta_info *sta) list_del_rcu(&sta->list); mutex_lock(&local->key_mtx); - for (i = 0; i < NUM_DEFAULT_KEYS; i++) + for (i = 0; i < NUM_DEFAULT_KEYS; i++) { __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i])); - if (sta->ptk) + have_key = true; + } + if (sta->ptk) { __ieee80211_key_free(key_mtx_dereference(local, sta->ptk)); + have_key = true; + } mutex_unlock(&local->key_mtx); + if (!have_key) + synchronize_net(); + sta->dead = true; local->num_sta--; -- cgit v1.2.3-55-g7522 From 021fcdc13acbab78589325ae2db0b384b4ee7222 Mon Sep 17 00:00:00 2001 From: Vladimir Kondratiev Date: Thu, 7 Mar 2013 11:08:29 +0200 Subject: cfg80211: fix inconsistency in trace for rdev_set_mac_acl There is NETDEV_ENTRY that was incorrectly assigned as WIPHY_ASSIGN, fix it. Signed-off-by: Vladimir Kondratiev Signed-off-by: Johannes Berg --- net/wireless/trace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/wireless/trace.h b/net/wireless/trace.h index b7a531380e19..6847d043edea 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -1778,7 +1778,7 @@ TRACE_EVENT(rdev_set_mac_acl, ), TP_fast_assign( WIPHY_ASSIGN; - WIPHY_ASSIGN; + NETDEV_ASSIGN; __entry->acl_policy = params->acl_policy; ), TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", acl policy: %d", -- cgit v1.2.3-55-g7522 From 1345ee6a6d90813f972379fad8b75f17026fc8b2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 6 Mar 2013 10:31:05 +0100 Subject: cfg80211: fix potential BSS memory leak and update In the odd case that while updating information from a beacon, a BSS was found that is part of a hidden group, we drop the new information. In this case, however, we leak the IE buffer from the update, and erroneously update the entry's timestamp so it will never time out. Fix both these issues. Cc: Larry Finger Signed-off-by: Johannes Berg --- net/wireless/scan.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 674aadca0079..e93bd31d23bb 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -698,11 +698,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, found = rb_find_bss(dev, tmp, BSS_CMP_REGULAR); if (found) { - found->pub.beacon_interval = tmp->pub.beacon_interval; - found->pub.signal = tmp->pub.signal; - found->pub.capability = tmp->pub.capability; - found->ts = tmp->ts; - /* Update IEs */ if (rcu_access_pointer(tmp->pub.proberesp_ies)) { const struct cfg80211_bss_ies *old; @@ -723,6 +718,8 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, if (found->pub.hidden_beacon_bss && !list_empty(&found->hidden_list)) { + const struct cfg80211_bss_ies *f; + /* * The found BSS struct is one of the probe * response members of a group, but we're @@ -732,6 +729,10 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, * SSID to showing it, which is confusing so * drop this information. */ + + f = rcu_access_pointer(tmp->pub.beacon_ies); + kfree_rcu((struct cfg80211_bss_ies *)f, + rcu_head); goto drop; } @@ -761,6 +762,11 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head); } + + found->pub.beacon_interval = tmp->pub.beacon_interval; + found->pub.signal = tmp->pub.signal; + found->pub.capability = tmp->pub.capability; + found->ts = tmp->ts; } else { struct cfg80211_internal_bss *new; struct cfg80211_internal_bss *hidden; -- cgit v1.2.3-55-g7522 From 07e5a5f5ab7474589c15fc5d88e4f7fc43979530 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 7 Mar 2013 13:22:05 +0100 Subject: mac80211: fix crash with P2P Device returning action frames If a P2P Device interface receives an unhandled action frame, we attempt to return it. This crashes because it doesn't have a channel context. Fix the crash by using status->band and properly mark the return frame as an off-channel frame. Reported-by: Ilan Peer Reviewed-by: Ilan Peer Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index bb73ed2d20b9..c6844ad080be 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2675,7 +2675,19 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) memset(nskb->cb, 0, sizeof(nskb->cb)); - ieee80211_tx_skb(rx->sdata, nskb); + if (rx->sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) { + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(nskb); + + info->flags = IEEE80211_TX_CTL_TX_OFFCHAN | + IEEE80211_TX_INTFL_OFFCHAN_TX_OK | + IEEE80211_TX_CTL_NO_CCK_RATE; + if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) + info->hw_queue = + local->hw.offchannel_tx_hw_queue; + } + + __ieee80211_tx_skb_tid_band(rx->sdata, nskb, 7, + status->band); } dev_kfree_skb(rx->skb); return RX_QUEUED; -- cgit v1.2.3-55-g7522 From 63981a4096081f3a35351f56fa89e91f493c02c7 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 22 Jan 2013 10:58:21 +0100 Subject: MIPS: compat: Return same error ENOSYS as native for invalid operation. The pains for multiplexed syscalls. Noticed by Al Viro . Signed-off-by: Ralf Baechle --- arch/mips/kernel/linux32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 8eeee1c860c0..db9655f08892 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -171,7 +171,7 @@ SYSCALL_DEFINE6(32_ipc, u32, call, long, first, long, second, long, third, err = compat_sys_shmctl(first, second, compat_ptr(ptr)); break; default: - err = -EINVAL; + err = -ENOSYS; break; } -- cgit v1.2.3-55-g7522 From e744109fce4b9581acdc23287667e240bcd239b7 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Sun, 3 Mar 2013 11:39:35 +0000 Subject: MIPS: Use CONFIG_CPU_MIPSR2 in csum_partial.S The csum_partial implementation contain optimalizations for the MIPS R2 instruction set. This optimization is never enabled however because the if directive uses the CPU_MIPSR2 constant which is not defined anywhere. Use the CONFIG_CPU_MIPSR2 constant instead. Signed-off-by: Gabor Juhos Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/4971/ Signed-off-by: Ralf Baechle --- arch/mips/lib/csum_partial.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S index 507147aebd41..a6adffbb4e5f 100644 --- a/arch/mips/lib/csum_partial.S +++ b/arch/mips/lib/csum_partial.S @@ -270,7 +270,7 @@ LEAF(csum_partial) #endif /* odd buffer alignment? */ -#ifdef CPU_MIPSR2 +#ifdef CONFIG_CPU_MIPSR2 wsbh v1, sum movn sum, v1, t7 #else @@ -670,7 +670,7 @@ EXC( sb t0, NBYTES-2(dst), .Ls_exc) addu sum, v1 #endif -#ifdef CPU_MIPSR2 +#ifdef CONFIG_CPU_MIPSR2 wsbh v1, sum movn sum, v1, odd #else -- cgit v1.2.3-55-g7522 From 0c81157b46c533139d6be721d41617020c59a2c3 Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 26 Feb 2013 14:35:23 -0800 Subject: MIPS: Fix logic errors in bitops.c commit 92d11594f6 (MIPS: Remove irqflags.h dependency from bitops.h) factored some of the bitops code out into a separate file (arch/mips/lib/bitops.c). Unfortunately the logic converting a bit mask into a boolean result was lost in some of the functions. We had: int res; unsigned long shifted_result_bit; . . . res = shifted_result_bit; return res; Which truncates off the high 32 bits (thus yielding an incorrect value) on 64-bit systems. The manifestation of this is that a non-SMP 64-bit kernel will not boot as the bitmap operations in bootmem.c are all screwed up. Signed-off-by: David Daney Cc: linux-mips@linux-mips.org Cc: Jim Quinlan Cc: stable@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/4965/ Signed-off-by: Ralf Baechle --- arch/mips/lib/bitops.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/mips/lib/bitops.c b/arch/mips/lib/bitops.c index 81f1dcfdcab8..a64daee740ee 100644 --- a/arch/mips/lib/bitops.c +++ b/arch/mips/lib/bitops.c @@ -90,12 +90,12 @@ int __mips_test_and_set_bit(unsigned long nr, unsigned bit = nr & SZLONG_MASK; unsigned long mask; unsigned long flags; - unsigned long res; + int res; a += nr >> SZLONG_LOG; mask = 1UL << bit; raw_local_irq_save(flags); - res = (mask & *a); + res = (mask & *a) != 0; *a |= mask; raw_local_irq_restore(flags); return res; @@ -116,12 +116,12 @@ int __mips_test_and_set_bit_lock(unsigned long nr, unsigned bit = nr & SZLONG_MASK; unsigned long mask; unsigned long flags; - unsigned long res; + int res; a += nr >> SZLONG_LOG; mask = 1UL << bit; raw_local_irq_save(flags); - res = (mask & *a); + res = (mask & *a) != 0; *a |= mask; raw_local_irq_restore(flags); return res; @@ -141,12 +141,12 @@ int __mips_test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) unsigned bit = nr & SZLONG_MASK; unsigned long mask; unsigned long flags; - unsigned long res; + int res; a += nr >> SZLONG_LOG; mask = 1UL << bit; raw_local_irq_save(flags); - res = (mask & *a); + res = (mask & *a) != 0; *a &= ~mask; raw_local_irq_restore(flags); return res; @@ -166,12 +166,12 @@ int __mips_test_and_change_bit(unsigned long nr, volatile unsigned long *addr) unsigned bit = nr & SZLONG_MASK; unsigned long mask; unsigned long flags; - unsigned long res; + int res; a += nr >> SZLONG_LOG; mask = 1UL << bit; raw_local_irq_save(flags); - res = (mask & *a); + res = (mask & *a) != 0; *a ^= mask; raw_local_irq_restore(flags); return res; -- cgit v1.2.3-55-g7522 From 9f91e5064c6c24d6ccd760a6b6120de4560d9829 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Thu, 21 Feb 2013 15:38:19 +0900 Subject: MIPS: VR4133: Fix probe for LL/SC. Signed-off-by: Yoichi Yuasa Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/4963/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-probe.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 6bfccc227a95..d069a19112e8 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -580,6 +580,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) c->tlbsize = 48; break; case PRID_IMP_VR41XX: + set_isa(c, MIPS_CPU_ISA_III); + c->options = R4K_OPTS; + c->tlbsize = 32; switch (c->processor_id & 0xf0) { case PRID_REV_VR4111: c->cputype = CPU_VR4111; @@ -604,6 +607,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) __cpu_name[cpu] = "NEC VR4131"; } else { c->cputype = CPU_VR4133; + c->options |= MIPS_CPU_LLSC; __cpu_name[cpu] = "NEC VR4133"; } break; @@ -613,9 +617,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) __cpu_name[cpu] = "NEC Vr41xx"; break; } - set_isa(c, MIPS_CPU_ISA_III); - c->options = R4K_OPTS; - c->tlbsize = 32; break; case PRID_IMP_R4300: c->cputype = CPU_R4300; -- cgit v1.2.3-55-g7522 From 383c97b4587665d47d08dff37ec85b44be760505 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 4 Mar 2013 04:17:21 +0000 Subject: MIPS: Add dependencies for HAVE_ARCH_TRANSPARENT_HUGEPAGE The MIPS implementation of transparent huge-pages (THP) is 64-bit only, and of course also requires that the CPU supports huge-pages. Currently it's entirely possible to enable THP in other configurations, which then fail to build due to pfn_pmd() not being defined. Signed-off-by: Ben Hutchings Cc: linux-mips@linux-mips.org Acked-by: David Daney Patchwork: https://patchwork.linux-mips.org/patch/4972/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index ae9c716c46bb..e8e10b794b87 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -18,7 +18,7 @@ config MIPS select HAVE_KRETPROBES select HAVE_DEBUG_KMEMLEAK select ARCH_BINFMT_ELF_RANDOMIZE_PIE - select HAVE_ARCH_TRANSPARENT_HUGEPAGE + select HAVE_ARCH_TRANSPARENT_HUGEPAGE if CPU_SUPPORTS_HUGEPAGES && 64BIT select RTC_LIB if !MACH_LOONGSON select GENERIC_ATOMIC64 if !64BIT select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE -- cgit v1.2.3-55-g7522 From 631b0af98c1efb160f02154743ae9f13fe03e347 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 5 Mar 2013 13:20:20 +0100 Subject: MIPS: Get rid of CONFIG_CPU_HAS_LLSC again Commit f7ade3c168e4f437c11f57be012992bbb0e3075c ("MIPS: Get rid of CONFIG_CPU_HAS_LLSC") did what it promised to do. But since then that macro and its Kconfig symbol popped up again. Get rid of those again. Signed-off-by: Paul Bolle Cc: Jonas Gorski Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/4978/ Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 1 - arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h | 4 ---- 2 files changed, 5 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e8e10b794b87..1a166d98773e 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1493,7 +1493,6 @@ config CPU_XLP select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM - select CPU_HAS_LLSC select WEAK_ORDERING select WEAK_REORDERING_BEYOND_LLSC select CPU_HAS_PREFETCH diff --git a/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h b/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h index d9c828419037..b40f37fb3dee 100644 --- a/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h @@ -28,11 +28,7 @@ /* #define cpu_has_prefetch ? */ #define cpu_has_mcheck 1 /* #define cpu_has_ejtag ? */ -#ifdef CONFIG_CPU_HAS_LLSC -#define cpu_has_llsc 1 -#else #define cpu_has_llsc 0 -#endif /* #define cpu_has_vtag_icache ? */ /* #define cpu_has_dc_aliases ? */ /* #define cpu_has_ic_fills_f_dc ? */ -- cgit v1.2.3-55-g7522 From f4cdb6a00c148e7724ada0998643b293a52b5f62 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 12 Mar 2013 16:06:07 +0100 Subject: MIPS: SEAD3: Enable LL/SC. All synthesizable CPU cores that could be loaded into a SEAD3's FPGA are MIPS32 or MIPS64 CPUs that have ll/sc. Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h b/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h index b40f37fb3dee..193c0912d38e 100644 --- a/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-sead3/cpu-feature-overrides.h @@ -28,7 +28,7 @@ /* #define cpu_has_prefetch ? */ #define cpu_has_mcheck 1 /* #define cpu_has_ejtag ? */ -#define cpu_has_llsc 0 +#define cpu_has_llsc 1 /* #define cpu_has_vtag_icache ? */ /* #define cpu_has_dc_aliases ? */ /* #define cpu_has_ic_fills_f_dc ? */ -- cgit v1.2.3-55-g7522 From c6432ea9cc043994d5b7dcb3ad86a087777cb40c Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 11 Mar 2013 17:27:02 +0000 Subject: regmap: Initialize `map->debugfs' before regcache In the rbtree code we are exposing statistics relating to the number of nodes/registers of the rbtree cache for each of the devices. Ensure that `map->debugfs' has been initialized before we attempt to initialize the debugfs entry for the rbtree cache. Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/base/regmap/regmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 3d2367501fd0..50ef277ea4b6 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -710,12 +710,12 @@ skip_format_initialization: } } + regmap_debugfs_init(map, config->name); + ret = regcache_init(map, config); if (ret != 0) goto err_range; - regmap_debugfs_init(map, config->name); - /* Add a devres resource for dev_get_regmap() */ m = devres_alloc(dev_get_regmap_release, sizeof(*m), GFP_KERNEL); if (!m) { -- cgit v1.2.3-55-g7522 From f4b828128ab64fd9dc5eec9525b38fbfeafa5c0e Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 12 Mar 2013 00:23:15 +0800 Subject: ASoC: wm_adsp: fix possible memory leak in wm_adsp_load_coeff() 'file' is malloced in wm_adsp_load_coeff() and should be freed before leaving from the error handling cases, otherwise it will cause memory leak. Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index f3f7e75f8628..9af1bddc4c62 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -828,7 +828,8 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp) &buf_list); if (!buf) { adsp_err(dsp, "Out of memory\n"); - return -ENOMEM; + ret = -ENOMEM; + goto out_fw; } adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", @@ -865,7 +866,7 @@ out_fw: wm_adsp_buf_free(&buf_list); out: kfree(file); - return 0; + return ret; } int wm_adsp1_init(struct wm_adsp *adsp) -- cgit v1.2.3-55-g7522 From e8b18addee32d1f389573b4c116e67ae230216ad Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 12 Mar 2013 00:35:14 +0800 Subject: ASoC: core: fix possible memory leak in snd_soc_bytes_put() 'data' is malloced in snd_soc_bytes_put() and should be freed before leaving from the error handling cases, otherwise it will cause memory leak. Signed-off-by: Wei Yongjun Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b7e84a7cd9ee..93341deaa4b9 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3140,7 +3140,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, if (params->mask) { ret = regmap_read(codec->control_data, params->base, &val); if (ret != 0) - return ret; + goto out; val &= params->mask; @@ -3158,13 +3158,15 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, ((u32 *)data)[0] |= cpu_to_be32(val); break; default: - return -EINVAL; + ret = -EINVAL; + goto out; } } ret = regmap_raw_write(codec->control_data, params->base, data, len); +out: kfree(data); return ret; -- cgit v1.2.3-55-g7522 From b6e51600f4e983e757b1b6942becaa1ae7d82e67 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sun, 10 Mar 2013 19:33:03 +0100 Subject: ASoC: imx-ssi: Fix occasional AC97 reset failure Signed-off-by: Sascha Hauer Signed-off-by: Markus Pargmann Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/fsl/imx-ssi.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index 55464a5b0706..810c7eeb7b03 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -496,6 +496,8 @@ static void imx_ssi_ac97_reset(struct snd_ac97 *ac97) if (imx_ssi->ac97_reset) imx_ssi->ac97_reset(ac97); + /* First read sometimes fails, do a dummy read */ + imx_ssi_ac97_read(ac97, 0); } static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97) @@ -504,6 +506,9 @@ static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97) if (imx_ssi->ac97_warm_reset) imx_ssi->ac97_warm_reset(ac97); + + /* First read sometimes fails, do a dummy read */ + imx_ssi_ac97_read(ac97, 0); } struct snd_ac97_bus_ops soc_ac97_ops = { -- cgit v1.2.3-55-g7522 From 34913fd950dc1817d466d76bdccd63443fdcbb12 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Sun, 10 Mar 2013 19:33:06 +0100 Subject: ASoC: pcm030 audio fabric: remove __init from probe Remove probe function from the init section. Signed-off-by: Markus Pargmann Signed-off-by: Mark Brown --- sound/soc/fsl/pcm030-audio-fabric.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c index 8e52c1485df3..eb4373840bb6 100644 --- a/sound/soc/fsl/pcm030-audio-fabric.c +++ b/sound/soc/fsl/pcm030-audio-fabric.c @@ -51,7 +51,7 @@ static struct snd_soc_card pcm030_card = { .num_links = ARRAY_SIZE(pcm030_fabric_dai), }; -static int __init pcm030_fabric_probe(struct platform_device *op) +static int pcm030_fabric_probe(struct platform_device *op) { struct device_node *np = op->dev.of_node; struct device_node *platform_np; -- cgit v1.2.3-55-g7522 From d558c4733759e077cf449246983a5d1fe97fc434 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 8 Mar 2013 11:51:19 +0530 Subject: spi: slink-tegra20: move runtime pm calls to transfer_one_message The prepare_transfer_hardware() is called in atomic context and calling synchronous runtime pm calls can create scheduling deadlock. Therefore, in place of calling runtime PM calls from prepare/unprepare message transfer, calling this in transfer_one_message(). Signed-off-by: Laxman Dewangan Tested-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/spi/spi-tegra20-slink.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c index b8698b389ef3..a829563f4713 100644 --- a/drivers/spi/spi-tegra20-slink.c +++ b/drivers/spi/spi-tegra20-slink.c @@ -858,21 +858,6 @@ static int tegra_slink_setup(struct spi_device *spi) return 0; } -static int tegra_slink_prepare_transfer(struct spi_master *master) -{ - struct tegra_slink_data *tspi = spi_master_get_devdata(master); - - return pm_runtime_get_sync(tspi->dev); -} - -static int tegra_slink_unprepare_transfer(struct spi_master *master) -{ - struct tegra_slink_data *tspi = spi_master_get_devdata(master); - - pm_runtime_put(tspi->dev); - return 0; -} - static int tegra_slink_transfer_one_message(struct spi_master *master, struct spi_message *msg) { @@ -885,6 +870,12 @@ static int tegra_slink_transfer_one_message(struct spi_master *master, msg->status = 0; msg->actual_length = 0; + ret = pm_runtime_get_sync(tspi->dev); + if (ret < 0) { + dev_err(tspi->dev, "runtime get failed: %d\n", ret); + goto done; + } + single_xfer = list_is_singular(&msg->transfers); list_for_each_entry(xfer, &msg->transfers, transfer_list) { INIT_COMPLETION(tspi->xfer_completion); @@ -921,6 +912,8 @@ static int tegra_slink_transfer_one_message(struct spi_master *master, exit: tegra_slink_writel(tspi, tspi->def_command_reg, SLINK_COMMAND); tegra_slink_writel(tspi, tspi->def_command2_reg, SLINK_COMMAND2); + pm_runtime_put(tspi->dev); +done: msg->status = ret; spi_finalize_current_message(master); return ret; @@ -1148,9 +1141,7 @@ static int tegra_slink_probe(struct platform_device *pdev) /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; master->setup = tegra_slink_setup; - master->prepare_transfer_hardware = tegra_slink_prepare_transfer; master->transfer_one_message = tegra_slink_transfer_one_message; - master->unprepare_transfer_hardware = tegra_slink_unprepare_transfer; master->num_chipselect = MAX_CHIP_SELECT; master->bus_num = -1; -- cgit v1.2.3-55-g7522 From 4a25b680b1e84cf97c740c8005e2c6655d6cfa7f Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Tue, 12 Mar 2013 00:13:36 +0100 Subject: spi/bcm63xx: Remove unused variable This fixes the following warning: drivers/spi/spi-bcm63xx.c: In function 'bcm63xx_spi_setup': drivers/spi/spi-bcm63xx.c:157:6: warning: unused variable 'ret' Signed-off-by: Kevin Cernekee Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 9578af782a77..0415a32cce33 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -152,7 +152,6 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi, static int bcm63xx_spi_setup(struct spi_device *spi) { struct bcm63xx_spi *bs; - int ret; bs = spi_master_get_devdata(spi->master); -- cgit v1.2.3-55-g7522 From b435ff212e91bddc2d12e6638a4d846d5f60daa6 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 12 Mar 2013 00:13:37 +0100 Subject: spi/bcm63xx: don't disable non enabled clocks in probe error path When msg_ctl_width is set to an invalid value we try to disable the clock despite it never being enabled. Fix it by jumping to the correct label. Signed-off-by: Jonas Gorski Acked-by: Florian Fainelli Signed-off-by: Mark Brown --- drivers/spi/spi-bcm63xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 0415a32cce33..d7df435d962e 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c @@ -489,7 +489,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev) default: dev_err(dev, "unsupported MSG_CTL width: %d\n", bs->msg_ctl_width); - goto out_clk_disable; + goto out_err; } /* Initialize hardware */ -- cgit v1.2.3-55-g7522 From 13872ebb915b547b3c0a1fc04f549a1475bb7989 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 13 Mar 2013 04:10:57 -0600 Subject: ARM: OMAP1: fix USB host on 1710 There is a long-standing bug that OHCI USB host controller does not respond on 1710, because of wrong clock definitions. See e.g. http://marc.info/?l=linux-omap&m=119634441229321&w=2. All register reads return just zeroes: [ 1.896606] ohci ohci: OMAP OHCI [ 1.912597] ohci ohci: new USB bus registered, assigned bus number 1 [ 1.933776] ohci ohci: irq 38, io mem 0xfffba000 [ 2.012573] ohci ohci: init err (00000000 0000) [ 2.030334] ohci ohci: can't start [ 2.046661] ohci ohci: startup error -75 [ 2.063201] ohci ohci: USB bus 1 deregistered After some experiments, it seems that when changing the usb_dc_ck / SOFT_REQ enable bit from USB_REQ_EN_SHIFT to SOFT_USB_OTG_DPLL_REQ_SHIFT (like done also on 7XX), the USB appears to work: [ 2.183959] ohci ohci: OMAP OHCI [ 2.198242] ohci ohci: new USB bus registered, assigned bus number 1 [ 2.215820] ohci ohci: irq 38, io mem 0xfffba000 [ 2.324798] hub 1-0:1.0: USB hub found [ 2.361267] hub 1-0:1.0: 3 ports detected The patch is tested on Nokia 770. Signed-off-by: Aaro Koskinen Signed-off-by: Paul Walmsley --- arch/arm/mach-omap1/clock_data.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c index cb7c6ae2e3fc..6c4f766365a2 100644 --- a/arch/arm/mach-omap1/clock_data.c +++ b/arch/arm/mach-omap1/clock_data.c @@ -538,15 +538,6 @@ static struct clk usb_hhc_ck16xx = { }; static struct clk usb_dc_ck = { - .name = "usb_dc_ck", - .ops = &clkops_generic, - /* Direct from ULPD, no parent */ - .rate = 48000000, - .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG), - .enable_bit = USB_REQ_EN_SHIFT, -}; - -static struct clk usb_dc_ck7xx = { .name = "usb_dc_ck", .ops = &clkops_generic, /* Direct from ULPD, no parent */ @@ -727,8 +718,7 @@ static struct omap_clk omap_clks[] = { CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310), CLK(NULL, "usb_hhc_ck", &usb_hhc_ck1510, CK_1510 | CK_310), CLK(NULL, "usb_hhc_ck", &usb_hhc_ck16xx, CK_16XX), - CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX), - CLK(NULL, "usb_dc_ck", &usb_dc_ck7xx, CK_7XX), + CLK(NULL, "usb_dc_ck", &usb_dc_ck, CK_16XX | CK_7XX), CLK(NULL, "mclk", &mclk_1510, CK_1510 | CK_310), CLK(NULL, "mclk", &mclk_16xx, CK_16XX), CLK(NULL, "bclk", &bclk_1510, CK_1510 | CK_310), -- cgit v1.2.3-55-g7522 From 71b37071f02e20345dcc0d570c69896da795e1e6 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Wed, 13 Mar 2013 04:11:23 -0600 Subject: ARM: OMAP4: clock data: lock USB DPLL on boot Some versions of the u-boot bootloader do not lock the USB DPLL and when the USB DPLL is not locked, then it is observed that the L3INIT power domain does not transition to retention state during kernel suspend on OMAP4 devices. Fix this by locking the USB DPLL at 960 MHz on kernel boot. Signed-off-by: Jon Hunter Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/cclock44xx_data.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm/mach-omap2/cclock44xx_data.c b/arch/arm/mach-omap2/cclock44xx_data.c index 3d58f335f173..015bcdc34b4a 100644 --- a/arch/arm/mach-omap2/cclock44xx_data.c +++ b/arch/arm/mach-omap2/cclock44xx_data.c @@ -52,6 +52,13 @@ */ #define OMAP4_DPLL_ABE_DEFFREQ 98304000 +/* + * OMAP4 USB DPLL default frequency. In OMAP4430 TRM version V, section + * "3.6.3.9.5 DPLL_USB Preferred Settings" shows that the preferred + * locked frequency for the USB DPLL is 960MHz. + */ +#define OMAP4_DPLL_USB_DEFFREQ 960000000 + /* Root clocks */ DEFINE_CLK_FIXED_RATE(extalt_clkin_ck, CLK_IS_ROOT, 59000000, 0x0); @@ -1705,5 +1712,13 @@ int __init omap4xxx_clk_init(void) if (rc) pr_err("%s: failed to configure ABE DPLL!\n", __func__); + /* + * Lock USB DPLL on OMAP4 devices so that the L3INIT power + * domain can transition to retention state when not in use. + */ + rc = clk_set_rate(&dpll_usb_ck, OMAP4_DPLL_USB_DEFFREQ); + if (rc) + pr_err("%s: failed to configure USB DPLL!\n", __func__); + return 0; } -- cgit v1.2.3-55-g7522 From 092bc089c249de0fa0f0c98b28dea6e5f1367b6e Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Mon, 11 Mar 2013 21:49:00 +0200 Subject: ARM: OMAP3: hwmod data: keep MIDLEMODE in force-standby for musb For some unknown reason, allowing hwmod to control MIDLEMODE causes core_pwrdm to not hit idle states for musb in DM3730 at least. I've verified that setting any MIDLEMODE value other than "force standby" before enabling the device causes subsequent suspend attempts to fail with core_pwrdm not entering idle states, even if the driver is unloaded and "force standby" is restored before suspend attempt. To recover from this, soft reset can be used, but that's not suitable solution for suspend. Keeping the register set at force standby (reset value) makes it work and device still functions properly, as musb has driver-controlled OTG_FORCESTDBY register that controls MSTANDBY signal. Note that TI PSP kernels also have similar workarounds. This patch also fixes HWMOD_SWSUP_MSTANDBY documentation to match the actual flag name. Signed-off-by: Grazvydas Ignotas Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 7 +++++-- arch/arm/mach-omap2/omap_hwmod.h | 9 +++++++-- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 7 ++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index c2c798c08c2b..a202a4785104 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1368,7 +1368,9 @@ static void _enable_sysc(struct omap_hwmod *oh) } if (sf & SYSC_HAS_MIDLEMODE) { - if (oh->flags & HWMOD_SWSUP_MSTANDBY) { + if (oh->flags & HWMOD_FORCE_MSTANDBY) { + idlemode = HWMOD_IDLEMODE_FORCE; + } else if (oh->flags & HWMOD_SWSUP_MSTANDBY) { idlemode = HWMOD_IDLEMODE_NO; } else { if (sf & SYSC_HAS_ENAWAKEUP) @@ -1440,7 +1442,8 @@ static void _idle_sysc(struct omap_hwmod *oh) } if (sf & SYSC_HAS_MIDLEMODE) { - if (oh->flags & HWMOD_SWSUP_MSTANDBY) { + if ((oh->flags & HWMOD_SWSUP_MSTANDBY) || + (oh->flags & HWMOD_FORCE_MSTANDBY)) { idlemode = HWMOD_IDLEMODE_FORCE; } else { if (sf & SYSC_HAS_ENAWAKEUP) diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index d43d9b608eda..d5dc935f6060 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -427,8 +427,8 @@ struct omap_hwmod_omap4_prcm { * * HWMOD_SWSUP_SIDLE: omap_hwmod code should manually bring module in and out * of idle, rather than relying on module smart-idle - * HWMOD_SWSUP_MSTDBY: omap_hwmod code should manually bring module in and out - * of standby, rather than relying on module smart-standby + * HWMOD_SWSUP_MSTANDBY: omap_hwmod code should manually bring module in and + * out of standby, rather than relying on module smart-standby * HWMOD_INIT_NO_RESET: don't reset this module at boot - important for * SDRAM controller, etc. XXX probably belongs outside the main hwmod file * XXX Should be HWMOD_SETUP_NO_RESET @@ -459,6 +459,10 @@ struct omap_hwmod_omap4_prcm { * correctly, or this is being abused to deal with some PM latency * issues -- but we're currently suffering from a shortage of * folks who are able to track these issues down properly. + * HWMOD_FORCE_MSTANDBY: Always keep MIDLEMODE bits cleared so that device + * is kept in force-standby mode. Failing to do so causes PM problems + * with musb on OMAP3630 at least. Note that musb has a dedicated register + * to control MSTANDBY signal when MIDLEMODE is set to force-standby. */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -471,6 +475,7 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_16BIT_REG (1 << 8) #define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) #define HWMOD_BLOCK_WFI (1 << 10) +#define HWMOD_FORCE_MSTANDBY (1 << 11) /* * omap_hwmod._int_flags definitions diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index ac7e03ec952f..5112d04e7b79 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1707,9 +1707,14 @@ static struct omap_hwmod omap3xxx_usbhsotg_hwmod = { * Erratum ID: i479 idle_req / idle_ack mechanism potentially * broken when autoidle is enabled * workaround is to disable the autoidle bit at module level. + * + * Enabling the device in any other MIDLEMODE setting but force-idle + * causes core_pwrdm not enter idle states at least on OMAP3630. + * Note that musb has OTG_FORCESTDBY register that controls MSTANDBY + * signal when MIDLEMODE is set to force-idle. */ .flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE - | HWMOD_SWSUP_MSTANDBY, + | HWMOD_FORCE_MSTANDBY, }; /* usb_otg_hs */ -- cgit v1.2.3-55-g7522 From 92702df3570e1ccfa050e135e50c450502251b79 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 12 Feb 2013 20:28:12 +0000 Subject: ARM: OMAP4: PM: fix PM regression introduced by recent clock cleanup Commit 17b7e7d33530e2bbd3bdc90f4db09b91cfdde2bb ("ARM: OMAP4: clock/hwmod data: start to remove some IP block control "clocks"") introduced a regression preventing the L3INIT clockdomain of OMAP4 systems from entering idle. This in turn prevented these systems from entering full chip clock-stop. The regression was caused by the incorrect removal of a so-called "optional functional clock" from the OMAP4 clock data. This wasn't caught for two reasons. First, I missed the retention entry failure in the branch test logs: http://www.pwsan.com/omap/testlogs/cleanup_a_3.9/20130126014242/pm/4460pandaes/4460pandaes_log.txt Second, the integration data for the OCP2SCP PHY IP block, added by commit 0c6688753f9912c6a7013549ec31c8844020bbc1 ("ARM: OMAP4: hwmod data: add remaining USB-related IP blocks"), should have associated this clock with the IP block, but did not. Fix by adding back the so-called "optional" functional clock to the clock data, and by linking that clock to the OCP2SCP PHY IP block integration hwmod data. The problem patch was discovered by J, Keerthy . Cc: Keerthy Cc: Benoît Cousson Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/cclock44xx_data.c | 5 +++++ arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/arch/arm/mach-omap2/cclock44xx_data.c b/arch/arm/mach-omap2/cclock44xx_data.c index 015bcdc34b4a..0c6834ae1fc4 100644 --- a/arch/arm/mach-omap2/cclock44xx_data.c +++ b/arch/arm/mach-omap2/cclock44xx_data.c @@ -1018,6 +1018,10 @@ DEFINE_CLK_OMAP_MUX(hsmmc2_fclk, "l3_init_clkdm", hsmmc1_fclk_sel, OMAP4430_CM_L3INIT_MMC2_CLKCTRL, OMAP4430_CLKSEL_MASK, hsmmc1_fclk_parents, func_dmic_abe_gfclk_ops); +DEFINE_CLK_GATE(ocp2scp_usb_phy_phy_48m, "func_48m_fclk", &func_48m_fclk, 0x0, + OMAP4430_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL, + OMAP4430_OPTFCLKEN_PHY_48M_SHIFT, 0x0, NULL); + DEFINE_CLK_GATE(sha2md5_fck, "l3_div_ck", &l3_div_ck, 0x0, OMAP4430_CM_L4SEC_SHA2MD51_CLKCTRL, OMAP4430_MODULEMODE_SWCTRL_SHIFT, 0x0, NULL); @@ -1545,6 +1549,7 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, "per_mcbsp4_gfclk", &per_mcbsp4_gfclk, CK_443X), CLK(NULL, "hsmmc1_fclk", &hsmmc1_fclk, CK_443X), CLK(NULL, "hsmmc2_fclk", &hsmmc2_fclk, CK_443X), + CLK(NULL, "ocp2scp_usb_phy_phy_48m", &ocp2scp_usb_phy_phy_48m, CK_443X), CLK(NULL, "sha2md5_fck", &sha2md5_fck, CK_443X), CLK(NULL, "slimbus1_fclk_1", &slimbus1_fclk_1, CK_443X), CLK(NULL, "slimbus1_fclk_0", &slimbus1_fclk_0, CK_443X), diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 0e47d2e1687c..9e0576569e07 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -2714,6 +2714,10 @@ static struct omap_ocp2scp_dev ocp2scp_dev_attr[] = { { } }; +static struct omap_hwmod_opt_clk ocp2scp_usb_phy_opt_clks[] = { + { .role = "48mhz", .clk = "ocp2scp_usb_phy_phy_48m" }, +}; + /* ocp2scp_usb_phy */ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { .name = "ocp2scp_usb_phy", @@ -2728,6 +2732,8 @@ static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { }, }, .dev_attr = ocp2scp_dev_attr, + .opt_clks = ocp2scp_usb_phy_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(ocp2scp_usb_phy_opt_clks), }; /* -- cgit v1.2.3-55-g7522 From 8abac3ba51b5525354e9b2ec0eed1c9e95c905d9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 13 Mar 2013 16:38:33 +0100 Subject: regmap: cache Fix regcache-rbtree sync The last register block, which falls into the specified range, is not handled correctly. The formula which calculates the number of register which should be synced is inverse (and off by one). E.g. if all registers in that block should be synced only one is synced, and if only one should be synced all (but one) are synced. To calculate the number of registers that need to be synced we need to subtract the number of the first register in the block from the max register number and add one. This patch updates the code accordingly. The issue was introduced in commit ac8d91c ("regmap: Supply ranges to the sync operations"). Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/base/regmap/regcache-rbtree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index e6732cf7c06e..79f4fca9877a 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c @@ -398,7 +398,7 @@ static int regcache_rbtree_sync(struct regmap *map, unsigned int min, base = 0; if (max < rbnode->base_reg + rbnode->blklen) - end = rbnode->base_reg + rbnode->blklen - max; + end = max - rbnode->base_reg + 1; else end = rbnode->blklen; -- cgit v1.2.3-55-g7522 From a4285b99e0087361c61f51c819633382fa659ea6 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 13 Mar 2013 20:54:34 +0100 Subject: MIPS: Fix inconsistent formatting inside /proc/cpuinfo There is a missing " " inside /proc/cpuinfo. The bad commit was: commit a96102be700f87283f168942cd09a2b30f86f324 Author: Steven J. Hill Date: Fri Dec 7 04:31:36 2012 +0000 MIPS: Add printing of ISA version in cpuinfo. Signed-off-by: John Crispin Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/4988/ Signed-off-by: Ralf Baechle --- arch/mips/kernel/proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 135c4aadccbe..7a54f74b7818 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c @@ -67,7 +67,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) if (cpu_has_mips_r) { seq_printf(m, "isa\t\t\t:"); if (cpu_has_mips_1) - seq_printf(m, "%s", "mips1"); + seq_printf(m, "%s", " mips1"); if (cpu_has_mips_2) seq_printf(m, "%s", " mips2"); if (cpu_has_mips_3) -- cgit v1.2.3-55-g7522 From 67e753ca41782913d805ff4a8a2b0f60b26b7915 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 14 Mar 2013 10:49:23 +0200 Subject: UBIFS: make space fixup work in the remount case The UBIFS space fixup is a useful feature which allows to fixup the "broken" flash space at the time of the first mount. The "broken" space is usually the result of using a "dumb" industrial flasher which is not able to skip empty NAND pages and just writes all 0xFFs to the empty space, which has grave side-effects for UBIFS when UBIFS trise to write useful data to those empty pages. The fix-up feature works roughly like this: 1. mkfs.ubifs sets the fixup flag in UBIFS superblock when creating the image (see -F option) 2. when the file-system is mounted for the first time, UBIFS notices the fixup flag and re-writes the entire media atomically, which may take really a lot of time. 3. UBIFS clears the fixup flag in the superblock. This works fine when the file system is mounted R/W for the very first time. But it did not really work in the case when we first mount the file-system R/O, and then re-mount R/W. The reason was that we started the fixup procedure too late, which we cannot really do because we have to fixup the space before it starts being used. Signed-off-by: Artem Bityutskiy Reported-by: Mark Jackson Cc: stable@vger.kernel.org # 3.0+ --- fs/ubifs/super.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index ac838b844936..f21acf0ef01f 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -1568,6 +1568,12 @@ static int ubifs_remount_rw(struct ubifs_info *c) c->remounting_rw = 1; c->ro_mount = 0; + if (c->space_fixup) { + err = ubifs_fixup_free_space(c); + if (err) + return err; + } + err = check_free_space(c); if (err) goto out; @@ -1684,12 +1690,6 @@ static int ubifs_remount_rw(struct ubifs_info *c) err = dbg_check_space_info(c); } - if (c->space_fixup) { - err = ubifs_fixup_free_space(c); - if (err) - goto out; - } - mutex_unlock(&c->umount_mutex); return err; -- cgit v1.2.3-55-g7522 From 7f08a89862b96d84c6dfe6c242eb010084e51d3b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 14 Mar 2013 21:26:24 +0100 Subject: ASoC: dapm: Fix pointer dereference in is_connected_output_ep() *path is not yet initialized when we check if the widget is connected. The compiler also warns about this: sound/soc/soc-dapm.c: In function 'is_connected_output_ep': sound/soc/soc-dapm.c:824:18: warning: 'path' may be used uninitialized in this function Signed-off-by: Peter Ujfalusi Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index f3255517de79..ab621b1db105 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -821,7 +821,6 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget, (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources))) { widget->outputs = snd_soc_dapm_suspend_check(widget); - path->walking = 0; return widget->outputs; } } -- cgit v1.2.3-55-g7522 From 605c357bb40ce412c086f3a928d07c1d4349b95b Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 15 Mar 2013 19:16:52 -0500 Subject: ARM: ep93xx: Fix wait for UART FIFO to be empty Commit 210dce5f "ARM: ep93xx: properly wait for UART FIFO to be empty" Removed the timeout loop while waiting for the uart transmit fifo to empty. Some bootloaders leave the uart in a state where there might be bytes in the uart that are not transmitted when execution is handed over to the kernel. This results in a deadlocked system while waiting for the fifo to empty. Add back the timeout wait to prevent the deadlock. Increase the wait time to hopefully prevent the decompressor corruption that lead to commit 210dce5f. This corruption was probably due to a slow uart baudrate. The 10* increase in the wait time should be enough for all cases. Signed-off-by: H Hartley Sweeten Acked-by: Florian Fainelli Signed-off-by: Ryan Mallon --- arch/arm/mach-ep93xx/include/mach/uncompress.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-ep93xx/include/mach/uncompress.h b/arch/arm/mach-ep93xx/include/mach/uncompress.h index d2afb4dd82ab..b5cc77d2380b 100644 --- a/arch/arm/mach-ep93xx/include/mach/uncompress.h +++ b/arch/arm/mach-ep93xx/include/mach/uncompress.h @@ -47,9 +47,13 @@ static void __raw_writel(unsigned int value, unsigned int ptr) static inline void putc(int c) { - /* Transmit fifo not full? */ - while (__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF) - ; + int i; + + for (i = 0; i < 10000; i++) { + /* Transmit fifo not full? */ + if (!(__raw_readb(PHYS_UART_FLAG) & UART_FLAG_TXFF)) + break; + } __raw_writeb(c, PHYS_UART_DATA); } -- cgit v1.2.3-55-g7522 From aabd6a8fa5a933bdf968cd86e34122745c1960e8 Mon Sep 17 00:00:00 2001 From: Sjur Brændeland Date: Mon, 18 Mar 2013 19:19:14 +1030 Subject: Revert "virtio_console: Initialize guest_connected=true for rproc_serial" This reverts commit 8078db789a92b10ff6e2d713231b5367e014c53b, and adds a lengthy comment explaining the problem area. The reverted patch caused opening of ports to fail for rproc_serial. In probe guest_connected was set to true, but port_fops_open() fails with -EMFILE if guest_connected already is true. Signed-off-by: Sjur Brændeland Acked-by: Amit Shah Signed-off-by: Rusty Russell --- drivers/char/virtio_console.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index e905d5f53051..e6ba6b7887e9 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1436,7 +1436,7 @@ static int add_port(struct ports_device *portdev, u32 id) * rproc_serial does not want the console port, only * the generic port implementation. */ - port->host_connected = port->guest_connected = true; + port->host_connected = true; else if (!use_multiport(port->portdev)) { /* * If we're not using multiport support, @@ -1752,13 +1752,23 @@ static void in_intr(struct virtqueue *vq) port->inbuf = get_inbuf(port); /* - * Don't queue up data when port is closed. This condition + * Normally the port should not accept data when the port is + * closed. For generic serial ports, the host won't (shouldn't) + * send data till the guest is connected. But this condition * can be reached when a console port is not yet connected (no - * tty is spawned) and the host sends out data to console - * ports. For generic serial ports, the host won't - * (shouldn't) send data till the guest is connected. + * tty is spawned) and the other side sends out data over the + * vring, or when a remote devices start sending data before + * the ports are opened. + * + * A generic serial port will discard data if not connected, + * while console ports and rproc-serial ports accepts data at + * any time. rproc-serial is initiated with guest_connected to + * false because port_fops_open expects this. Console ports are + * hooked up with an HVC console and is initialized with + * guest_connected to true. */ - if (!port->guest_connected) + + if (!port->guest_connected && !is_rproc_serial(port->portdev->vdev)) discard_port_data(port); spin_unlock_irqrestore(&port->inbuf_lock, flags); -- cgit v1.2.3-55-g7522 From 63c2b6812f1dc0beda4d6adad0365e048aa693e2 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 18 Mar 2013 15:56:10 +0000 Subject: MIPS: Fix code generation for non-DSP capable CPUs Commit 32a7ede (MIPS: dsp: Add assembler support for DSP ASEs) has enabled the use of DSP ASE specific instructions such as rddsp and wrdsp under the idea that all code path that will make use of these two instructions are properly checking for cpu_has_dsp to ensure that the particular CPU we are running on *actually* supports DSP ASE. This commit actually causes the following oops on QEMU Malta emulating a MIPS 24Kc without the DSP ASE implemented: [ 7.960000] Reserved instruction in kernel [ 7.960000] Cpu 0 [ 7.960000] $ 0 : 00000000 00000000 00000014 00000005 [ 7.960000] $ 4 : 8fc2de48 00000001 00000000 8f59ddb0 [ 7.960000] $ 8 : 8f5ceec4 00000018 00000c00 00800000 [ 7.960000] $12 : 00000100 00000200 00000000 00457b84 [ 7.960000] $16 : 00000000 8fc2ba78 8f4ec980 00000001 [ 7.960000] $20 : 80418f90 00000000 00000000 000002dd [ 7.960000] $24 : 0000009c 7730d7b8 [ 7.960000] $28 : 8f59c000 8f59dd38 00000001 80104248 [ 7.960000] Hi : 0000001d [ 7.960000] Lo : 0000000b [ 7.960000] epc : 801041ec thread_saved_pc+0x2c/0x38 [ 7.960000] Not tainted [ 7.960000] ra : 80104248 get_wchan+0x48/0xac [ 7.960000] Status: 1000b703 KERNEL EXL IE [ 7.960000] Cause : 10800028 [ 7.960000] PrId : 00019300 (MIPS 24Kc) [ 7.960000] Modules linked in: [ 7.960000] Process killall (pid: 1574, threadinfo=8f59c000, task=8fd14558, tls=773aa440) [ 7.960000] Stack : 8fc2ba78 8012b008 0000000c 0000001d 00000000 00000000 8f58a380 8f58a380 8fc2ba78 80202668 8f59de78 8f468600 8f59de28 801b2a3c 8f59df00 8f98ba20 74696e69 8f468600 8f59de28 801b7308 0081c007 00000000 00000000 00000000 00000000 00000000 00000000 00000000 8fc2bbb4 00000001 0000001d 0000000b 77f038cc 7fe80648 ffffffff ffffffff 00000000 00000001 0016e000 00000000 ... [ 7.960000] Call Trace: [ 7.960000] [<801041ec>] thread_saved_pc+0x2c/0x38 [ 7.960000] [<80104248>] get_wchan+0x48/0xac The disassembly of thread_saved_pc points to the following: 000006d0 : 6d0: 8c820208 lw v0,520(a0) 6d4: 3c030000 lui v1,0x0 6d8: 24630000 addiu v1,v1,0 6dc: 10430008 beq v0,v1,700 6e0: 00000000 nop 6e4: 3c020000 lui v0,0x0 6e8: 8c43000c lw v1,12(v0) 6ec: 04620004 bltzl v1,700 6f0: 00001021 move v0,zero 6f4: 8c840200 lw a0,512(a0) 6f8: 00031080 sll v0,v1,0x2 6fc: 7c44100a lwx v0,a0(v0) <------------ 700: 03e00008 jr ra 704: 00000000 nop If we specifically disable -mdsp/-mdspr2 for arch/mips/kernel/process.o, we get the following (non-crashing) assembly: 00000708 : 708: 8c820208 lw v0,520(a0) 70c: 3c030000 lui v1,0x0 710: 24630000 addiu v1,v1,0 714: 10430009 beq v0,v1,73c 718: 00000000 nop 71c: 3c020000 lui v0,0x0 720: 8c42000c lw v0,12(v0) 724: 04420005 bltzl v0,73c 728: 00001021 move v0,zero 72c: 8c830200 lw v1,512(a0) 730: 00021080 sll v0,v0,0x2 734: 00431021 addu v0,v0,v1 738: 8c420000 lw v0,0(v0) 73c: 03e00008 jr ra 740: 00000000 nop The specific line that leads a different assembly being produced is: unsigned long thread_saved_pc(struct task_struct *tsk) ... return ((unsigned long *)t->reg29)[schedule_mfi.pc_offset]; <--- The problem here is that the compiler was given the right to use DSP instructions with the -mdsp / -mdspr2 command-line switches and performed some optimization for us and used DSP ASE instructions where we are not checking that the running CPU actually supports DSP ASE. This patch fixes the issue by partially reverting commit 32a7ede for arch/mips/kernel/Makefile in order to remove the -mdsp / -mdspr2 compiler command-line switches such that we are now guaranteed that the compiler will not optimize using DSP ASE reserved instructions. We also need to fixup the rddsp/wrdsp and m{t,h}{hi,lo}{0,1,2,3} macros in arch/mips/include/asm/mipsregs.h to tell the assembler that we are going to explicitely use DSP ASE reserved instructions. The comment in arch/mips/kernel/Makefile is also updated to reflect that. Signed-off-by: Florian Fainelli Acked-by: Steven J. Hill Cc: linux-mips@linux-mips.org Cc: blogic@openwrt.org Signed-off-by: Ralf Baechle --- arch/mips/include/asm/mipsregs.h | 209 +++++++++++++++++++++++++++++++++++---- arch/mips/kernel/Makefile | 25 ++--- 2 files changed, 196 insertions(+), 38 deletions(-) diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 12b70c25906a..0da44d422f5b 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -1166,7 +1166,10 @@ do { \ unsigned int __dspctl; \ \ __asm__ __volatile__( \ + " .set push \n" \ + " .set dsp \n" \ " rddsp %0, %x1 \n" \ + " .set pop \n" \ : "=r" (__dspctl) \ : "i" (mask)); \ __dspctl; \ @@ -1175,30 +1178,198 @@ do { \ #define wrdsp(val, mask) \ do { \ __asm__ __volatile__( \ + " .set push \n" \ + " .set dsp \n" \ " wrdsp %0, %x1 \n" \ + " .set pop \n" \ : \ : "r" (val), "i" (mask)); \ } while (0) -#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;}) -#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;}) -#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;}) -#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;}) - -#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;}) -#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;}) -#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;}) -#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;}) - -#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x)) -#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x)) -#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x)) -#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x)) - -#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x)) -#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x)) -#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x)) -#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x)) +#define mflo0() \ +({ \ + long mflo0; \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mflo %0, $ac0 \n" \ + " .set pop \n" \ + : "=r" (mflo0)); \ + mflo0; \ +}) + +#define mflo1() \ +({ \ + long mflo1; \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mflo %0, $ac1 \n" \ + " .set pop \n" \ + : "=r" (mflo1)); \ + mflo1; \ +}) + +#define mflo2() \ +({ \ + long mflo2; \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mflo %0, $ac2 \n" \ + " .set pop \n" \ + : "=r" (mflo2)); \ + mflo2; \ +}) + +#define mflo3() \ +({ \ + long mflo3; \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mflo %0, $ac3 \n" \ + " .set pop \n" \ + : "=r" (mflo3)); \ + mflo3; \ +}) + +#define mfhi0() \ +({ \ + long mfhi0; \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mfhi %0, $ac0 \n" \ + " .set pop \n" \ + : "=r" (mfhi0)); \ + mfhi0; \ +}) + +#define mfhi1() \ +({ \ + long mfhi1; \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mfhi %0, $ac1 \n" \ + " .set pop \n" \ + : "=r" (mfhi1)); \ + mfhi1; \ +}) + +#define mfhi2() \ +({ \ + long mfhi2; \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mfhi %0, $ac2 \n" \ + " .set pop \n" \ + : "=r" (mfhi2)); \ + mfhi2; \ +}) + +#define mfhi3() \ +({ \ + long mfhi3; \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mfhi %0, $ac3 \n" \ + " .set pop \n" \ + : "=r" (mfhi3)); \ + mfhi3; \ +}) + + +#define mtlo0(x) \ +({ \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mtlo %0, $ac0 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +}) + +#define mtlo1(x) \ +({ \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mtlo %0, $ac1 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +}) + +#define mtlo2(x) \ +({ \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mtlo %0, $ac2 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +}) + +#define mtlo3(x) \ +({ \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mtlo %0, $ac3 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +}) + +#define mthi0(x) \ +({ \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mthi %0, $ac0 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +}) + +#define mthi1(x) \ +({ \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mthi %0, $ac1 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +}) + +#define mthi2(x) \ +({ \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mthi %0, $ac2 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +}) + +#define mthi3(x) \ +({ \ + __asm__( \ + " .set push \n" \ + " .set dsp \n" \ + " mthi %0, $ac3 \n" \ + " .set pop \n" \ + : \ + : "r" (x)); \ +}) #else diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index f81d98f6184c..de75fb50562b 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile @@ -100,29 +100,16 @@ obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o # -# DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is safe -# to enable DSP assembler support here even if the MIPS Release 2 CPU we -# are targetting does not support DSP because all code-paths making use of -# it properly check that the running CPU *actually does* support these -# instructions. +# DSP ASE supported for MIPS32 or MIPS64 Release 2 cores only. It is not +# safe to unconditionnaly use the assembler -mdsp / -mdspr2 switches +# here because the compiler may use DSP ASE instructions (such as lwx) in +# code paths where we cannot check that the CPU we are running on supports it. +# Proper abstraction using HAVE_AS_DSP and macros is done in +# arch/mips/include/asm/mipsregs.h. # ifeq ($(CONFIG_CPU_MIPSR2), y) CFLAGS_DSP = -DHAVE_AS_DSP -# -# Check if assembler supports DSP ASE -# -ifeq ($(call cc-option-yn,-mdsp), y) -CFLAGS_DSP += -mdsp -endif - -# -# Check if assembler supports DSP ASE Rev2 -# -ifeq ($(call cc-option-yn,-mdspr2), y) -CFLAGS_DSP += -mdspr2 -endif - CFLAGS_signal.o = $(CFLAGS_DSP) CFLAGS_signal32.o = $(CFLAGS_DSP) CFLAGS_process.o = $(CFLAGS_DSP) -- cgit v1.2.3-55-g7522 From 97367519d7dac94de566796f034d5f72cbc671f7 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 19 Mar 2013 13:08:27 +0000 Subject: MIPS: BCM63XX: Make nvram checksum failure non fatal Some vendors modify the nvram layout moving the checksum to a different place or dropping entirely, so reduce the checksum failure to a warning. Reported-by: Álvaro Fernández Rojas Signed-off-by: Jonas Gorski Cc: linux-mips@linux-mips.org Cc: John Crispin Cc: Maxime Bizon Cc: Florian Fainelli Cc: Kevin Cernekee Signed-off-by: Ralf Baechle --- arch/mips/bcm63xx/boards/board_bcm963xx.c | 5 +---- arch/mips/bcm63xx/nvram.c | 7 +++---- arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | 4 +--- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c index ed1949c29508..9aa7d44898ed 100644 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c @@ -745,10 +745,7 @@ void __init board_prom_init(void) strcpy(cfe_version, "unknown"); printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); - if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) { - printk(KERN_ERR PFX "invalid nvram checksum\n"); - return; - } + bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET); board_name = bcm63xx_nvram_get_name(); /* find board by name */ diff --git a/arch/mips/bcm63xx/nvram.c b/arch/mips/bcm63xx/nvram.c index 620611680839..a4b8864f9307 100644 --- a/arch/mips/bcm63xx/nvram.c +++ b/arch/mips/bcm63xx/nvram.c @@ -38,7 +38,7 @@ struct bcm963xx_nvram { static struct bcm963xx_nvram nvram; static int mac_addr_used; -int __init bcm63xx_nvram_init(void *addr) +void __init bcm63xx_nvram_init(void *addr) { unsigned int check_len; u32 crc, expected_crc; @@ -60,9 +60,8 @@ int __init bcm63xx_nvram_init(void *addr) crc = crc32_le(~0, (u8 *)&nvram, check_len); if (crc != expected_crc) - return -EINVAL; - - return 0; + pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n", + expected_crc, crc); } u8 *bcm63xx_nvram_get_name(void) diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h index 62d6a3b4d3b7..4e0b6bc1165e 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h @@ -9,10 +9,8 @@ * * Initialized the local nvram copy from the target address and checks * its checksum. - * - * Returns 0 on success. */ -int __init bcm63xx_nvram_init(void *nvram); +void bcm63xx_nvram_init(void *nvram); /** * bcm63xx_nvram_get_name() - returns the board name according to nvram -- cgit v1.2.3-55-g7522 From 1762c5ab7ce5f482aafaf9b6a721e41f073ae3cb Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 19 Mar 2013 13:20:19 +0000 Subject: Revert "MIPS: BCM63XX: Call board_register_device from device_initcall()" This commit causes a race between PCI scan and SSB fallback SPROM handler registration, causing the wifi to not work on slower systems. The only subsystem touched from board_register_devices is platform device registration, which is safe as an arch init call. This reverts commit d64ed7ada2f689d2c62af1892ca55e47d3653e36 [MIPS: BCM63XX: Call board_register_device from device_initcall()]. Signed-off-by: Jonas Gorski To: linux-mips@linux-mips.org Cc: John Crispin Cc: Maxime Bizon Cc: Florian Fainelli Cc: Kevin Cernekee Signed-off-by: Ralf Baechle --- arch/mips/bcm63xx/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c index 314231be788c..35e18e98beb9 100644 --- a/arch/mips/bcm63xx/setup.c +++ b/arch/mips/bcm63xx/setup.c @@ -157,4 +157,4 @@ int __init bcm63xx_register_devices(void) return board_register_devices(); } -device_initcall(bcm63xx_register_devices); +arch_initcall(bcm63xx_register_devices); -- cgit v1.2.3-55-g7522 From 2a1486981c1317dc4f4aad568f2cc6e49dfb8c82 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 19 Mar 2013 14:00:53 +0000 Subject: Fix breakage in MIPS siginfo handling MIPS's siginfo handling has been broken since this commit: commit 574c4866e33d648520a8bd5bf6f573ea6e554e88 Author: Al Viro Date: Sun Nov 25 22:24:19 2012 -0500 consolidate kernel-side struct sigaction declarations for 64-bit BE MIPS CPUs. The UAPI variant looks like this: struct sigaction { unsigned int sa_flags; __sighandler_t sa_handler; sigset_t sa_mask; }; but the core kernel's variant looks like this: struct sigaction { #ifndef __ARCH_HAS_ODD_SIGACTION __sighandler_t sa_handler; unsigned long sa_flags; #else unsigned long sa_flags; __sighandler_t sa_handler; #endif #ifdef __ARCH_HAS_SA_RESTORER __sigrestore_t sa_restorer; #endif sigset_t sa_mask; }; The problem is that sa_flags has been changed from an unsigned int to an unsigned long. Fix this by making sa_flags unsigned int if __ARCH_HAS_ODD_SIGACTION is defined. Whilst we're at it, rename __ARCH_HAS_ODD_SIGACTION to __ARCH_HAS_IRIX_SIGACTION. Signed-off-by: David Howells Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org Acked-by: Al Viro Signed-off-by: Ralf Baechle --- arch/mips/include/asm/signal.h | 2 +- include/linux/compat.h | 4 ++-- include/linux/signal.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/mips/include/asm/signal.h b/arch/mips/include/asm/signal.h index 197f6367c201..8efe5a9e2c3e 100644 --- a/arch/mips/include/asm/signal.h +++ b/arch/mips/include/asm/signal.h @@ -21,6 +21,6 @@ #include #include -#define __ARCH_HAS_ODD_SIGACTION +#define __ARCH_HAS_IRIX_SIGACTION #endif /* _ASM_SIGNAL_H */ diff --git a/include/linux/compat.h b/include/linux/compat.h index 76a87fb57ac2..377cd8c3395e 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -141,11 +141,11 @@ typedef struct { } compat_sigset_t; struct compat_sigaction { -#ifndef __ARCH_HAS_ODD_SIGACTION +#ifndef __ARCH_HAS_IRIX_SIGACTION compat_uptr_t sa_handler; compat_ulong_t sa_flags; #else - compat_ulong_t sa_flags; + compat_uint_t sa_flags; compat_uptr_t sa_handler; #endif #ifdef __ARCH_HAS_SA_RESTORER diff --git a/include/linux/signal.h b/include/linux/signal.h index a2dcb94ea49d..9475c5cb28bc 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -250,11 +250,11 @@ extern int show_unhandled_signals; extern int sigsuspend(sigset_t *); struct sigaction { -#ifndef __ARCH_HAS_ODD_SIGACTION +#ifndef __ARCH_HAS_IRIX_SIGACTION __sighandler_t sa_handler; unsigned long sa_flags; #else - unsigned long sa_flags; + unsigned int sa_flags; __sighandler_t sa_handler; #endif #ifdef __ARCH_HAS_SA_RESTORER -- cgit v1.2.3-55-g7522 From b7d44d9487a11e835de10908f4ab30b4290c0b7f Mon Sep 17 00:00:00 2001 From: Satoru Takeuchi Date: Wed, 20 Mar 2013 11:28:51 +1030 Subject: hw_random: free rng_buffer at module exit rng-core module allocates rng_buffer by kmalloc() since commit f7f154f1246ccc5a0a7e9ce50932627d60a0c878. But this buffer won't be freed and there is a memory leak possibility at module exit. Signed-off-by: Satoru Takeuchi Signed-off-by: Rusty Russell --- drivers/char/hw_random/core.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 69ae5972713c..a0f7724852eb 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -380,6 +380,15 @@ void hwrng_unregister(struct hwrng *rng) } EXPORT_SYMBOL_GPL(hwrng_unregister); +static void __exit hwrng_exit(void) +{ + mutex_lock(&rng_mutex); + BUG_ON(current_rng); + kfree(rng_buffer); + mutex_unlock(&rng_mutex); +} + +module_exit(hwrng_exit); MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-55-g7522 From 4480764f57ba494e3f64003e13223c0b5ec6a2ca Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 19 Mar 2013 14:58:43 -0700 Subject: ASoC:: max98090: Remove executable bit Source files shouldn't have the executable bit set. Signed-off-by: Joe Perches Signed-off-by: Mark Brown --- include/sound/max98090.h | 0 sound/soc/codecs/max98090.c | 0 sound/soc/codecs/max98090.h | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 include/sound/max98090.h mode change 100755 => 100644 sound/soc/codecs/max98090.c mode change 100755 => 100644 sound/soc/codecs/max98090.h diff --git a/include/sound/max98090.h b/include/sound/max98090.h old mode 100755 new mode 100644 diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c old mode 100755 new mode 100644 diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h old mode 100755 new mode 100644 -- cgit v1.2.3-55-g7522 From 59d9cc2a5073ab4b8c8f8bdbacf230a538abc55d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Mar 2013 18:57:23 +0100 Subject: ASoC: spear_pcm: Update to new pcm_new() API Commit 552d1ef6 ("ASoC: core - Optimise and refactor pcm_new() to pass only rtd") updated the pcm_new() callback to take the rtd as the only parameter. The spear PCM driver (which was merged much later) still uses the old API. This patch updates the driver to the new API. Signed-off-by: Lars-Peter Clausen Acked-by: Rajeev Kumar Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/spear/spear_pcm.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index 9b76cc5a1148..5e7aebe1e664 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c @@ -149,9 +149,9 @@ static void spear_pcm_free(struct snd_pcm *pcm) static u64 spear_pcm_dmamask = DMA_BIT_MASK(32); -static int spear_pcm_new(struct snd_card *card, - struct snd_soc_dai *dai, struct snd_pcm *pcm) +static int spear_pcm_new(struct snd_soc_pcm_runtime *rtd) { + struct snd_card *card = rtd->card->snd_card; int ret; if (!card->dev->dma_mask) @@ -159,16 +159,16 @@ static int spear_pcm_new(struct snd_card *card, if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = DMA_BIT_MASK(32); - if (dai->driver->playback.channels_min) { - ret = spear_pcm_preallocate_dma_buffer(pcm, + if (rtd->cpu_dai->driver->playback.channels_min) { + ret = spear_pcm_preallocate_dma_buffer(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK, spear_pcm_hardware.buffer_bytes_max); if (ret) return ret; } - if (dai->driver->capture.channels_min) { - ret = spear_pcm_preallocate_dma_buffer(pcm, + if (rtd->cpu_dai->driver->capture.channels_min) { + ret = spear_pcm_preallocate_dma_buffer(rtd->pcm, SNDRV_PCM_STREAM_CAPTURE, spear_pcm_hardware.buffer_bytes_max); if (ret) -- cgit v1.2.3-55-g7522 From f7ba716f1e704a00d682a8697108f9c86497c551 Mon Sep 17 00:00:00 2001 From: Silviu-Mihai Popescu Date: Sat, 16 Mar 2013 13:45:34 +0200 Subject: ASoC: core: fix invalid free of devm_ allocated data The objects allocated by devm_* APIs are managed by devres and are freed when the device is detached. Hence there is no need to use kfree() explicitly. Signed-off-by: Silviu-Mihai Popescu Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 93341deaa4b9..507d251916af 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4199,7 +4199,6 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, dev_err(card->dev, "ASoC: Property '%s' index %d could not be read: %d\n", propname, 2 * i, ret); - kfree(routes); return -EINVAL; } ret = of_property_read_string_index(np, propname, @@ -4208,7 +4207,6 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, dev_err(card->dev, "ASoC: Property '%s' index %d could not be read: %d\n", propname, (2 * i) + 1, ret); - kfree(routes); return -EINVAL; } } -- cgit v1.2.3-55-g7522 From bec964ed3b2549086e1fdfbf7f1ce8c22f89baa4 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Wed, 20 Mar 2013 10:50:50 +0100 Subject: NFC: llcp: Detach socket from process context only when releasing the socket Calling sock_orphan when e.g. the NFC adapter is removed can lead to kernel crashes when e.g. a connection less client is sleeping on the Rx workqueue, waiting for data to show up. Signed-off-by: Samuel Ortiz --- net/nfc/llcp/llcp.c | 6 ------ net/nfc/llcp/sock.c | 2 -- 2 files changed, 8 deletions(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index b530afadd76c..336813ff8cd5 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -107,8 +107,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, accept_sk->sk_state_change(sk); bh_unlock_sock(accept_sk); - - sock_orphan(accept_sk); } if (listen == true) { @@ -134,8 +132,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, bh_unlock_sock(sk); - sock_orphan(sk); - sk_del_node_init(sk); } @@ -164,8 +160,6 @@ static void nfc_llcp_socket_release(struct nfc_llcp_local *local, bool listen, bh_unlock_sock(sk); - sock_orphan(sk); - sk_del_node_init(sk); } diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index 5c7cdf3f2a83..e488e440186a 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c @@ -464,8 +464,6 @@ static int llcp_sock_release(struct socket *sock) nfc_llcp_accept_unlink(accept_sk); release_sock(accept_sk); - - sock_orphan(accept_sk); } } -- cgit v1.2.3-55-g7522 From 0017c0b57500606aab894cdb02fdf3380ddd60ee Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Mon, 11 Mar 2013 10:32:16 +0100 Subject: xfrm: Fix replay notification for esn. We may miscalculate the sequence number difference from the last time we send a notification if a sequence number wrap occured in the meantime. We fix this by adding a separate replay notify function for esn. Here we take the high bits of the sequence number into account to calculate the difference. Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_replay.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index 35754cc8a9e5..a3906737f49e 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c @@ -334,6 +334,72 @@ static void xfrm_replay_notify_bmp(struct xfrm_state *x, int event) x->xflags &= ~XFRM_TIME_DEFER; } +static void xfrm_replay_notify_esn(struct xfrm_state *x, int event) +{ + u32 seq_diff, oseq_diff; + struct km_event c; + struct xfrm_replay_state_esn *replay_esn = x->replay_esn; + struct xfrm_replay_state_esn *preplay_esn = x->preplay_esn; + + /* we send notify messages in case + * 1. we updated on of the sequence numbers, and the seqno difference + * is at least x->replay_maxdiff, in this case we also update the + * timeout of our timer function + * 2. if x->replay_maxage has elapsed since last update, + * and there were changes + * + * The state structure must be locked! + */ + + switch (event) { + case XFRM_REPLAY_UPDATE: + if (!x->replay_maxdiff) + break; + + if (replay_esn->seq_hi == preplay_esn->seq_hi) + seq_diff = replay_esn->seq - preplay_esn->seq; + else + seq_diff = UINT_MAX - preplay_esn->seq + + replay_esn->seq; + + if (replay_esn->oseq_hi == preplay_esn->oseq_hi) + oseq_diff = replay_esn->oseq - preplay_esn->oseq; + else + oseq_diff = UINT_MAX - preplay_esn->oseq + + replay_esn->oseq; + + if (seq_diff < x->replay_maxdiff && + oseq_diff < x->replay_maxdiff) { + + if (x->xflags & XFRM_TIME_DEFER) + event = XFRM_REPLAY_TIMEOUT; + else + return; + } + + break; + + case XFRM_REPLAY_TIMEOUT: + if (memcmp(x->replay_esn, x->preplay_esn, + xfrm_replay_state_esn_len(replay_esn)) == 0) { + x->xflags |= XFRM_TIME_DEFER; + return; + } + + break; + } + + memcpy(x->preplay_esn, x->replay_esn, + xfrm_replay_state_esn_len(replay_esn)); + c.event = XFRM_MSG_NEWAE; + c.data.aevent = event; + km_state_notify(x, &c); + + if (x->replay_maxage && + !mod_timer(&x->rtimer, jiffies + x->replay_maxage)) + x->xflags &= ~XFRM_TIME_DEFER; +} + static int xfrm_replay_overflow_esn(struct xfrm_state *x, struct sk_buff *skb) { int err = 0; @@ -510,7 +576,7 @@ static struct xfrm_replay xfrm_replay_esn = { .advance = xfrm_replay_advance_esn, .check = xfrm_replay_check_esn, .recheck = xfrm_replay_recheck_esn, - .notify = xfrm_replay_notify_bmp, + .notify = xfrm_replay_notify_esn, .overflow = xfrm_replay_overflow_esn, }; -- cgit v1.2.3-55-g7522 From cc904c7188c29847817f35e6966fec3014c7479b Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 14 Mar 2013 08:35:06 +0200 Subject: iwlwifi: fix length check in multi-TB HCMD As reported by Ben Hutchings, there was a harmless issue in the checks being done on the lengths of the TBs while building the TFD for a multi-TB host command. Cc: stable@vger@kernel.org Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 8595c16f74de..cb5c6792e3a8 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1264,7 +1264,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { int copy = 0; - if (!cmd->len) + if (!cmd->len[i]) continue; /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ -- cgit v1.2.3-55-g7522 From 4620020b5d7ca34d1c03fa98b0ca457320cb7d71 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 13 Mar 2013 16:38:32 +0200 Subject: iwlwifi: set rfkill in internal state of the transport We didn't update the internal of the PCIe transport when we read the RFkill state directly. Fix that. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/trans.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 17bedc50e753..12c4f31ca8fb 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -475,6 +475,10 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, /* If platform's RF_KILL switch is NOT set to KILL */ hw_rfkill = iwl_is_rfkill_set(trans); + if (hw_rfkill) + set_bit(STATUS_RFKILL, &trans_pcie->status); + else + clear_bit(STATUS_RFKILL, &trans_pcie->status); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); if (hw_rfkill && !run_in_rfkill) return -ERFKILL; @@ -641,6 +645,7 @@ static int iwl_trans_pcie_d3_resume(struct iwl_trans *trans, static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); bool hw_rfkill; int err; @@ -656,6 +661,10 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) iwl_enable_rfkill_int(trans); hw_rfkill = iwl_is_rfkill_set(trans); + if (hw_rfkill) + set_bit(STATUS_RFKILL, &trans_pcie->status); + else + clear_bit(STATUS_RFKILL, &trans_pcie->status); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); return 0; @@ -694,6 +703,10 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, * op_mode. */ hw_rfkill = iwl_is_rfkill_set(trans); + if (hw_rfkill) + set_bit(STATUS_RFKILL, &trans_pcie->status); + else + clear_bit(STATUS_RFKILL, &trans_pcie->status); iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); } } -- cgit v1.2.3-55-g7522 From 2d5d50ee596361566f7f84300117cba7d7672bc5 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 31 Jan 2013 15:03:55 +0200 Subject: iwlwifi: dvm: don't send HCMD in restart flow There is a race between the restart flow and the workers. The workers are cancelled after the fw is already killed and might send HCMD when there is fw to handle them. Simply check that there is a fw to which the HCMD can be sent before actually sending it. Cc: stable@vger.kernel.org Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/lib.c | 9 +++++++++ drivers/net/wireless/iwlwifi/dvm/ucode.c | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 86ea5f4c3939..44ca0e57f9f7 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -1261,6 +1261,15 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) return -EIO; } + /* + * This can happen upon FW ASSERT: we clear the STATUS_FW_ERROR flag + * in iwl_down but cancel the workers only later. + */ + if (!priv->ucode_loaded) { + IWL_ERR(priv, "Fw not loaded - dropping CMD: %x\n", cmd->id); + return -EIO; + } + /* * Synchronous commands from this op-mode must hold * the mutex, this ensures we don't try to send two diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index 736fe9bb140e..1a4ac9236a44 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -367,6 +367,8 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, return -EIO; } + priv->ucode_loaded = true; + if (ucode_type != IWL_UCODE_WOWLAN) { /* delay a bit to give rfkill time to run */ msleep(5); @@ -380,8 +382,6 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, return ret; } - priv->ucode_loaded = true; - return 0; } -- cgit v1.2.3-55-g7522 From b3155155440190de78fb501953136a6c5b82e327 Mon Sep 17 00:00:00 2001 From: Thierry Escande Date: Wed, 20 Mar 2013 16:00:16 +0100 Subject: NFC: llcp: Remove possible double call to kfree_skb kfree_skb was called twice when the socket receive queue is full Signed-off-by: Thierry Escande Signed-off-by: Samuel Ortiz --- net/nfc/llcp/llcp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c index 336813ff8cd5..ee25f25f0cd6 100644 --- a/net/nfc/llcp/llcp.c +++ b/net/nfc/llcp/llcp.c @@ -821,7 +821,6 @@ static void nfc_llcp_recv_ui(struct nfc_llcp_local *local, skb_get(skb); } else { pr_err("Receive queue is full\n"); - kfree_skb(skb); } nfc_llcp_sock_put(llcp_sock); @@ -1022,7 +1021,6 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, skb_get(skb); } else { pr_err("Receive queue is full\n"); - kfree_skb(skb); } } -- cgit v1.2.3-55-g7522 From ce1eadda6badef9e4e3460097ede674fca47383d Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 19 Mar 2013 20:26:57 +0100 Subject: cfg80211: fix wdev tracing crash Arend reported a crash in tracing if the driver returns an ERR_PTR() value from the add_virtual_intf() callback. This is due to the tracing then still attempting to dereference the "pointer", fix this by using IS_ERR_OR_NULL(). Reported-by: Arend van Spriel Tested-by: Arend van Spriel Signed-off-by: Johannes Berg --- net/wireless/trace.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 6847d043edea..7586de77a2f8 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h @@ -27,7 +27,8 @@ #define WIPHY_PR_ARG __entry->wiphy_name #define WDEV_ENTRY __field(u32, id) -#define WDEV_ASSIGN (__entry->id) = (wdev ? wdev->identifier : 0) +#define WDEV_ASSIGN (__entry->id) = (!IS_ERR_OR_NULL(wdev) \ + ? wdev->identifier : 0) #define WDEV_PR_FMT "wdev(%u)" #define WDEV_PR_ARG (__entry->id) -- cgit v1.2.3-55-g7522 From 8b305780ed0c49a49c6bd58a4372fd6b22a5a71e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Mar 2013 22:25:17 +0100 Subject: mac80211: fix virtual monitor interface locking The virtual monitor interface has a locking issue, it calls into the channel context code with the iflist mutex held which isn't allowed since it is usually acquired the other way around. The mutex is still required for the interface iteration, but need not be held across the channel calls. Signed-off-by: Johannes Berg --- net/mac80211/iface.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index baaa8608e52d..3bfe2612c8c2 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -349,21 +349,19 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata) static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; - int ret = 0; + int ret; if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) return 0; - mutex_lock(&local->iflist_mtx); + ASSERT_RTNL(); if (local->monitor_sdata) - goto out_unlock; + return 0; sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); - if (!sdata) { - ret = -ENOMEM; - goto out_unlock; - } + if (!sdata) + return -ENOMEM; /* set up data */ sdata->local = local; @@ -377,13 +375,13 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) if (WARN_ON(ret)) { /* ok .. stupid driver, it asked for this! */ kfree(sdata); - goto out_unlock; + return ret; } ret = ieee80211_check_queues(sdata); if (ret) { kfree(sdata); - goto out_unlock; + return ret; } ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef, @@ -391,13 +389,14 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) if (ret) { drv_remove_interface(local, sdata); kfree(sdata); - goto out_unlock; + return ret; } + mutex_lock(&local->iflist_mtx); rcu_assign_pointer(local->monitor_sdata, sdata); - out_unlock: mutex_unlock(&local->iflist_mtx); - return ret; + + return 0; } static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) @@ -407,14 +406,20 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) return; + ASSERT_RTNL(); + mutex_lock(&local->iflist_mtx); sdata = rcu_dereference_protected(local->monitor_sdata, lockdep_is_held(&local->iflist_mtx)); - if (!sdata) - goto out_unlock; + if (!sdata) { + mutex_unlock(&local->iflist_mtx); + return; + } rcu_assign_pointer(local->monitor_sdata, NULL); + mutex_unlock(&local->iflist_mtx); + synchronize_net(); ieee80211_vif_release_channel(sdata); @@ -422,8 +427,6 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) drv_remove_interface(local, sdata); kfree(sdata); - out_unlock: - mutex_unlock(&local->iflist_mtx); } /* -- cgit v1.2.3-55-g7522 From 6c43a519610a5e11af5be707ad88391ce86129ba Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 20 Mar 2013 09:45:22 +0100 Subject: drivers/Kconfig: add several missing GENERIC_HARDIRQS dependencies With this patch an allmodconfig finally builds on s390 again. Fixes these build errors: ERROR: "devm_request_threaded_irq" [drivers/spi/spi-altera.ko] undefined! ERROR: "devm_request_threaded_irq" [drivers/media/platform/sh_veu.ko] undefined! ERROR: "devm_request_threaded_irq" [drivers/dma/dw_dmac.ko] undefined! Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/dma/Kconfig | 1 + drivers/media/platform/Kconfig | 2 +- drivers/spi/Kconfig | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 80b69971cf28..aeaea32bcfda 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -83,6 +83,7 @@ config INTEL_IOP_ADMA config DW_DMAC tristate "Synopsys DesignWare AHB DMA support" + depends on GENERIC_HARDIRQS select DMA_ENGINE default y if CPU_AT32AP7000 help diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 05d7b6333461..a0639e779973 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -204,7 +204,7 @@ config VIDEO_SAMSUNG_EXYNOS_GSC config VIDEO_SH_VEU tristate "SuperH VEU mem2mem video processing driver" - depends on VIDEO_DEV && VIDEO_V4L2 + depends on VIDEO_DEV && VIDEO_V4L2 && GENERIC_HARDIRQS select VIDEOBUF2_DMA_CONTIG select V4L2_MEM2MEM_DEV help diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index f80eee74a311..2be0de920d67 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -55,6 +55,7 @@ comment "SPI Master Controller Drivers" config SPI_ALTERA tristate "Altera SPI Controller" + depends on GENERIC_HARDIRQS select SPI_BITBANG help This is the driver for the Altera SPI Controller. @@ -310,7 +311,7 @@ config SPI_PXA2XX_DMA config SPI_PXA2XX tristate "PXA2xx SSP SPI master" - depends on ARCH_PXA || PCI || ACPI + depends on (ARCH_PXA || PCI || ACPI) && GENERIC_HARDIRQS select PXA_SSP if ARCH_PXA help This enables using a PXA2xx or Sodaville SSP port as a SPI master -- cgit v1.2.3-55-g7522 From 3bff6038f1938d2541943dfde604a9b92f347650 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Mon, 18 Mar 2013 16:01:30 +0100 Subject: s390/scm_block: fix printk format string Use hex digits when referring to scm addresses. Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/block/scm_blk.c | 4 ++-- drivers/s390/block/scm_drv.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c index 5ac9c935c151..713f0185f96d 100644 --- a/drivers/s390/block/scm_blk.c +++ b/drivers/s390/block/scm_blk.c @@ -307,7 +307,7 @@ static void scm_blk_handle_error(struct scm_request *scmrq) case EQC_WR_PROHIBIT: spin_lock_irqsave(&bdev->lock, flags); if (bdev->state != SCM_WR_PROHIBIT) - pr_info("%lu: Write access to the SCM increment is suspended\n", + pr_info("%lx: Write access to the SCM increment is suspended\n", (unsigned long) bdev->scmdev->address); bdev->state = SCM_WR_PROHIBIT; spin_unlock_irqrestore(&bdev->lock, flags); @@ -445,7 +445,7 @@ void scm_blk_set_available(struct scm_blk_dev *bdev) spin_lock_irqsave(&bdev->lock, flags); if (bdev->state == SCM_WR_PROHIBIT) - pr_info("%lu: Write access to the SCM increment is restored\n", + pr_info("%lx: Write access to the SCM increment is restored\n", (unsigned long) bdev->scmdev->address); bdev->state = SCM_OPER; spin_unlock_irqrestore(&bdev->lock, flags); diff --git a/drivers/s390/block/scm_drv.c b/drivers/s390/block/scm_drv.c index 5f6180d6ff08..c98cf52d78d1 100644 --- a/drivers/s390/block/scm_drv.c +++ b/drivers/s390/block/scm_drv.c @@ -19,7 +19,7 @@ static void scm_notify(struct scm_device *scmdev, enum scm_event event) switch (event) { case SCM_CHANGE: - pr_info("%lu: The capabilities of the SCM increment changed\n", + pr_info("%lx: The capabilities of the SCM increment changed\n", (unsigned long) scmdev->address); SCM_LOG(2, "State changed"); SCM_LOG_STATE(2, scmdev); -- cgit v1.2.3-55-g7522 From 94f9852de86447088e8e3c12d8b5a8f996acee32 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 20 Mar 2013 13:40:54 +0100 Subject: s390/scm_blk: fix error return code in scm_blk_init() Fix to return a negative error code from the error handling case instead of 0, as returned elsewhere in this function. Signed-off-by: Wei Yongjun Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/block/scm_blk.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c index 713f0185f96d..e9b9c8392832 100644 --- a/drivers/s390/block/scm_blk.c +++ b/drivers/s390/block/scm_blk.c @@ -463,12 +463,15 @@ static int __init scm_blk_init(void) goto out; scm_major = ret; - if (scm_alloc_rqs(nr_requests)) + ret = scm_alloc_rqs(nr_requests); + if (ret) goto out_unreg; scm_debug = debug_register("scm_log", 16, 1, 16); - if (!scm_debug) + if (!scm_debug) { + ret = -ENOMEM; goto out_free; + } debug_register_view(scm_debug, &debug_hex_ascii_view); debug_set_level(scm_debug, 2); -- cgit v1.2.3-55-g7522 From b7fef2dd7217d9e3f35c948e87297451e55c9709 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 21 Mar 2013 08:24:11 +0100 Subject: s390/uaccess: fix clear_user_pt() The page table walker variant of clear_user() is supposed to copy the contents of the empty zero page to user space. However since 238ec4ef "[S390] zero page cache synonyms" empty_zero_page is not anymore the page itself but contains the pointer to the empty zero pages. Therefore the page table walker variant of clear_user() copied the address of the first empty zero page and afterwards more or less random data to user space instead of clearing the given user space range. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/lib/uaccess_pt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index dff631d34b45..6771fdd89377 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c @@ -197,7 +197,7 @@ size_t copy_to_user_pt(size_t n, void __user *to, const void *from) static size_t clear_user_pt(size_t n, void __user *to) { - void *zpage = &empty_zero_page; + void *zpage = (void *) empty_zero_page; long done, size, ret; done = 0; -- cgit v1.2.3-55-g7522 From 1fcbba3d65dff8ce9d25e644fcc86fa8c629de7d Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 21 Mar 2013 13:07:18 +0100 Subject: s390/3270: fix minor_start issue The 3270 device nodes 227/0 and 228/0 are special. 227/0 is never used, and 228/0 is used to redirect full screen applications from /dev/3270/tub to the real device node of the 3270 terminal. To keep the device names /dev/3270/tty consistent with the minor number the device driver sets minor_start to 0 and skips minor 0. That makes the tty index equivalent to the minor number. But doing so seems to causes problems with init scripts. A better solution is to set minor_start to the correct value of 1 and set name_base to 1 as well. tty_register_device will then automatically create the correct tty name. Signed-off-by: Martin Schwidefsky --- drivers/s390/char/tty3270.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index b907dba24025..cee69dac3e18 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -915,7 +915,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) int i, rc; /* Check if the tty3270 is already there. */ - view = raw3270_find_view(&tty3270_fn, tty->index); + view = raw3270_find_view(&tty3270_fn, tty->index + RAW3270_FIRSTMINOR); if (!IS_ERR(view)) { tp = container_of(view, struct tty3270, view); tty->driver_data = tp; @@ -927,15 +927,16 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) tp->inattr = TF_INPUT; return tty_port_install(&tp->port, driver, tty); } - if (tty3270_max_index < tty->index) - tty3270_max_index = tty->index; + if (tty3270_max_index < tty->index + 1) + tty3270_max_index = tty->index + 1; /* Allocate tty3270 structure on first open. */ tp = tty3270_alloc_view(); if (IS_ERR(tp)) return PTR_ERR(tp); - rc = raw3270_add_view(&tp->view, &tty3270_fn, tty->index); + rc = raw3270_add_view(&tp->view, &tty3270_fn, + tty->index + RAW3270_FIRSTMINOR); if (rc) { tty3270_free_view(tp); return rc; @@ -1846,12 +1847,12 @@ static const struct tty_operations tty3270_ops = { void tty3270_create_cb(int minor) { - tty_register_device(tty3270_driver, minor, NULL); + tty_register_device(tty3270_driver, minor - RAW3270_FIRSTMINOR, NULL); } void tty3270_destroy_cb(int minor) { - tty_unregister_device(tty3270_driver, minor); + tty_unregister_device(tty3270_driver, minor - RAW3270_FIRSTMINOR); } struct raw3270_notifier tty3270_notifier = @@ -1884,7 +1885,8 @@ static int __init tty3270_init(void) driver->driver_name = "tty3270"; driver->name = "3270/tty"; driver->major = IBM_TTY3270_MAJOR; - driver->minor_start = 0; + driver->minor_start = RAW3270_FIRSTMINOR; + driver->name_base = RAW3270_FIRSTMINOR; driver->type = TTY_DRIVER_TYPE_SYSTEM; driver->subtype = SYSTEM_TYPE_TTY; driver->init_termios = tty_std_termios; -- cgit v1.2.3-55-g7522 From bc8ce4afd7ee7e1421c935d24b1f879f82afdd4e Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 20 Mar 2013 17:02:02 -0600 Subject: regmap: don't corrupt work buffer in _regmap_raw_write() _regmap_raw_write() contains code to call regcache_write() to write values to the cache. That code calls memcpy() to copy the value data to the start of the work_buf. However, at least when _regmap_raw_write() is called from _regmap_bus_raw_write(), the value data is in the work_buf, and this memcpy() operation may over-write part of that value data, depending on the value of reg_bytes + pad_bytes. At least when using reg_bytes==1 and pad_bytes==0, corruption of the value data does occur. To solve this, remove the memcpy() operation, and modify the subsequent .parse_val() call to parse the original value buffer directly. At least in the case of 8-bit register address and 16-bit values, and writes of single registers at a time, this memcpy-then-parse combination used to cancel each-other out; for a work-buffer containing xx 89 03, the memcpy changed it to 89 03 03, and the parse_val changed it back to 89 89 03, thus leaving the value uncorrupted. This appears completely accidental though. Since commit 8a819ff "regmap: core: Split out in place value parsing", .parse_val only returns the parsed value, and does not modify the buffer, and hence does not (accidentally) undo the corruption caused by memcpy(). This caused bogus values to get written to HW, thus preventing e.g. audio playback on systems with a WM8903 CODEC. This patch fixes that. Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 3d2367501fd0..89a920510e1d 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -943,8 +943,7 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, unsigned int ival; int val_bytes = map->format.val_bytes; for (i = 0; i < val_len / val_bytes; i++) { - memcpy(map->work_buf, val + (i * val_bytes), val_bytes); - ival = map->format.parse_val(map->work_buf); + ival = map->format.parse_val(val + (i * val_bytes)); ret = regcache_write(map, reg + (i * map->reg_stride), ival); if (ret) { -- cgit v1.2.3-55-g7522 From 417a1178f1bf3cdc606376b3ded3a22489fbb3eb Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 15 Mar 2013 11:26:15 +0100 Subject: ASoC: dma-sh7760: Fix compile error The dma-sh7760 currently fails with the following compile error: sound/soc/sh/dma-sh7760.c:346:2: error: unknown field 'pcm_ops' specified in initializer sound/soc/sh/dma-sh7760.c:346:2: warning: initialization from incompatible pointer type sound/soc/sh/dma-sh7760.c:347:2: error: unknown field 'pcm_new' specified in initializer sound/soc/sh/dma-sh7760.c:347:2: warning: initialization makes integer from pointer without a cast sound/soc/sh/dma-sh7760.c:348:2: error: unknown field 'pcm_free' specified in initializer sound/soc/sh/dma-sh7760.c:348:2: warning: initialization from incompatible pointer type sound/soc/sh/dma-sh7760.c: In function 'sh7760_soc_platform_probe': sound/soc/sh/dma-sh7760.c:353:2: warning: passing argument 2 of 'snd_soc_register_platform' from incompatible pointer type include/sound/soc.h:368:5: note: expected 'struct snd_soc_platform_driver *' but argument is of type 'struct snd_soc_platform *' This is due the misnaming of the snd_soc_platform_driver type name and 'ops' field. The issue was introduced in commit f0fba2a("ASoC: multi-component - ASoC Multi-Component Support"). Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/sh/dma-sh7760.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index 19eff8fc4fdd..1a8b03e4b41b 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c @@ -342,8 +342,8 @@ static int camelot_pcm_new(struct snd_soc_pcm_runtime *rtd) return 0; } -static struct snd_soc_platform sh7760_soc_platform = { - .pcm_ops = &camelot_pcm_ops, +static struct snd_soc_platform_driver sh7760_soc_platform = { + .ops = &camelot_pcm_ops, .pcm_new = camelot_pcm_new, .pcm_free = camelot_pcm_free, }; -- cgit v1.2.3-55-g7522 From e651eab0af88aa7a281fe9e8c36c0846552aa7fc Mon Sep 17 00:00:00 2001 From: Sricharan R Date: Mon, 18 Mar 2013 12:24:04 +0100 Subject: ARM: 7677/1: LPAE: Fix mapping in alloc_init_section for unaligned addresses With LPAE enabled, alloc_init_section() does not map the entire address space for unaligned addresses. The issue also reproduced with CMA + LPAE. CMA tries to map 16MB with page granularity mappings during boot. alloc_init_pte() is called and out of 16MB, only 2MB gets mapped and rest remains unaccessible. Because of this OMAP5 boot is broken with CMA + LPAE enabled. Fix the issue by ensuring that the entire addresses are mapped. Signed-off-by: R Sricharan Cc: Catalin Marinas Cc: Christoffer Dall Cc: Santosh Shilimkar Tested-by: Laura Abbott Acked-by: Catalin Marinas Acked-by: Christoffer Dall Signed-off-by: Russell King --- arch/arm/mm/mmu.c | 73 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index e95a996ab78f..78978945492a 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -598,39 +598,60 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr, } while (pte++, addr += PAGE_SIZE, addr != end); } -static void __init alloc_init_section(pud_t *pud, unsigned long addr, - unsigned long end, phys_addr_t phys, - const struct mem_type *type) +static void __init map_init_section(pmd_t *pmd, unsigned long addr, + unsigned long end, phys_addr_t phys, + const struct mem_type *type) { - pmd_t *pmd = pmd_offset(pud, addr); - +#ifndef CONFIG_ARM_LPAE /* - * Try a section mapping - end, addr and phys must all be aligned - * to a section boundary. Note that PMDs refer to the individual - * L1 entries, whereas PGDs refer to a group of L1 entries making - * up one logical pointer to an L2 table. + * In classic MMU format, puds and pmds are folded in to + * the pgds. pmd_offset gives the PGD entry. PGDs refer to a + * group of L1 entries making up one logical pointer to + * an L2 table (2MB), where as PMDs refer to the individual + * L1 entries (1MB). Hence increment to get the correct + * offset for odd 1MB sections. + * (See arch/arm/include/asm/pgtable-2level.h) */ - if (type->prot_sect && ((addr | end | phys) & ~SECTION_MASK) == 0) { - pmd_t *p = pmd; - -#ifndef CONFIG_ARM_LPAE - if (addr & SECTION_SIZE) - pmd++; + if (addr & SECTION_SIZE) + pmd++; #endif + do { + *pmd = __pmd(phys | type->prot_sect); + phys += SECTION_SIZE; + } while (pmd++, addr += SECTION_SIZE, addr != end); - do { - *pmd = __pmd(phys | type->prot_sect); - phys += SECTION_SIZE; - } while (pmd++, addr += SECTION_SIZE, addr != end); + flush_pmd_entry(pmd); +} - flush_pmd_entry(p); - } else { +static void __init alloc_init_pmd(pud_t *pud, unsigned long addr, + unsigned long end, phys_addr_t phys, + const struct mem_type *type) +{ + pmd_t *pmd = pmd_offset(pud, addr); + unsigned long next; + + do { /* - * No need to loop; pte's aren't interested in the - * individual L1 entries. + * With LPAE, we must loop over to map + * all the pmds for the given range. */ - alloc_init_pte(pmd, addr, end, __phys_to_pfn(phys), type); - } + next = pmd_addr_end(addr, end); + + /* + * Try a section mapping - addr, next and phys must all be + * aligned to a section boundary. + */ + if (type->prot_sect && + ((addr | next | phys) & ~SECTION_MASK) == 0) { + map_init_section(pmd, addr, next, phys, type); + } else { + alloc_init_pte(pmd, addr, next, + __phys_to_pfn(phys), type); + } + + phys += next - addr; + + } while (pmd++, addr = next, addr != end); } static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, @@ -641,7 +662,7 @@ static void __init alloc_init_pud(pgd_t *pgd, unsigned long addr, do { next = pud_addr_end(addr, end); - alloc_init_section(pud, addr, next, phys, type); + alloc_init_pmd(pud, addr, next, phys, type); phys += next - addr; } while (pud++, addr = next, addr != end); } -- cgit v1.2.3-55-g7522 From c40e3641670eb6ebfdb71d4b0c775416ef95f4f0 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 18 Mar 2013 19:44:14 +0100 Subject: ARM: 7679/1: Clear IDIVT hwcap if CONFIG_ARM_THUMB=n Don't advertise support for the SDIV/UDIV thumb instructions if the kernel is not compiled with support for thumb userspace. This is in line with how we remove the THUMB hwcap in these configurations. Acked-by: Will Deacon Cc: Stepan Moskovchenko Signed-off-by: Stephen Boyd Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 3f6cbb2e3eda..e2c8bbffb0b1 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -484,7 +484,7 @@ static void __init setup_processor(void) list->elf_name, ENDIANNESS); elf_hwcap = list->elf_hwcap; #ifndef CONFIG_ARM_THUMB - elf_hwcap &= ~HWCAP_THUMB; + elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT); #endif feat_v6_fixup(); -- cgit v1.2.3-55-g7522 From 8164f7af88d9ad3a757bd14f634b23997ee77f6b Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 18 Mar 2013 19:44:15 +0100 Subject: ARM: 7680/1: Detect support for SDIV/UDIV from ISAR0 register The ISAR0 register indicates support for the SDIV and UDIV instructions in both the Thumb and ARM instruction set. Read the register to detect the supported instructions and update the elf_hwcap mask as appropriate. This is better than adding more and more cpuid checks in proc-v7.S for each new cpu variant that supports these instructions. Acked-by: Will Deacon Cc: Stepan Moskovchenko Signed-off-by: Stephen Boyd Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 20 ++++++++++++++++++++ arch/arm/mm/proc-v7.S | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index e2c8bbffb0b1..f3ac13f69b7a 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -353,6 +353,23 @@ void __init early_print(const char *str, ...) printk("%s", buf); } +static void __init cpuid_init_hwcaps(void) +{ + unsigned int divide_instrs; + + if (cpu_architecture() < CPU_ARCH_ARMv7) + return; + + divide_instrs = (read_cpuid_ext(CPUID_EXT_ISAR0) & 0x0f000000) >> 24; + + switch (divide_instrs) { + case 2: + elf_hwcap |= HWCAP_IDIVA; + case 1: + elf_hwcap |= HWCAP_IDIVT; + } +} + static void __init feat_v6_fixup(void) { int id = read_cpuid_id(); @@ -483,6 +500,9 @@ static void __init setup_processor(void) snprintf(elf_platform, ELF_PLATFORM_SIZE, "%s%c", list->elf_name, ENDIANNESS); elf_hwcap = list->elf_hwcap; + + cpuid_init_hwcaps(); + #ifndef CONFIG_ARM_THUMB elf_hwcap &= ~(HWCAP_THUMB | HWCAP_IDIVT); #endif diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 3a3c015f8d5c..bcd3d48922fb 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -420,7 +420,7 @@ __v7_pj4b_proc_info: __v7_ca7mp_proc_info: .long 0x410fc070 .long 0xff0ffff0 - __v7_proc __v7_ca7mp_setup, hwcaps = HWCAP_IDIV + __v7_proc __v7_ca7mp_setup .size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info /* @@ -430,7 +430,7 @@ __v7_ca7mp_proc_info: __v7_ca15mp_proc_info: .long 0x410fc0f0 .long 0xff0ffff0 - __v7_proc __v7_ca15mp_setup, hwcaps = HWCAP_IDIV + __v7_proc __v7_ca15mp_setup .size __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info /* -- cgit v1.2.3-55-g7522 From 120ecfafabec382c4feb79ff159ef42a39b6d33b Mon Sep 17 00:00:00 2001 From: Stepan Moskovchenko Date: Mon, 18 Mar 2013 19:44:16 +0100 Subject: ARM: 7678/1: Work around faulty ISAR0 register in some Krait CPUs Some early versions of the Krait CPU design incorrectly indicate that they only support the UDIV and SDIV instructions in Thumb mode when they actually support them in ARM and Thumb mode. It seems that these CPUs follow the DDI0406B ARM ARM which has two possible values for the divide instructions field, instead of the DDI0406C document which has three possible values. Work around this problem by checking the MIDR against Krait CPUs with this faulty ISAR0 register and force the hwcaps to indicate support in both modes. [sboyd: Rewrote commit text to reflect real reasoning now that we autodetect udiv/sdiv] Signed-off-by: Stepan Moskovchenko Acked-by: Will Deacon Signed-off-by: Stephen Boyd Signed-off-by: Russell King --- arch/arm/mm/proc-v7.S | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index bcd3d48922fb..f584d3f5b37c 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -433,6 +433,21 @@ __v7_ca15mp_proc_info: __v7_proc __v7_ca15mp_setup .size __v7_ca15mp_proc_info, . - __v7_ca15mp_proc_info + /* + * Qualcomm Inc. Krait processors. + */ + .type __krait_proc_info, #object +__krait_proc_info: + .long 0x510f0400 @ Required ID value + .long 0xff0ffc00 @ Mask for ID + /* + * Some Krait processors don't indicate support for SDIV and UDIV + * instructions in the ARM instruction set, even though they actually + * do support them. + */ + __v7_proc __v7_setup, hwcaps = HWCAP_IDIV + .size __krait_proc_info, . - __krait_proc_info + /* * Match any ARMv7 processor core. */ -- cgit v1.2.3-55-g7522 From 68a154fc53ddd3f7b33e482847a411bf54a50855 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Wed, 20 Mar 2013 17:30:30 +0100 Subject: ARM: 7681/1: hw_breakpoint: use warn_once to avoid spam from reset_ctrl_regs() CPU debug features like hardware break, watchpoints can be used only when the debug mode is enabled and available. Unfortunately on OMAP4 based devices, after a CPU power cycle, the debug feature gets disabled which leads to a flood of messages coming from reset_ctrl_regs() which gets called on every CPU_PM_EXIT with CPUidle enabled. So make use of warn_once() so that system is usable. Thanks to Will for pointers and Lokesh for the analysis of the issue. Tested-by: Lokesh Vutla Signed-off-by: Santosh Shilimkar Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/kernel/hw_breakpoint.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 96093b75ab90..5dc1aa6f0f7d 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -966,7 +966,7 @@ static void reset_ctrl_regs(void *unused) } if (err) { - pr_warning("CPU %d debug is powered down!\n", cpu); + pr_warn_once("CPU %d debug is powered down!\n", cpu); cpumask_or(&debug_err_mask, &debug_err_mask, cpumask_of(cpu)); return; } @@ -987,7 +987,7 @@ clear_vcr: isb(); if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) { - pr_warning("CPU %d failed to disable vector catch\n", cpu); + pr_warn_once("CPU %d failed to disable vector catch\n", cpu); return; } @@ -1007,7 +1007,7 @@ clear_vcr: } if (cpumask_intersects(&debug_err_mask, cpumask_of(cpu))) { - pr_warning("CPU %d failed to clear debug register pairs\n", cpu); + pr_warn_once("CPU %d failed to clear debug register pairs\n", cpu); return; } -- cgit v1.2.3-55-g7522 From 4080d2d11a2d572228c2b8d02406e997b87ba6a5 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 14 Mar 2013 20:31:37 -0700 Subject: ARM: msm: Stop counting before reprogramming clockevent If the clockevent is forcibly reprogrammed to have a different match value we mistakenly assume the timer is not ticking and program a new match value while the timer is running. Although we clear the timer before programming a new match, it's better to stop the timer before clearing it so that we're sure the proper amount of ticks are counted. Failure to do so can lead to missed ticks and system hangs. Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- arch/arm/mach-msm/timer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 2969027f02fa..f9fd77e8f1f5 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -62,7 +62,10 @@ static int msm_timer_set_next_event(unsigned long cycles, { u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE); - writel_relaxed(0, event_base + TIMER_CLEAR); + ctrl &= ~TIMER_ENABLE_EN; + writel_relaxed(ctrl, event_base + TIMER_ENABLE); + + writel_relaxed(ctrl, event_base + TIMER_CLEAR); writel_relaxed(cycles, event_base + TIMER_MATCH_VAL); writel_relaxed(ctrl | TIMER_ENABLE_EN, event_base + TIMER_ENABLE); return 0; -- cgit v1.2.3-55-g7522 From f9f475292dbb0e7035fb6661d1524761ea0888d9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 19 Mar 2013 15:04:07 +0100 Subject: cfg80211: always check for scan end on P2P device If a P2P device wdev is removed while it has a scan, then the scan completion might crash later as it is already freed by that time. To avoid the crash always check the scan completion when the P2P device is being removed for some reason. If the driver already canceled it, don't want and free it, otherwise warn and leak it to avoid later crashes. In order to do this, locking needs to be changed away from the rdev mutex (which can't always be guaranteed). For now, use the sched_scan_mtx instead, I'll rename it to just scan_mtx in a later patch. Signed-off-by: Johannes Berg --- net/wireless/core.c | 64 ++++++++++++++++++++++++++++++++++++------------- net/wireless/core.h | 3 +++ net/wireless/nl80211.c | 52 +++++++++++++++++++++------------------- net/wireless/scan.c | 8 ++++--- net/wireless/sme.c | 6 +++-- net/wireless/wext-sme.c | 6 +++++ 6 files changed, 92 insertions(+), 47 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index 922002105062..11743d48cbc2 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -212,6 +212,39 @@ static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) rdev_rfkill_poll(rdev); } +void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev) +{ + lockdep_assert_held(&rdev->devlist_mtx); + lockdep_assert_held(&rdev->sched_scan_mtx); + + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)) + return; + + if (!wdev->p2p_started) + return; + + rdev_stop_p2p_device(rdev, wdev); + wdev->p2p_started = false; + + rdev->opencount--; + + if (rdev->scan_req && rdev->scan_req->wdev == wdev) { + bool busy = work_busy(&rdev->scan_done_wk); + + /* + * If the work isn't pending or running (in which case it would + * be waiting for the lock we hold) the driver didn't properly + * cancel the scan when the interface was removed. In this case + * warn and leak the scan request object to not crash later. + */ + WARN_ON(!busy); + + rdev->scan_req->aborted = true; + ___cfg80211_scan_done(rdev, !busy); + } +} + static int cfg80211_rfkill_set_block(void *data, bool blocked) { struct cfg80211_registered_device *rdev = data; @@ -221,7 +254,8 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked) return 0; rtnl_lock(); - mutex_lock(&rdev->devlist_mtx); + + /* read-only iteration need not hold the devlist_mtx */ list_for_each_entry(wdev, &rdev->wdev_list, list) { if (wdev->netdev) { @@ -231,18 +265,18 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked) /* otherwise, check iftype */ switch (wdev->iftype) { case NL80211_IFTYPE_P2P_DEVICE: - if (!wdev->p2p_started) - break; - rdev_stop_p2p_device(rdev, wdev); - wdev->p2p_started = false; - rdev->opencount--; + /* but this requires it */ + mutex_lock(&rdev->devlist_mtx); + mutex_lock(&rdev->sched_scan_mtx); + cfg80211_stop_p2p_device(rdev, wdev); + mutex_unlock(&rdev->sched_scan_mtx); + mutex_unlock(&rdev->devlist_mtx); break; default: break; } } - mutex_unlock(&rdev->devlist_mtx); rtnl_unlock(); return 0; @@ -745,17 +779,13 @@ static void wdev_cleanup_work(struct work_struct *work) wdev = container_of(work, struct wireless_dev, cleanup_work); rdev = wiphy_to_dev(wdev->wiphy); - cfg80211_lock_rdev(rdev); + mutex_lock(&rdev->sched_scan_mtx); if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) { rdev->scan_req->aborted = true; ___cfg80211_scan_done(rdev, true); } - cfg80211_unlock_rdev(rdev); - - mutex_lock(&rdev->sched_scan_mtx); - if (WARN_ON(rdev->sched_scan_req && rdev->sched_scan_req->dev == wdev->netdev)) { __cfg80211_stop_sched_scan(rdev, false); @@ -781,21 +811,19 @@ void cfg80211_unregister_wdev(struct wireless_dev *wdev) return; mutex_lock(&rdev->devlist_mtx); + mutex_lock(&rdev->sched_scan_mtx); list_del_rcu(&wdev->list); rdev->devlist_generation++; switch (wdev->iftype) { case NL80211_IFTYPE_P2P_DEVICE: - if (!wdev->p2p_started) - break; - rdev_stop_p2p_device(rdev, wdev); - wdev->p2p_started = false; - rdev->opencount--; + cfg80211_stop_p2p_device(rdev, wdev); break; default: WARN_ON_ONCE(1); break; } + mutex_unlock(&rdev->sched_scan_mtx); mutex_unlock(&rdev->devlist_mtx); } EXPORT_SYMBOL(cfg80211_unregister_wdev); @@ -937,6 +965,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, cfg80211_update_iface_num(rdev, wdev->iftype, 1); cfg80211_lock_rdev(rdev); mutex_lock(&rdev->devlist_mtx); + mutex_lock(&rdev->sched_scan_mtx); wdev_lock(wdev); switch (wdev->iftype) { #ifdef CONFIG_CFG80211_WEXT @@ -968,6 +997,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, break; } wdev_unlock(wdev); + mutex_unlock(&rdev->sched_scan_mtx); rdev->opencount++; mutex_unlock(&rdev->devlist_mtx); cfg80211_unlock_rdev(rdev); diff --git a/net/wireless/core.h b/net/wireless/core.h index 3aec0e429d8a..5845c2b37aa8 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -503,6 +503,9 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, enum nl80211_iftype iftype, int num); +void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev); + #define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d44ab216c0ec..58e13a8c95f9 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4702,14 +4702,19 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->scan) return -EOPNOTSUPP; - if (rdev->scan_req) - return -EBUSY; + mutex_lock(&rdev->sched_scan_mtx); + if (rdev->scan_req) { + err = -EBUSY; + goto unlock; + } if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { n_channels = validate_scan_freqs( info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); - if (!n_channels) - return -EINVAL; + if (!n_channels) { + err = -EINVAL; + goto unlock; + } } else { enum ieee80211_band band; n_channels = 0; @@ -4723,23 +4728,29 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) n_ssids++; - if (n_ssids > wiphy->max_scan_ssids) - return -EINVAL; + if (n_ssids > wiphy->max_scan_ssids) { + err = -EINVAL; + goto unlock; + } if (info->attrs[NL80211_ATTR_IE]) ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); else ie_len = 0; - if (ie_len > wiphy->max_scan_ie_len) - return -EINVAL; + if (ie_len > wiphy->max_scan_ie_len) { + err = -EINVAL; + goto unlock; + } request = kzalloc(sizeof(*request) + sizeof(*request->ssids) * n_ssids + sizeof(*request->channels) * n_channels + ie_len, GFP_KERNEL); - if (!request) - return -ENOMEM; + if (!request) { + err = -ENOMEM; + goto unlock; + } if (n_ssids) request->ssids = (void *)&request->channels[n_channels]; @@ -4876,6 +4887,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) kfree(request); } + unlock: + mutex_unlock(&rdev->sched_scan_mtx); return err; } @@ -7749,20 +7762,9 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info) if (!rdev->ops->stop_p2p_device) return -EOPNOTSUPP; - if (!wdev->p2p_started) - return 0; - - rdev_stop_p2p_device(rdev, wdev); - wdev->p2p_started = false; - - mutex_lock(&rdev->devlist_mtx); - rdev->opencount--; - mutex_unlock(&rdev->devlist_mtx); - - if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) { - rdev->scan_req->aborted = true; - ___cfg80211_scan_done(rdev, true); - } + mutex_lock(&rdev->sched_scan_mtx); + cfg80211_stop_p2p_device(rdev, wdev); + mutex_unlock(&rdev->sched_scan_mtx); return 0; } @@ -8486,7 +8488,7 @@ static int nl80211_add_scan_req(struct sk_buff *msg, struct nlattr *nest; int i; - ASSERT_RDEV_LOCK(rdev); + lockdep_assert_held(&rdev->sched_scan_mtx); if (WARN_ON(!req)) return 0; diff --git a/net/wireless/scan.c b/net/wireless/scan.c index e93bd31d23bb..fd99ea495b7e 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -169,7 +169,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) union iwreq_data wrqu; #endif - ASSERT_RDEV_LOCK(rdev); + lockdep_assert_held(&rdev->sched_scan_mtx); request = rdev->scan_req; @@ -230,9 +230,9 @@ void __cfg80211_scan_done(struct work_struct *wk) rdev = container_of(wk, struct cfg80211_registered_device, scan_done_wk); - cfg80211_lock_rdev(rdev); + mutex_lock(&rdev->sched_scan_mtx); ___cfg80211_scan_done(rdev, false); - cfg80211_unlock_rdev(rdev); + mutex_unlock(&rdev->sched_scan_mtx); } void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) @@ -1062,6 +1062,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, if (IS_ERR(rdev)) return PTR_ERR(rdev); + mutex_lock(&rdev->sched_scan_mtx); if (rdev->scan_req) { err = -EBUSY; goto out; @@ -1168,6 +1169,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, dev_hold(dev); } out: + mutex_unlock(&rdev->sched_scan_mtx); kfree(creq); cfg80211_unlock_rdev(rdev); return err; diff --git a/net/wireless/sme.c b/net/wireless/sme.c index f432bd3755b1..09d994d192ff 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -85,6 +85,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) ASSERT_RTNL(); ASSERT_RDEV_LOCK(rdev); ASSERT_WDEV_LOCK(wdev); + lockdep_assert_held(&rdev->sched_scan_mtx); if (rdev->scan_req) return -EBUSY; @@ -320,11 +321,9 @@ void cfg80211_sme_scan_done(struct net_device *dev) { struct wireless_dev *wdev = dev->ieee80211_ptr; - mutex_lock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx); wdev_lock(wdev); __cfg80211_sme_scan_done(dev); wdev_unlock(wdev); - mutex_unlock(&wiphy_to_dev(wdev->wiphy)->devlist_mtx); } void cfg80211_sme_rx_auth(struct net_device *dev, @@ -924,9 +923,12 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, int err; mutex_lock(&rdev->devlist_mtx); + /* might request scan - scan_mtx -> wdev_mtx dependency */ + mutex_lock(&rdev->sched_scan_mtx); wdev_lock(dev->ieee80211_ptr); err = __cfg80211_connect(rdev, dev, connect, connkeys, NULL); wdev_unlock(dev->ieee80211_ptr); + mutex_unlock(&rdev->sched_scan_mtx); mutex_unlock(&rdev->devlist_mtx); return err; diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index fb9622f6d99c..e79cb5c0655a 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -89,6 +89,7 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev, cfg80211_lock_rdev(rdev); mutex_lock(&rdev->devlist_mtx); + mutex_lock(&rdev->sched_scan_mtx); wdev_lock(wdev); if (wdev->sme_state != CFG80211_SME_IDLE) { @@ -135,6 +136,7 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev, err = cfg80211_mgd_wext_connect(rdev, wdev); out: wdev_unlock(wdev); + mutex_unlock(&rdev->sched_scan_mtx); mutex_unlock(&rdev->devlist_mtx); cfg80211_unlock_rdev(rdev); return err; @@ -190,6 +192,7 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev, cfg80211_lock_rdev(rdev); mutex_lock(&rdev->devlist_mtx); + mutex_lock(&rdev->sched_scan_mtx); wdev_lock(wdev); err = 0; @@ -223,6 +226,7 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev, err = cfg80211_mgd_wext_connect(rdev, wdev); out: wdev_unlock(wdev); + mutex_unlock(&rdev->sched_scan_mtx); mutex_unlock(&rdev->devlist_mtx); cfg80211_unlock_rdev(rdev); return err; @@ -285,6 +289,7 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev, cfg80211_lock_rdev(rdev); mutex_lock(&rdev->devlist_mtx); + mutex_lock(&rdev->sched_scan_mtx); wdev_lock(wdev); if (wdev->sme_state != CFG80211_SME_IDLE) { @@ -313,6 +318,7 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev, err = cfg80211_mgd_wext_connect(rdev, wdev); out: wdev_unlock(wdev); + mutex_unlock(&rdev->sched_scan_mtx); mutex_unlock(&rdev->devlist_mtx); cfg80211_unlock_rdev(rdev); return err; -- cgit v1.2.3-55-g7522 From 370bd005937c0e00f9104a602f9fe1dd6b21b54b Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 19 Mar 2013 17:50:50 -0700 Subject: mac80211: Don't restart sta-timer if not associated. I found another crash when deleting lots of virtual stations in a congested environment. I think the problem is that the ieee80211_mlme_notify_scan_completed could call ieee80211_restart_sta_timer for a stopped interface that was about to be deleted. With the following patch I am unable to reproduce the crash. Signed-off-by: Ben Greear [move check, also make the same change in mesh] Signed-off-by: Johannes Berg --- net/mac80211/mesh.c | 3 ++- net/mac80211/mlme.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 29ce2aa87e7b..4749b3858695 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -1060,7 +1060,8 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) - if (ieee80211_vif_is_mesh(&sdata->vif)) + if (ieee80211_vif_is_mesh(&sdata->vif) && + ieee80211_sdata_running(sdata)) ieee80211_queue_work(&local->hw, &sdata->work); rcu_read_unlock(); } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 141577412d84..82cc30318a86 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3608,8 +3608,10 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) /* Restart STA timers */ rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) - ieee80211_restart_sta_timer(sdata); + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (ieee80211_sdata_running(sdata)) + ieee80211_restart_sta_timer(sdata); + } rcu_read_unlock(); } -- cgit v1.2.3-55-g7522 From 799ef90c55e692e096d8bd9e5871b95264b1e9ba Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Wed, 20 Mar 2013 22:59:11 +0100 Subject: xfrm: Fix esn sequence number diff calculation in xfrm_replay_notify_esn() Commit 0017c0b "xfrm: Fix replay notification for esn." is off by one for the sequence number wrapped case as UINT_MAX is 0xffffffff, not 0x100000000. ;) Just calculate the diff like done everywhere else in the file. Signed-off-by: Mathias Krause Signed-off-by: Steffen Klassert --- net/xfrm/xfrm_replay.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c index a3906737f49e..8dafe6d3c6e4 100644 --- a/net/xfrm/xfrm_replay.c +++ b/net/xfrm/xfrm_replay.c @@ -359,14 +359,12 @@ static void xfrm_replay_notify_esn(struct xfrm_state *x, int event) if (replay_esn->seq_hi == preplay_esn->seq_hi) seq_diff = replay_esn->seq - preplay_esn->seq; else - seq_diff = UINT_MAX - preplay_esn->seq - + replay_esn->seq; + seq_diff = ~preplay_esn->seq + replay_esn->seq + 1; if (replay_esn->oseq_hi == preplay_esn->oseq_hi) oseq_diff = replay_esn->oseq - preplay_esn->oseq; else - oseq_diff = UINT_MAX - preplay_esn->oseq - + replay_esn->oseq; + oseq_diff = ~preplay_esn->oseq + replay_esn->oseq + 1; if (seq_diff < x->replay_maxdiff && oseq_diff < x->replay_maxdiff) { -- cgit v1.2.3-55-g7522 From 3fbd45ca8d1c98f3c2582ef8bc70ade42f70947b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 25 Mar 2013 11:51:14 +0100 Subject: mac80211: fix remain-on-channel cancel crash If a ROC item is canceled just as it expires, the work struct may be scheduled while it is running (and waiting for the mutex). This results in it being run after being freed, which obviously crashes. To fix this don't free it when aborting is requested but instead mark it as "to be freed", which makes the work a no-op and allows freeing it outside. Cc: stable@vger.kernel.org [3.6+] Reported-by: Jouni Malinen Tested-by: Jouni Malinen Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 6 ++++-- net/mac80211/ieee80211_i.h | 3 ++- net/mac80211/offchannel.c | 23 +++++++++++++++++------ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index fb306814576a..a6893602f87a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -2582,7 +2582,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, list_del(&dep->list); mutex_unlock(&local->mtx); - ieee80211_roc_notify_destroy(dep); + ieee80211_roc_notify_destroy(dep, true); return 0; } @@ -2622,7 +2622,7 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, ieee80211_start_next_roc(local); mutex_unlock(&local->mtx); - ieee80211_roc_notify_destroy(found); + ieee80211_roc_notify_destroy(found, true); } else { /* work may be pending so use it all the time */ found->abort = true; @@ -2632,6 +2632,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, /* work will clean up etc */ flush_delayed_work(&found->work); + WARN_ON(!found->to_be_freed); + kfree(found); } return 0; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 388580a1bada..7bdefd901f9d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -309,6 +309,7 @@ struct ieee80211_roc_work { struct ieee80211_channel *chan; bool started, abort, hw_begun, notified; + bool to_be_freed; unsigned long hw_start_time; @@ -1347,7 +1348,7 @@ void ieee80211_offchannel_return(struct ieee80211_local *local); void ieee80211_roc_setup(struct ieee80211_local *local); void ieee80211_start_next_roc(struct ieee80211_local *local); void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); -void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc); +void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free); void ieee80211_sw_roc_work(struct work_struct *work); void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index cc79b4a2e821..430bd254e496 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -297,10 +297,13 @@ void ieee80211_start_next_roc(struct ieee80211_local *local) } } -void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) +void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc, bool free) { struct ieee80211_roc_work *dep, *tmp; + if (WARN_ON(roc->to_be_freed)) + return; + /* was never transmitted */ if (roc->frame) { cfg80211_mgmt_tx_status(&roc->sdata->wdev, @@ -316,9 +319,12 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) GFP_KERNEL); list_for_each_entry_safe(dep, tmp, &roc->dependents, list) - ieee80211_roc_notify_destroy(dep); + ieee80211_roc_notify_destroy(dep, true); - kfree(roc); + if (free) + kfree(roc); + else + roc->to_be_freed = true; } void ieee80211_sw_roc_work(struct work_struct *work) @@ -331,6 +337,9 @@ void ieee80211_sw_roc_work(struct work_struct *work) mutex_lock(&local->mtx); + if (roc->to_be_freed) + goto out_unlock; + if (roc->abort) goto finish; @@ -370,7 +379,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) finish: list_del(&roc->list); started = roc->started; - ieee80211_roc_notify_destroy(roc); + ieee80211_roc_notify_destroy(roc, !roc->abort); if (started) { drv_flush(local, false); @@ -410,7 +419,7 @@ static void ieee80211_hw_roc_done(struct work_struct *work) list_del(&roc->list); - ieee80211_roc_notify_destroy(roc); + ieee80211_roc_notify_destroy(roc, true); /* if there's another roc, start it now */ ieee80211_start_next_roc(local); @@ -460,12 +469,14 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) list_for_each_entry_safe(roc, tmp, &tmp_list, list) { if (local->ops->remain_on_channel) { list_del(&roc->list); - ieee80211_roc_notify_destroy(roc); + ieee80211_roc_notify_destroy(roc, true); } else { ieee80211_queue_delayed_work(&local->hw, &roc->work, 0); /* work will clean up etc */ flush_delayed_work(&roc->work); + WARN_ON(!roc->to_be_freed); + kfree(roc); } } -- cgit v1.2.3-55-g7522 From 130549fed828cc34c22624c6195afcf9e7ae56fe Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 21 Mar 2013 19:48:41 +0000 Subject: netfilter: reset nf_trace in nf_reset We forgot to clear the nf_trace of sk_buff in nf_reset, When we use veth device, this nf_trace information will be leaked from one net namespace to another net namespace. Signed-off-by: Gao feng Signed-off-by: Pablo Neira Ayuso --- include/linux/skbuff.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 441f5bfdab8e..72b396751de7 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2641,6 +2641,9 @@ static inline void nf_reset(struct sk_buff *skb) nf_bridge_put(skb->nf_bridge); skb->nf_bridge = NULL; #endif +#if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) + skb->nf_trace = 0; +#endif } /* Note: This doesn't put any conntrack and bridge info in dst. */ -- cgit v1.2.3-55-g7522 From 558724a5b2a73ad0c7638e21e8dffc419d267b6c Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 22 Mar 2013 01:28:18 +0000 Subject: netfilter: nfnetlink_queue: fix error return code in nfnetlink_queue_init() Fix to return a negative error code from the error handling case instead of 0, as returned elsewhere in this function. Signed-off-by: Wei Yongjun Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nfnetlink_queue_core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c index 1cb48540f86a..42680b2baa11 100644 --- a/net/netfilter/nfnetlink_queue_core.c +++ b/net/netfilter/nfnetlink_queue_core.c @@ -1062,8 +1062,10 @@ static int __init nfnetlink_queue_init(void) #ifdef CONFIG_PROC_FS if (!proc_create("nfnetlink_queue", 0440, - proc_net_netfilter, &nfqnl_file_ops)) + proc_net_netfilter, &nfqnl_file_ops)) { + status = -ENOMEM; goto cleanup_subsys; + } #endif register_netdevice_notifier(&nfqnl_dev_notifier); -- cgit v1.2.3-55-g7522 From deadcfc3324410726cd6a663fb4fc46be595abe7 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 23 Mar 2013 16:57:59 +0100 Subject: netfilter: nfnetlink_acct: return -EINVAL if object name is empty If user-space tries to create accounting object with an empty name, then return -EINVAL. Reported-by: Michael Zintakis Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nfnetlink_acct.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c index 589d686f0b4c..dc3fd5d44464 100644 --- a/net/netfilter/nfnetlink_acct.c +++ b/net/netfilter/nfnetlink_acct.c @@ -49,6 +49,8 @@ nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb, return -EINVAL; acct_name = nla_data(tb[NFACCT_NAME]); + if (strlen(acct_name) == 0) + return -EINVAL; list_for_each_entry(nfacct, &nfnl_acct_list, head) { if (strncmp(nfacct->name, acct_name, NFACCT_NAME_MAX) != 0) -- cgit v1.2.3-55-g7522 From 382a103b2b528a3085cde4ac56fc69d92a828b72 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Mar 2013 22:30:09 +0100 Subject: mac80211: fix idle handling sequence Corey Richardson reported that my idle handling cleanup (commit fd0f979a1b, "mac80211: simplify idle handling") broke ath9k_htc. The reason appears to be that it wants to go out of idle before switching channels. To fix it, reimplement that sequence. Reported-by: Corey Richardson Signed-off-by: Johannes Berg --- net/mac80211/chan.c | 17 ++++++++++++++--- net/mac80211/ieee80211_i.h | 1 + net/mac80211/iface.c | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 78c0d90dd641..931be419ab5a 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -63,6 +63,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local, enum ieee80211_chanctx_mode mode) { struct ieee80211_chanctx *ctx; + u32 changed; int err; lockdep_assert_held(&local->chanctx_mtx); @@ -76,6 +77,13 @@ ieee80211_new_chanctx(struct ieee80211_local *local, ctx->conf.rx_chains_dynamic = 1; ctx->mode = mode; + /* acquire mutex to prevent idle from changing */ + mutex_lock(&local->mtx); + /* turn idle off *before* setting channel -- some drivers need that */ + changed = ieee80211_idle_off(local); + if (changed) + ieee80211_hw_config(local, changed); + if (!local->use_chanctx) { local->_oper_channel_type = cfg80211_get_chandef_type(chandef); @@ -85,14 +93,17 @@ ieee80211_new_chanctx(struct ieee80211_local *local, err = drv_add_chanctx(local, ctx); if (err) { kfree(ctx); - return ERR_PTR(err); + ctx = ERR_PTR(err); + + ieee80211_recalc_idle(local); + goto out; } } + /* and keep the mutex held until the new chanctx is on the list */ list_add_rcu(&ctx->list, &local->chanctx_list); - mutex_lock(&local->mtx); - ieee80211_recalc_idle(local); + out: mutex_unlock(&local->mtx); return ctx; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 7bdefd901f9d..5672533a0832 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1362,6 +1362,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, enum nl80211_iftype type); void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); void ieee80211_remove_interfaces(struct ieee80211_local *local); +u32 ieee80211_idle_off(struct ieee80211_local *local); void ieee80211_recalc_idle(struct ieee80211_local *local); void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, const int offset); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 3bfe2612c8c2..58150f877ec3 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -78,7 +78,7 @@ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); } -static u32 ieee80211_idle_off(struct ieee80211_local *local) +u32 ieee80211_idle_off(struct ieee80211_local *local) { if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) return 0; -- cgit v1.2.3-55-g7522 From 0f49d64c95944f5701216e900b89aab749edcda2 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Wed, 20 Mar 2013 17:56:23 -0700 Subject: mwifiex: reset skb->data after processing PCIe sleep confirm cmd respose This patch is a bug fix for an issue wherein power save was not working for PCIe. This happens because for processing power save sleep confirm command we pull skb so that skb->data points ahead of interface header. We use same skb to get other cmda responses as well. So if we don't push skb after processing cmd response, it results into reduction in skb->len and finally skb->len reaches zero. This causes failure in processing sleep command response. Fix this by pushing skb by INTF_HEADER_LEN at the end of command response processing. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 5c395e2e6a2b..feb204613397 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -1508,6 +1508,7 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) } memcpy(adapter->upld_buf, skb->data, min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len)); + skb_push(skb, INTF_HEADER_LEN); if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_UPLD_SIZE, PCI_DMA_FROMDEVICE)) return -1; -- cgit v1.2.3-55-g7522 From 01bdcb626f80838f55ec2af993daef50b9c59c49 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Mon, 25 Mar 2013 11:00:26 -0700 Subject: bnx2fc: Make the fcoe_cltr the SCSI host parent The fcoemon userspace daemon is searching for the a hostX under the the /sys/bus/fcoe/devices/ctlrX/ entries. When interfaces created using fcoe_sysfs and fcoe.ko this linkage is setup correctly, but bnx2fc is not doing the same thing and therefore fcoemon does not create the fcoe interface for bnx2fc. This patch sets up the correct linkage for bnx2fc such that fcoemon will work correctly with fcoe_sysfs and bnx2fc. Signed-off-by: Robert Love Acked-by: Bhanu Prakash Gollapudi --- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 2daf4b0da434..cc4791cf575b 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -2133,6 +2133,7 @@ static int _bnx2fc_create(struct net_device *netdev, } ctlr = bnx2fc_to_ctlr(interface); + cdev = fcoe_ctlr_to_ctlr_dev(ctlr); interface->vlan_id = vlan_id; interface->timer_work_queue = @@ -2143,7 +2144,7 @@ static int _bnx2fc_create(struct net_device *netdev, goto ifput_err; } - lport = bnx2fc_if_create(interface, &interface->hba->pcidev->dev, 0); + lport = bnx2fc_if_create(interface, &cdev->dev, 0); if (!lport) { printk(KERN_ERR PFX "Failed to create interface (%s)\n", netdev->name); @@ -2159,8 +2160,6 @@ static int _bnx2fc_create(struct net_device *netdev, /* Make this master N_port */ ctlr->lp = lport; - cdev = fcoe_ctlr_to_ctlr_dev(ctlr); - if (link_state == BNX2FC_CREATE_LINK_UP) cdev->enabled = FCOE_CTLR_ENABLED; else -- cgit v1.2.3-55-g7522 From f9c4358edb285cead00a0d6cf0644c84ee773026 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Mon, 25 Mar 2013 11:00:27 -0700 Subject: fcoe: Fix deadlock between create and destroy paths We can deadlock (s_active and fcoe_config_mutex) if a port is being destroyed at the same time one is being created. [ 4200.503113] ====================================================== [ 4200.503114] [ INFO: possible circular locking dependency detected ] [ 4200.503116] 3.8.0-rc5+ #8 Not tainted [ 4200.503117] ------------------------------------------------------- [ 4200.503118] kworker/3:2/2492 is trying to acquire lock: [ 4200.503119] (s_active#292){++++.+}, at: [] sysfs_addrm_finish+0x3b/0x70 [ 4200.503127] but task is already holding lock: [ 4200.503128] (fcoe_config_mutex){+.+.+.}, at: [] fcoe_destroy_work+0xe8/0x120 [fcoe] [ 4200.503133] which lock already depends on the new lock. [ 4200.503135] the existing dependency chain (in reverse order) is: [ 4200.503136] -> #1 (fcoe_config_mutex){+.+.+.}: [ 4200.503139] [] lock_acquire+0xa1/0x140 [ 4200.503143] [] mutex_lock_nested+0x6e/0x360 [ 4200.503146] [] fcoe_enable+0x1d/0xb0 [fcoe] [ 4200.503148] [] fcoe_ctlr_enabled+0x2d/0x50 [fcoe] [ 4200.503151] [] store_ctlr_enabled+0x38/0x90 [libfcoe] [ 4200.503154] [] dev_attr_store+0x18/0x30 [ 4200.503157] [] sysfs_write_file+0xe0/0x150 [ 4200.503160] [] vfs_write+0xac/0x180 [ 4200.503162] [] sys_write+0x52/0xa0 [ 4200.503164] [] system_call_fastpath+0x16/0x1b [ 4200.503167] -> #0 (s_active#292){++++.+}: [ 4200.503170] [] __lock_acquire+0x135f/0x1c90 [ 4200.503172] [] lock_acquire+0xa1/0x140 [ 4200.503174] [] sysfs_deactivate+0x116/0x160 [ 4200.503176] [] sysfs_addrm_finish+0x3b/0x70 [ 4200.503178] [] sysfs_hash_and_remove+0x5b/0xb0 [ 4200.503180] [] sysfs_remove_group+0x61/0x100 [ 4200.503183] [] device_remove_groups+0x3b/0x60 [ 4200.503185] [] device_remove_attrs+0x44/0x80 [ 4200.503187] [] device_del+0x127/0x1c0 [ 4200.503189] [] device_unregister+0x22/0x60 [ 4200.503191] [] fcoe_ctlr_device_delete+0xe0/0xf0 [libfcoe] [ 4200.503194] [] fcoe_interface_cleanup+0x6c/0xa0 [fcoe] [ 4200.503196] [] fcoe_destroy_work+0x105/0x120 [fcoe] [ 4200.503198] [] process_one_work+0x1a1/0x580 [ 4200.503203] [] worker_thread+0x15e/0x440 [ 4200.503205] [] kthread+0xea/0xf0 [ 4200.503207] [] ret_from_fork+0x7c/0xb0 [ 4200.503209] other info that might help us debug this: [ 4200.503211] Possible unsafe locking scenario: [ 4200.503212] CPU0 CPU1 [ 4200.503213] ---- ---- [ 4200.503214] lock(fcoe_config_mutex); [ 4200.503215] lock(s_active#292); [ 4200.503218] lock(fcoe_config_mutex); [ 4200.503219] lock(s_active#292); [ 4200.503221] *** DEADLOCK *** [ 4200.503223] 3 locks held by kworker/3:2/2492: [ 4200.503224] #0: (fcoe){.+.+.+}, at: [] process_one_work+0x13b/0x580 [ 4200.503228] #1: ((&port->destroy_work)){+.+.+.}, at: [] process_one_work+0x13b/0x580 [ 4200.503232] #2: (fcoe_config_mutex){+.+.+.}, at: [] fcoe_destroy_work+0xe8/0x120 [fcoe] [ 4200.503236] stack backtrace: [ 4200.503238] Pid: 2492, comm: kworker/3:2 Not tainted 3.8.0-rc5+ #8 [ 4200.503240] Call Trace: [ 4200.503243] [] print_circular_bug+0x1fb/0x20c [ 4200.503246] [] __lock_acquire+0x135f/0x1c90 [ 4200.503248] [] ? debug_check_no_locks_freed+0x9a/0x180 [ 4200.503250] [] lock_acquire+0xa1/0x140 [ 4200.503253] [] ? sysfs_addrm_finish+0x3b/0x70 [ 4200.503255] [] sysfs_deactivate+0x116/0x160 [ 4200.503258] [] ? sysfs_addrm_finish+0x3b/0x70 [ 4200.503260] [] sysfs_addrm_finish+0x3b/0x70 [ 4200.503262] [] sysfs_hash_and_remove+0x5b/0xb0 [ 4200.503265] [] sysfs_remove_group+0x61/0x100 [ 4200.503273] [] device_remove_groups+0x3b/0x60 [ 4200.503275] [] device_remove_attrs+0x44/0x80 [ 4200.503277] [] device_del+0x127/0x1c0 [ 4200.503279] [] device_unregister+0x22/0x60 [ 4200.503282] [] fcoe_ctlr_device_delete+0xe0/0xf0 [libfcoe] [ 4200.503285] [] fcoe_interface_cleanup+0x6c/0xa0 [fcoe] [ 4200.503287] [] fcoe_destroy_work+0x105/0x120 [fcoe] [ 4200.503290] [] process_one_work+0x1a1/0x580 [ 4200.503292] [] ? process_one_work+0x13b/0x580 [ 4200.503295] [] ? fcoe_if_destroy+0x230/0x230 [fcoe] [ 4200.503297] [] worker_thread+0x15e/0x440 [ 4200.503299] [] ? busy_worker_rebind_fn+0x100/0x100 [ 4200.503301] [] kthread+0xea/0xf0 [ 4200.503304] [] ? kthread_create_on_node+0x160/0x160 [ 4200.503306] [] ret_from_fork+0x7c/0xb0 [ 4200.503308] [] ? kthread_create_on_node+0x160/0x160 Signed-off-by: Robert Love Tested-by: Jack Morgan --- drivers/scsi/fcoe/fcoe.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index b5d92fc93c70..9bfdc9a3f897 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -490,7 +490,6 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) { struct net_device *netdev = fcoe->netdev; struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); - struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip); rtnl_lock(); if (!fcoe->removed) @@ -501,7 +500,6 @@ static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) /* tear-down the FCoE controller */ fcoe_ctlr_destroy(fip); scsi_host_put(fip->lp->host); - fcoe_ctlr_device_delete(ctlr_dev); dev_put(netdev); module_put(THIS_MODULE); } @@ -2194,6 +2192,8 @@ out_nodev: */ static void fcoe_destroy_work(struct work_struct *work) { + struct fcoe_ctlr_device *cdev; + struct fcoe_ctlr *ctlr; struct fcoe_port *port; struct fcoe_interface *fcoe; struct Scsi_Host *shost; @@ -2224,10 +2224,15 @@ static void fcoe_destroy_work(struct work_struct *work) mutex_lock(&fcoe_config_mutex); fcoe = port->priv; + ctlr = fcoe_to_ctlr(fcoe); + cdev = fcoe_ctlr_to_ctlr_dev(ctlr); + fcoe_if_destroy(port->lport); fcoe_interface_cleanup(fcoe); mutex_unlock(&fcoe_config_mutex); + + fcoe_ctlr_device_delete(cdev); } /** @@ -2335,7 +2340,9 @@ static int _fcoe_create(struct net_device *netdev, enum fip_state fip_mode, rc = -EIO; rtnl_unlock(); fcoe_interface_cleanup(fcoe); - goto out_nortnl; + mutex_unlock(&fcoe_config_mutex); + fcoe_ctlr_device_delete(ctlr_dev); + goto out; } /* Make this the "master" N_Port */ @@ -2375,8 +2382,8 @@ static int _fcoe_create(struct net_device *netdev, enum fip_state fip_mode, out_nodev: rtnl_unlock(); -out_nortnl: mutex_unlock(&fcoe_config_mutex); +out: return rc; } -- cgit v1.2.3-55-g7522 From 8a9a71381208b2364a2d12b0d257ae333917a1bc Mon Sep 17 00:00:00 2001 From: Robert Love Date: Mon, 25 Mar 2013 11:00:27 -0700 Subject: libfc, fcoe, bnx2fc: Always use fcoe_disc_init for discovery layer initialization Currently libfcoe is doing some libfc discovery layer initialization outside of libfc. This patch moves this code into libfc and sets up a split in discovery (one time) initialization code and (re-configurable) settings that will come in the next patch. Signed-off-by: Robert Love Tested-by: Jack Morgan Reviewed-by: Bhanu Prakash Gollapudi --- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 2 +- drivers/scsi/fcoe/fcoe_ctlr.c | 11 ++++++----- drivers/scsi/libfc/fc_disc.c | 5 +++-- include/scsi/libfc.h | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index cc4791cf575b..b867b1bfa908 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -939,7 +939,7 @@ static int bnx2fc_libfc_config(struct fc_lport *lport) fc_elsct_init(lport); fc_exch_init(lport); fc_rport_init(lport); - fc_disc_init(lport); + fc_disc_init(lport, lport); return 0; } diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 08c3bc398da2..ba2f977a6e1d 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -2826,6 +2826,8 @@ unlock: int fcoe_libfc_config(struct fc_lport *lport, struct fcoe_ctlr *fip, const struct libfc_function_template *tt, int init_fcp) { + void *priv = lport; + /* Set the function pointers set by the LLDD */ memcpy(&lport->tt, tt, sizeof(*tt)); if (init_fcp && fc_fcp_init(lport)) @@ -2842,12 +2844,11 @@ int fcoe_libfc_config(struct fc_lport *lport, struct fcoe_ctlr *fip, lport->tt.disc_start = fcoe_ctlr_disc_start; lport->tt.disc_stop = fcoe_ctlr_disc_stop; lport->tt.disc_stop_final = fcoe_ctlr_disc_stop_final; - mutex_init(&lport->disc.disc_mutex); - INIT_LIST_HEAD(&lport->disc.rports); - lport->disc.priv = fip; - } else { - fc_disc_init(lport); + priv = fip; } + + fc_disc_init(lport, priv); + return 0; } EXPORT_SYMBOL_GPL(fcoe_libfc_config); diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 8e561e6a557c..141c54b97082 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c @@ -714,8 +714,9 @@ static void fc_disc_stop_final(struct fc_lport *lport) /** * fc_disc_init() - Initialize the discovery layer for a local port * @lport: The local port that needs the discovery layer to be initialized + * @priv: Private data structre for users of the discovery layer */ -int fc_disc_init(struct fc_lport *lport) +int fc_disc_init(struct fc_lport *lport, void *priv) { struct fc_disc *disc; @@ -736,7 +737,7 @@ int fc_disc_init(struct fc_lport *lport) mutex_init(&disc->disc_mutex); INIT_LIST_HEAD(&disc->rports); - disc->priv = lport; + disc->priv = priv; return 0; } diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index 399162b50a8d..add2a498bd44 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -1074,7 +1074,7 @@ void fc_rport_terminate_io(struct fc_rport *); /* * DISCOVERY LAYER *****************************/ -int fc_disc_init(struct fc_lport *); +int fc_disc_init(struct fc_lport *, void *); static inline struct fc_lport *fc_disc_lport(struct fc_disc *disc) { -- cgit v1.2.3-55-g7522 From 0807619d3c64d935c257a377ac86982c777f969c Mon Sep 17 00:00:00 2001 From: Robert Love Date: Mon, 25 Mar 2013 11:00:28 -0700 Subject: libfc, fcoe, bnx2fc: Split fc_disc_init into fc_disc_{init, config} Split discovery initialization in code that is setup once (fcoe_disc_init) and code that can be re-configured (fcoe_disc_config). Signed-off-by: Robert Love Tested-by: Jack Morgan Reviewed-by: Bhanu Prakash Gollapudi --- drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 3 ++- drivers/scsi/fcoe/fcoe_ctlr.c | 3 ++- drivers/scsi/libfc/fc_disc.c | 25 +++++++++++++++++-------- include/scsi/libfc.h | 3 ++- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index b867b1bfa908..90bc7bd00966 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -939,7 +939,8 @@ static int bnx2fc_libfc_config(struct fc_lport *lport) fc_elsct_init(lport); fc_exch_init(lport); fc_rport_init(lport); - fc_disc_init(lport, lport); + fc_disc_init(lport); + fc_disc_config(lport, lport); return 0; } diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index ba2f977a6e1d..34ee56cf4bcc 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -2847,7 +2847,8 @@ int fcoe_libfc_config(struct fc_lport *lport, struct fcoe_ctlr *fip, priv = fip; } - fc_disc_init(lport, priv); + fc_disc_init(lport); + fc_disc_config(lport, priv); return 0; } diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 141c54b97082..880a9068ca12 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c @@ -712,13 +712,13 @@ static void fc_disc_stop_final(struct fc_lport *lport) } /** - * fc_disc_init() - Initialize the discovery layer for a local port - * @lport: The local port that needs the discovery layer to be initialized + * fc_disc_config() - Configure the discovery layer for a local port + * @lport: The local port that needs the discovery layer to be configured * @priv: Private data structre for users of the discovery layer */ -int fc_disc_init(struct fc_lport *lport, void *priv) +void fc_disc_config(struct fc_lport *lport, void *priv) { - struct fc_disc *disc; + struct fc_disc *disc = &lport->disc; if (!lport->tt.disc_start) lport->tt.disc_start = fc_disc_start; @@ -733,12 +733,21 @@ int fc_disc_init(struct fc_lport *lport, void *priv) lport->tt.disc_recv_req = fc_disc_recv_req; disc = &lport->disc; - INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout); - mutex_init(&disc->disc_mutex); - INIT_LIST_HEAD(&disc->rports); disc->priv = priv; +} +EXPORT_SYMBOL(fc_disc_config); - return 0; +/** + * fc_disc_init() - Initialize the discovery layer for a local port + * @lport: The local port that needs the discovery layer to be initialized + */ +void fc_disc_init(struct fc_lport *lport) +{ + struct fc_disc *disc = &lport->disc; + + INIT_DELAYED_WORK(&disc->disc_work, fc_disc_timeout); + mutex_init(&disc->disc_mutex); + INIT_LIST_HEAD(&disc->rports); } EXPORT_SYMBOL(fc_disc_init); diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index add2a498bd44..e1379b4e8faf 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -1074,7 +1074,8 @@ void fc_rport_terminate_io(struct fc_rport *); /* * DISCOVERY LAYER *****************************/ -int fc_disc_init(struct fc_lport *, void *); +void fc_disc_init(struct fc_lport *); +void fc_disc_config(struct fc_lport *, void *); static inline struct fc_lport *fc_disc_lport(struct fc_disc *disc) { -- cgit v1.2.3-55-g7522 From 0db0e377ab5be5d507a2fca3d78215cd2e83b974 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Mon, 25 Mar 2013 11:00:28 -0700 Subject: libfcoe: Fix fcoe_sysfs VN2VN mode The libfc discovery layer is being initialized in the 'create' paths for both legacy libfcoe module parameters and fcoe_sysfs control interfaces. The problem is that for VN2VN mode the discovery layer is initialized as if it were in 'fabric' mode and it is not re-configured when the mode is changed to 'vn2vn'. This patch splits out code that needs to be initialized once and code that can, and should be, re-configured when the mode changes. Additionally this patch makes that change so that the discovery layer can be reconfigured to the libfcoe implementation when in 'vn2vn' mode. Signed-off-by: Robert Love Tested-by: Jack Morgan Reviewed-by: Bhanu Prakash Gollapudi --- drivers/scsi/fcoe/fcoe_ctlr.c | 60 ++++++++++++++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 34ee56cf4bcc..a76247201be5 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -2814,6 +2814,47 @@ unlock: fc_lport_set_local_id(fip->lp, new_port_id); } +/** + * fcoe_ctlr_mode_set() - Set or reset the ctlr's mode + * @lport: The local port to be (re)configured + * @fip: The FCoE controller whose mode is changing + * @fip_mode: The new fip mode + * + * Note that the we shouldn't be changing the libfc discovery settings + * (fc_disc_config) while an lport is going through the libfc state + * machine. The mode can only be changed when a fcoe_ctlr device is + * disabled, so that should ensure that this routine is only called + * when nothing is happening. + */ +void fcoe_ctlr_mode_set(struct fc_lport *lport, struct fcoe_ctlr *fip, + enum fip_state fip_mode) +{ + void *priv; + + WARN_ON(lport->state != LPORT_ST_RESET && + lport->state != LPORT_ST_DISABLED); + + if (fip_mode == FIP_MODE_VN2VN) { + lport->rport_priv_size = sizeof(struct fcoe_rport); + lport->point_to_multipoint = 1; + lport->tt.disc_recv_req = fcoe_ctlr_disc_recv; + lport->tt.disc_start = fcoe_ctlr_disc_start; + lport->tt.disc_stop = fcoe_ctlr_disc_stop; + lport->tt.disc_stop_final = fcoe_ctlr_disc_stop_final; + priv = fip; + } else { + lport->rport_priv_size = 0; + lport->point_to_multipoint = 0; + lport->tt.disc_recv_req = NULL; + lport->tt.disc_start = NULL; + lport->tt.disc_stop = NULL; + lport->tt.disc_stop_final = NULL; + priv = lport; + } + + fc_disc_config(lport, priv); +} + /** * fcoe_libfc_config() - Sets up libfc related properties for local port * @lport: The local port to configure libfc for @@ -2826,8 +2867,6 @@ unlock: int fcoe_libfc_config(struct fc_lport *lport, struct fcoe_ctlr *fip, const struct libfc_function_template *tt, int init_fcp) { - void *priv = lport; - /* Set the function pointers set by the LLDD */ memcpy(&lport->tt, tt, sizeof(*tt)); if (init_fcp && fc_fcp_init(lport)) @@ -2835,21 +2874,9 @@ int fcoe_libfc_config(struct fc_lport *lport, struct fcoe_ctlr *fip, fc_exch_init(lport); fc_elsct_init(lport); fc_lport_init(lport); - if (fip->mode == FIP_MODE_VN2VN) - lport->rport_priv_size = sizeof(struct fcoe_rport); fc_rport_init(lport); - if (fip->mode == FIP_MODE_VN2VN) { - lport->point_to_multipoint = 1; - lport->tt.disc_recv_req = fcoe_ctlr_disc_recv; - lport->tt.disc_start = fcoe_ctlr_disc_start; - lport->tt.disc_stop = fcoe_ctlr_disc_stop; - lport->tt.disc_stop_final = fcoe_ctlr_disc_stop_final; - priv = fip; - } - fc_disc_init(lport); - fc_disc_config(lport, priv); - + fcoe_ctlr_mode_set(lport, fip, fip->mode); return 0; } EXPORT_SYMBOL_GPL(fcoe_libfc_config); @@ -2877,6 +2904,7 @@ EXPORT_SYMBOL(fcoe_fcf_get_selected); void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *ctlr_dev) { struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); + struct fc_lport *lport = ctlr->lp; mutex_lock(&ctlr->ctlr_mutex); switch (ctlr_dev->mode) { @@ -2890,5 +2918,7 @@ void fcoe_ctlr_set_fip_mode(struct fcoe_ctlr_device *ctlr_dev) } mutex_unlock(&ctlr->ctlr_mutex); + + fcoe_ctlr_mode_set(lport, ctlr, ctlr->mode); } EXPORT_SYMBOL(fcoe_ctlr_set_fip_mode); -- cgit v1.2.3-55-g7522 From bd17381372c0740c43a9addf0d80271f647f2b38 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 25 Mar 2013 11:24:10 +0100 Subject: drm/i915: duct-tape locking when eDP init fails Thanks to apple gpu mux fail we detect an eDP output, but can't read anything over dp aux. In the resulting failure path we then hit a paranoid WARN about potential locking. Since the WARN is pretty useful for normal operation just paper over it in the failure case by grabbing the demanded (but for init/teardown not really required) lock. I've checked our driver unload code and we already don't hold the kms lock when calling drm_mode_config_cleanup. So this won't lead to a new deadlock when reloading i915.ko. v2: Make it compile. Reported-by: Dave Airlie Cc: Dave Airlie Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d7d4afe01341..8fc93f90a7cd 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2559,12 +2559,15 @@ void intel_dp_encoder_destroy(struct drm_encoder *encoder) { struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder); struct intel_dp *intel_dp = &intel_dig_port->dp; + struct drm_device *dev = intel_dp_to_dev(intel_dp); i2c_del_adapter(&intel_dp->adapter); drm_encoder_cleanup(encoder); if (is_edp(intel_dp)) { cancel_delayed_work_sync(&intel_dp->panel_vdd_work); + mutex_lock(&dev->mode_config.mutex); ironlake_panel_vdd_off_sync(intel_dp); + mutex_unlock(&dev->mode_config.mutex); } kfree(intel_dig_port); } -- cgit v1.2.3-55-g7522 From 2f3edfd7e27ad4206acbc2ae99c9df5f46353024 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 26 Mar 2013 16:46:07 +0800 Subject: ARM: imx: fix sync issue between imx_cpu_die and imx_cpu_kill There is a sync issue with hotplug operation. It's possible that when imx_cpu_kill gets running on primary core, the imx_cpu_die execution on the core which is to be killed hasn't been finished yet. The problem will very likely be hit when running suspend without no_console_suspend setting on kernel cmdline. It uses cpu jumping argument register to sync imx_cpu_die and imx_cpu_kill. The register will be set in imx_cpu_die and imx_cpu_kill will wait for the register being cleared to actually kill the cpu. Signed-off-by: Shawn Guo Cc: --- arch/arm/mach-imx/common.h | 2 ++ arch/arm/mach-imx/hotplug.c | 12 ++++++++++++ arch/arm/mach-imx/src.c | 12 ++++++++++++ 3 files changed, 26 insertions(+) diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 5a800bfcec5b..5bf4a97ab241 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -110,6 +110,8 @@ void tzic_handle_irq(struct pt_regs *); extern void imx_enable_cpu(int cpu, bool enable); extern void imx_set_cpu_jump(int cpu, void *jump_addr); +extern u32 imx_get_cpu_arg(int cpu); +extern void imx_set_cpu_arg(int cpu, u32 arg); extern void v7_cpu_resume(void); extern u32 *pl310_get_save_ptr(void); #ifdef CONFIG_SMP diff --git a/arch/arm/mach-imx/hotplug.c b/arch/arm/mach-imx/hotplug.c index 7bc5fe15dda2..361a253e2b63 100644 --- a/arch/arm/mach-imx/hotplug.c +++ b/arch/arm/mach-imx/hotplug.c @@ -46,11 +46,23 @@ static inline void cpu_enter_lowpower(void) void imx_cpu_die(unsigned int cpu) { cpu_enter_lowpower(); + /* + * We use the cpu jumping argument register to sync with + * imx_cpu_kill() which is running on cpu0 and waiting for + * the register being cleared to kill the cpu. + */ + imx_set_cpu_arg(cpu, ~0); cpu_do_idle(); } int imx_cpu_kill(unsigned int cpu) { + unsigned long timeout = jiffies + msecs_to_jiffies(50); + + while (imx_get_cpu_arg(cpu) == 0) + if (time_after(jiffies, timeout)) + return 0; imx_enable_cpu(cpu, false); + imx_set_cpu_arg(cpu, 0); return 1; } diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index e15f1555c59b..09a742f8c7ab 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c @@ -43,6 +43,18 @@ void imx_set_cpu_jump(int cpu, void *jump_addr) src_base + SRC_GPR1 + cpu * 8); } +u32 imx_get_cpu_arg(int cpu) +{ + cpu = cpu_logical_map(cpu); + return readl_relaxed(src_base + SRC_GPR1 + cpu * 8 + 4); +} + +void imx_set_cpu_arg(int cpu, u32 arg) +{ + cpu = cpu_logical_map(cpu); + writel_relaxed(arg, src_base + SRC_GPR1 + cpu * 8 + 4); +} + void imx_src_prepare_restart(void) { u32 val; -- cgit v1.2.3-55-g7522 From 39a352a5b5896403ad4ce842a9bc3845a01c02cd Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Tue, 26 Mar 2013 14:35:57 +0100 Subject: NFC: llcp: Keep the connected socket parent pointer alive And avoid decreasing the ack log twice when dequeueing connected LLCP sockets. Signed-off-by: Samuel Ortiz --- net/nfc/llcp/sock.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/nfc/llcp/sock.c b/net/nfc/llcp/sock.c index e488e440186a..8f025746f337 100644 --- a/net/nfc/llcp/sock.c +++ b/net/nfc/llcp/sock.c @@ -270,7 +270,9 @@ struct sock *nfc_llcp_accept_dequeue(struct sock *parent, } if (sk->sk_state == LLCP_CONNECTED || !newsock) { - nfc_llcp_accept_unlink(sk); + list_del_init(&lsk->accept_queue); + sock_put(sk); + if (newsock) sock_graft(sk, newsock); -- cgit v1.2.3-55-g7522 From 64a817cfbded8674f345d1117b117f942a351a69 Mon Sep 17 00:00:00 2001 From: J. Bruce Fields Date: Tue, 26 Mar 2013 14:11:13 -0400 Subject: nfsd4: reject "negative" acl lengths Since we only enforce an upper bound, not a lower bound, a "negative" length can get through here. The symptom seen was a warning when we attempt to a kmalloc with an excessive size. Reported-by: Toralf Förster Cc: stable@kernel.org Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 01168865dd37..a2720071f282 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -264,7 +264,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, iattr->ia_valid |= ATTR_SIZE; } if (bmval[0] & FATTR4_WORD0_ACL) { - int nace; + u32 nace; struct nfs4_ace *ace; READ_BUF(4); len += 4; -- cgit v1.2.3-55-g7522 From 637f44d24f8868ee5a597a99e7874fdd150d4cba Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 25 Mar 2013 15:40:05 -0400 Subject: drm/i915: Be sure to turn hsync/vsync back on at crt enable (v2) commit f40ebd6bcbbd0d30591f42dc16be52b5086a366b Author: Patrik Jakobsson Date: Tue Mar 5 14:24:48 2013 +0100 drm/i915: Turn off hsync and vsync on ADPA when disabling crt properly disabled the hsync/vsync logic at disable time, but neglected to re-enable them at enable time. v2: In the enable hook, restore the connector's expected DPMS level instead of forcing ON. Do this by stashing a back pointer to the connector in the crt (suggested by danvet) since otherwise it's awkward to look up. Signed-off-by: Adam Jackson Cc: stable@vger.kernel.org [danvet: Added more verbose commit citation and cc: stable tag. Also, make it compile. Then self-lart and try to assign the right pointer.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_crt.c | 40 +++++++++++++++++----------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 32a3693905ec..1ce45a0a2d3e 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -45,6 +45,9 @@ struct intel_crt { struct intel_encoder base; + /* DPMS state is stored in the connector, which we need in the + * encoder's enable/disable callbacks */ + struct intel_connector *connector; bool force_hotplug_required; u32 adpa_reg; }; @@ -81,29 +84,6 @@ static bool intel_crt_get_hw_state(struct intel_encoder *encoder, return true; } -static void intel_disable_crt(struct intel_encoder *encoder) -{ - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; - struct intel_crt *crt = intel_encoder_to_crt(encoder); - u32 temp; - - temp = I915_READ(crt->adpa_reg); - temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE; - temp &= ~ADPA_DAC_ENABLE; - I915_WRITE(crt->adpa_reg, temp); -} - -static void intel_enable_crt(struct intel_encoder *encoder) -{ - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; - struct intel_crt *crt = intel_encoder_to_crt(encoder); - u32 temp; - - temp = I915_READ(crt->adpa_reg); - temp |= ADPA_DAC_ENABLE; - I915_WRITE(crt->adpa_reg, temp); -} - /* Note: The caller is required to filter out dpms modes not supported by the * platform. */ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) @@ -135,6 +115,19 @@ static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) I915_WRITE(crt->adpa_reg, temp); } +static void intel_disable_crt(struct intel_encoder *encoder) +{ + intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF); +} + +static void intel_enable_crt(struct intel_encoder *encoder) +{ + struct intel_crt *crt = intel_encoder_to_crt(encoder); + + intel_crt_set_dpms(encoder, crt->connector->base.dpms); +} + + static void intel_crt_dpms(struct drm_connector *connector, int mode) { struct drm_device *dev = connector->dev; @@ -746,6 +739,7 @@ void intel_crt_init(struct drm_device *dev) } connector = &intel_connector->base; + crt->connector = intel_connector; drm_connector_init(dev, &intel_connector->base, &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); -- cgit v1.2.3-55-g7522 From fffe01f7a768d07cc50ace71abe28fbf2f786a43 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 26 Mar 2013 17:25:54 -0400 Subject: PCI: Add PCI ROM helper for platform-provided ROM images It turns out that some UEFI systems provide apparently an apparently valid PCI ROM BAR that turns out to contain garbage, so the attempt in 547b52463 to prefer the ROM from the BAR actually breaks a different set of machines. As Linus pointed out, the graphics drivers are probably in the best position to make this judgement, so this basically reverts 547b52463 and f9a37be0f and adds a new helper function. Followup patches will add support to nouveau and radeon for probing this ROM source if they can't find a ROM from some other source. [bhelgaas: added reporter and bugzilla pointers, s/f4eb5ff05/547b52463] Reference: https://bugzilla.redhat.com/show_bug.cgi?id=927451 Reference: http://lkml.kernel.org/r/kg69ef$vdb$1@ger.gmane.org Reported-by: Mantas Mikulėnas Reported-by: Chris Murphy Signed-off-by: Matthew Garrett Signed-off-by: Bjorn Helgaas --- drivers/pci/rom.c | 67 +++++++++++++++++++++++++---------------------------- include/linux/pci.h | 1 + 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index b41ac7756a4b..c5d0a08a8747 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -100,27 +100,6 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) return min((size_t)(image - rom), size); } -static loff_t pci_find_rom(struct pci_dev *pdev, size_t *size) -{ - struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; - loff_t start; - - /* assign the ROM an address if it doesn't have one */ - if (res->parent == NULL && pci_assign_resource(pdev, PCI_ROM_RESOURCE)) - return 0; - start = pci_resource_start(pdev, PCI_ROM_RESOURCE); - *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); - - if (*size == 0) - return 0; - - /* Enable ROM space decodes */ - if (pci_enable_rom(pdev)) - return 0; - - return start; -} - /** * pci_map_rom - map a PCI ROM to kernel space * @pdev: pointer to pci device struct @@ -135,7 +114,7 @@ static loff_t pci_find_rom(struct pci_dev *pdev, size_t *size) void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) { struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; - loff_t start = 0; + loff_t start; void __iomem *rom; /* @@ -154,21 +133,21 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) return (void __iomem *)(unsigned long) pci_resource_start(pdev, PCI_ROM_RESOURCE); } else { - start = pci_find_rom(pdev, size); - } - } + /* assign the ROM an address if it doesn't have one */ + if (res->parent == NULL && + pci_assign_resource(pdev,PCI_ROM_RESOURCE)) + return NULL; + start = pci_resource_start(pdev, PCI_ROM_RESOURCE); + *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); + if (*size == 0) + return NULL; - /* - * Some devices may provide ROMs via a source other than the BAR - */ - if (!start && pdev->rom && pdev->romlen) { - *size = pdev->romlen; - return phys_to_virt(pdev->rom); + /* Enable ROM space decodes */ + if (pci_enable_rom(pdev)) + return NULL; + } } - if (!start) - return NULL; - rom = ioremap(start, *size); if (!rom) { /* restore enable if ioremap fails */ @@ -202,8 +181,7 @@ void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom) if (res->flags & (IORESOURCE_ROM_COPY | IORESOURCE_ROM_BIOS_COPY)) return; - if (!pdev->rom || !pdev->romlen) - iounmap(rom); + iounmap(rom); /* Disable again before continuing, leave enabled if pci=rom */ if (!(res->flags & (IORESOURCE_ROM_ENABLE | IORESOURCE_ROM_SHADOW))) @@ -227,7 +205,24 @@ void pci_cleanup_rom(struct pci_dev *pdev) } } +/** + * pci_platform_rom - provides a pointer to any ROM image provided by the + * platform + * @pdev: pointer to pci device struct + * @size: pointer to receive size of pci window over ROM + */ +void __iomem *pci_platform_rom(struct pci_dev *pdev, size_t *size) +{ + if (pdev->rom && pdev->romlen) { + *size = pdev->romlen; + return phys_to_virt((phys_addr_t)pdev->rom); + } + + return NULL; +} + EXPORT_SYMBOL(pci_map_rom); EXPORT_SYMBOL(pci_unmap_rom); EXPORT_SYMBOL_GPL(pci_enable_rom); EXPORT_SYMBOL_GPL(pci_disable_rom); +EXPORT_SYMBOL(pci_platform_rom); diff --git a/include/linux/pci.h b/include/linux/pci.h index 2461033a7987..710067f3618c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -916,6 +916,7 @@ void pci_disable_rom(struct pci_dev *pdev); void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); +void __iomem __must_check *pci_platform_rom(struct pci_dev *pdev, size_t *size); /* Power management related routines */ int pci_save_state(struct pci_dev *dev); -- cgit v1.2.3-55-g7522 From ff931c821bab6713a52b768b0cd7ee7e90713b36 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Thu, 21 Mar 2013 16:34:52 +0530 Subject: ARM: OMAP: clocks: Delay clk inits atleast until slab is initialized clk inits on OMAP happen quite early, even before slab is available. The dependency comes from the fact that the timer init code starts to use clocks and hwmod and we need clocks to be initialized by then. There are various problems doing clk inits this early, one is, not being able to do dynamic clk registrations and hence the dependency on clk-private.h. The other is, inability to debug early kernel crashes without enabling DEBUG_LL and earlyprintk. Doing early clk init also exposed another instance of a kernel panic due to a BUG() when CONFIG_DEBUG_SLAB is enabled. [ 0.000000] Kernel BUG at c01174f8 [verbose debug info unavailable] [ 0.000000] Internal error: Oops - BUG: 0 [#1] SMP ARM [ 0.000000] Modules linked in: [ 0.000000] CPU: 0 Not tainted (3.9.0-rc1-12179-g72d48f9 #6) [ 0.000000] PC is at __kmalloc+0x1d4/0x248 [ 0.000000] LR is at __clk_init+0x2e0/0x364 [ 0.000000] pc : [] lr : [] psr: 600001d3 [ 0.000000] sp : c076ff28 ip : c065cefc fp : c0441f54 [ 0.000000] r10: 0000001c r9 : 000080d0 r8 : c076ffd4 [ 0.000000] r7 : c074b578 r6 : c0794d88 r5 : 00000040 r4 : 00000000 [ 0.000000] r3 : 00000000 r2 : c07cac70 r1 : 000080d0 r0 : 0000001c [ 0.000000] Flags: nZCv IRQs off FIQs off Mode SVC_32 ISA ARM Segment kernel [ 0.000000] Control: 10c53c7d Table: 8000404a DAC: 00000017 [ 0.000000] Process swapper (pid: 0, stack limit = 0xc076e240) [ 0.000000] Stack: (0xc076ff28 to 0xc0770000) [ 0.000000] ff20: 22222222 c0794ec8 c06546e8 00000000 00000040 c0794d88 [ 0.000000] ff40: c074b578 c076ffd4 c07951c8 c076e000 00000000 c0441f54 c074b578 c076ffd4 [ 0.000000] ff60: c0793828 00000040 c0794d88 c074b578 c076ffd4 c0776900 c076e000 c07272ac [ 0.000000] ff80: 2f800000 c074c968 c07f93d0 c0719780 c076ffa0 c076ff98 00000000 00000000 [ 0.000000] ffa0: 00000000 00000000 00000000 00000001 c074cd6c c077b1ec 8000406a c0715724 [ 0.000000] ffc0: 00000000 00000000 00000000 00000000 00000000 c074c968 10c53c7d c0776974 [ 0.000000] ffe0: c074cd6c c077b1ec 8000406a 411fc092 00000000 80008074 00000000 00000000 [ 0.000000] [] (__kmalloc+0x1d4/0x248) from [] (__clk_init+0x2e0/0x364) [ 0.000000] [] (__clk_init+0x2e0/0x364) from [] (omap4xxx_clk_init+0xbc/0x140) [ 0.000000] [] (omap4xxx_clk_init+0xbc/0x140) from [] (setup_arch+0x15c/0x284) [ 0.000000] [] (setup_arch+0x15c/0x284) from [] (start_kernel+0x7c/0x334) [ 0.000000] [] (start_kernel+0x7c/0x334) from [<80008074>] (0x80008074) [ 0.000000] Code: e5883004 e1a00006 e28dd00c e8bd8ff0 (e7f001f2) [ 0.000000] ---[ end trace 1b75b31a2719ed1c ]--- [ 0.000000] Kernel panic - not syncing: Attempted to kill the idle task! It was a know issue, that slab allocations would fail when common clock core tries to cache parent pointers for mux clocks on OMAP, and hence a patch 'clk: Allow late cache allocation for clk->parents, commit 7975059d' was added to work this problem around. A BUG() within kmalloc() with CONFIG_DEBUG_SLAB enabled was completely overlooked causing this regression. More details on the issue reported can be found here, http://www.mail-archive.com/linux-omap@vger.kernel.org/msg85932.html With all these issues around clk inits happening way too early, it makes sense to at least move them to a point where dynamic memory allocations are possible. So move them to a point just before the timer code starts using clocks and hwmod. This should at least pave way for clk inits on OMAP moving to dynamic clock registrations instead of using the static macros defined in clk-private.h. The issue with kernel panic while CONFIG_DEBUG_SLAB is enabled was reported by Piotr Haber and Tony Lindgren and this patch fixes the reported issue as well. Reported-by: Piotr Haber Reported-by: Tony Lindgren Signed-off-by: Rajendra Nayak Acked-by: Santosh Shilimkar Reviewed-by: Mike Turquette Acked-by: Paul Walmsley Cc: stable@vger.kernel.org # v3.8 Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/common.h | 3 +++ arch/arm/mach-omap2/io.c | 18 ++++++++++++------ arch/arm/mach-omap2/timer.c | 4 ++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 40f4a03d728f..d6ba13e1c540 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -293,5 +293,8 @@ extern void omap_reserve(void); struct omap_hwmod; extern int omap_dss_reset(struct omap_hwmod *); +/* SoC specific clock initializer */ +extern int (*omap_clk_init)(void); + #endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */ diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 2c3fdd65387b..5c445ca1e271 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -54,6 +54,12 @@ #include "prm3xxx.h" #include "prm44xx.h" +/* + * omap_clk_init: points to a function that does the SoC-specific + * clock initializations + */ +int (*omap_clk_init)(void); + /* * The machine specific code may provide the extra mapping besides the * default mapping provided here. @@ -397,7 +403,7 @@ void __init omap2420_init_early(void) omap242x_clockdomains_init(); omap2420_hwmod_init(); omap_hwmod_init_postsetup(); - omap2420_clk_init(); + omap_clk_init = omap2420_clk_init; } void __init omap2420_init_late(void) @@ -427,7 +433,7 @@ void __init omap2430_init_early(void) omap243x_clockdomains_init(); omap2430_hwmod_init(); omap_hwmod_init_postsetup(); - omap2430_clk_init(); + omap_clk_init = omap2430_clk_init; } void __init omap2430_init_late(void) @@ -462,7 +468,7 @@ void __init omap3_init_early(void) omap3xxx_clockdomains_init(); omap3xxx_hwmod_init(); omap_hwmod_init_postsetup(); - omap3xxx_clk_init(); + omap_clk_init = omap3xxx_clk_init; } void __init omap3430_init_early(void) @@ -500,7 +506,7 @@ void __init ti81xx_init_early(void) omap3xxx_clockdomains_init(); omap3xxx_hwmod_init(); omap_hwmod_init_postsetup(); - omap3xxx_clk_init(); + omap_clk_init = omap3xxx_clk_init; } void __init omap3_init_late(void) @@ -568,7 +574,7 @@ void __init am33xx_init_early(void) am33xx_clockdomains_init(); am33xx_hwmod_init(); omap_hwmod_init_postsetup(); - am33xx_clk_init(); + omap_clk_init = am33xx_clk_init; } #endif @@ -593,7 +599,7 @@ void __init omap4430_init_early(void) omap44xx_clockdomains_init(); omap44xx_hwmod_init(); omap_hwmod_init_postsetup(); - omap4xxx_clk_init(); + omap_clk_init = omap4xxx_clk_init; } void __init omap4430_init_late(void) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 2bdd4cf17a8f..f62b509ed08d 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -547,6 +547,8 @@ static inline void __init realtime_counter_init(void) clksrc_nr, clksrc_src) \ void __init omap##name##_gptimer_timer_init(void) \ { \ + if (omap_clk_init) \ + omap_clk_init(); \ omap_dmtimer_init(); \ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ omap2_gptimer_clocksource_init((clksrc_nr), clksrc_src); \ @@ -556,6 +558,8 @@ void __init omap##name##_gptimer_timer_init(void) \ clksrc_nr, clksrc_src) \ void __init omap##name##_sync32k_timer_init(void) \ { \ + if (omap_clk_init) \ + omap_clk_init(); \ omap_dmtimer_init(); \ omap2_gp_clockevent_init((clkev_nr), clkev_src, clkev_prop); \ /* Enable the use of clocksource="gp_timer" kernel parameter */ \ -- cgit v1.2.3-55-g7522 From 2ab3a749eb14c96eaf453afe6e678c9c1dab1637 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 5 Mar 2013 09:06:58 +0100 Subject: gpio-ich: Fix value returned by ichx_gpio_request Per Documentation/gpio.txt, gpio_request callbacks should return 0 on success or a negative value on error. So it is not clear what was meant by letting ichx_gpio_request return 1 in some cases, nor how a caller would interpret it. Align the code with the comment above it and consider pins as available by default. Signed-off-by: Jean Delvare Cc: Grant Likely Acked-by: Peter Tyser Signed-off-by: Linus Walleij --- drivers/gpio/gpio-ich.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c index f9dbd503fc40..de3c317bd3e2 100644 --- a/drivers/gpio/gpio-ich.c +++ b/drivers/gpio/gpio-ich.c @@ -214,7 +214,7 @@ static int ichx_gpio_request(struct gpio_chip *chip, unsigned nr) * If it can't be trusted, assume that the pin can be used as a GPIO. */ if (ichx_priv.desc->use_sel_ignore[nr / 32] & (1 << (nr & 0x1f))) - return 1; + return 0; return ichx_read_bit(GPIO_USE_SEL, nr) ? 0 : -ENODEV; } -- cgit v1.2.3-55-g7522 From d6b057b5dbba97e6ba13aace5270babd7c8b658c Mon Sep 17 00:00:00 2001 From: Christoph Paasch Date: Wed, 20 Mar 2013 08:59:35 +0000 Subject: e1000: ethtool: Add missing dma_mapping_error-call in e1000_setup_desc_rings After dma_map_single, dma_mapping_error must be called. Signed-off-by: Christoph Paasch Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000/e1000_ethtool.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c index 43462d596a4e..ffd287196bf8 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c +++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c @@ -1053,6 +1053,10 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) txdr->buffer_info[i].dma = dma_map_single(&pdev->dev, skb->data, skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(&pdev->dev, txdr->buffer_info[i].dma)) { + ret_val = 4; + goto err_nomem; + } tx_desc->buffer_addr = cpu_to_le64(txdr->buffer_info[i].dma); tx_desc->lower.data = cpu_to_le32(skb->len); tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP | @@ -1069,7 +1073,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rxdr->buffer_info = kcalloc(rxdr->count, sizeof(struct e1000_buffer), GFP_KERNEL); if (!rxdr->buffer_info) { - ret_val = 4; + ret_val = 5; goto err_nomem; } @@ -1077,7 +1081,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rxdr->desc = dma_alloc_coherent(&pdev->dev, rxdr->size, &rxdr->dma, GFP_KERNEL); if (!rxdr->desc) { - ret_val = 5; + ret_val = 6; goto err_nomem; } memset(rxdr->desc, 0, rxdr->size); @@ -1101,7 +1105,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL); if (!skb) { - ret_val = 6; + ret_val = 7; goto err_nomem; } skb_reserve(skb, NET_IP_ALIGN); @@ -1110,6 +1114,10 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rxdr->buffer_info[i].dma = dma_map_single(&pdev->dev, skb->data, E1000_RXBUFFER_2048, DMA_FROM_DEVICE); + if (dma_mapping_error(&pdev->dev, rxdr->buffer_info[i].dma)) { + ret_val = 8; + goto err_nomem; + } rx_desc->buffer_addr = cpu_to_le64(rxdr->buffer_info[i].dma); memset(skb->data, 0x00, skb->len); } -- cgit v1.2.3-55-g7522 From 065946c65a61943b4c609a0a1b1bac6742b3b593 Mon Sep 17 00:00:00 2001 From: Christoph Paasch Date: Wed, 20 Mar 2013 08:59:41 +0000 Subject: ixgb: Add missing dma_mapping_error-call in ixgb_alloc_rx_buffers After dma_map_single, dma_mapping_error must be called. It seems safe to not free the skb allocated in this function, as the skb can be reused later. Additionally this patch fixes one coding-style error. Signed-off-by: Christoph Paasch Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/ixgb/ixgb_main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index ea4808373435..b5f94abe3cff 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -2159,6 +2159,10 @@ map_skb: skb->data, adapter->rx_buffer_len, DMA_FROM_DEVICE); + if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { + adapter->alloc_rx_buff_failed++; + break; + } rx_desc = IXGB_RX_DESC(*rx_ring, i); rx_desc->buff_addr = cpu_to_le64(buffer_info->dma); @@ -2168,7 +2172,8 @@ map_skb: rx_desc->status = 0; - if (++i == rx_ring->count) i = 0; + if (++i == rx_ring->count) + i = 0; buffer_info = &rx_ring->buffer_info[i]; } -- cgit v1.2.3-55-g7522 From 9afd9b7090225d78ef56423a2ff65354dc38f1b1 Mon Sep 17 00:00:00 2001 From: Gabriel Fernandez Date: Mon, 18 Mar 2013 11:45:05 +0100 Subject: gpio: stmpe: pass DT node to irqdomain The irq domain was implemented but the device tree node was not transmitted to irq_domain_add_simple(). Cc: stable@vger.kernel.org Signed-off-by: Gabriel Fernandez Signed-off-by: Linus Walleij --- drivers/gpio/gpio-stmpe.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 770476a9da87..3ce5bc38ac31 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -307,11 +307,15 @@ static const struct irq_domain_ops stmpe_gpio_irq_simple_ops = { .xlate = irq_domain_xlate_twocell, }; -static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio) +static int stmpe_gpio_irq_init(struct stmpe_gpio *stmpe_gpio, + struct device_node *np) { - int base = stmpe_gpio->irq_base; + int base = 0; - stmpe_gpio->domain = irq_domain_add_simple(NULL, + if (!np) + base = stmpe_gpio->irq_base; + + stmpe_gpio->domain = irq_domain_add_simple(np, stmpe_gpio->chip.ngpio, base, &stmpe_gpio_irq_simple_ops, stmpe_gpio); if (!stmpe_gpio->domain) { @@ -346,6 +350,9 @@ static int stmpe_gpio_probe(struct platform_device *pdev) stmpe_gpio->chip = template_chip; stmpe_gpio->chip.ngpio = stmpe->num_gpios; stmpe_gpio->chip.dev = &pdev->dev; +#ifdef CONFIG_OF + stmpe_gpio->chip.of_node = np; +#endif stmpe_gpio->chip.base = pdata ? pdata->gpio_base : -1; if (pdata) @@ -366,7 +373,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev) goto out_free; if (irq >= 0) { - ret = stmpe_gpio_irq_init(stmpe_gpio); + ret = stmpe_gpio_irq_init(stmpe_gpio, np); if (ret) goto out_disable; -- cgit v1.2.3-55-g7522 From 37287fae7e4506fb0822523587c769783164cdd6 Mon Sep 17 00:00:00 2001 From: Christoph Paasch Date: Wed, 20 Mar 2013 08:59:46 +0000 Subject: e1000e: Add missing dma_mapping_error-call in e1000_alloc_jumbo_rx_buffers After dma_map_page, dma_mapping_error must be called. It seems safe to not free the skb/page allocated in this function, as the skb/page can be reused later. Signed-off-by: Christoph Paasch Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 948b86ffa4f0..7e615e2bf7e6 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -848,11 +848,16 @@ check_page: } } - if (!buffer_info->dma) + if (!buffer_info->dma) { buffer_info->dma = dma_map_page(&pdev->dev, buffer_info->page, 0, PAGE_SIZE, DMA_FROM_DEVICE); + if (dma_mapping_error(&pdev->dev, buffer_info->dma)) { + adapter->alloc_rx_buff_failed++; + break; + } + } rx_desc = E1000_RX_DESC_EXT(*rx_ring, i); rx_desc->read.buffer_addr = cpu_to_le64(buffer_info->dma); -- cgit v1.2.3-55-g7522 From f901b6bc404b67d96eca739857c097e022727b71 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 27 Mar 2013 11:36:42 +0100 Subject: can: sja1000: fix define conflict on SH Thias patch fixes a define conflict between the SH architecture and the sja1000 driver: drivers/net/can/sja1000/sja1000.h:59:0: warning: "REG_SR" redefined [enabled by default] arch/sh/include/asm/ptrace_32.h:25:0: note: this is the location of the previous definition A SJA1000_ prefix is added to the offending sja1000 define only, to make a minimal patch suited for stable. A later patch will add a SJA1000_ prefix to all defines in sja1000.h. Cc: linux-stable Reported-by: Fengguang Wu Signed-off-by: Marc Kleine-Budde --- drivers/net/can/sja1000/plx_pci.c | 4 ++-- drivers/net/can/sja1000/sja1000.c | 6 +++--- drivers/net/can/sja1000/sja1000.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c index a042cdc260dc..3c18d7d000ed 100644 --- a/drivers/net/can/sja1000/plx_pci.c +++ b/drivers/net/can/sja1000/plx_pci.c @@ -348,7 +348,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv) */ if ((priv->read_reg(priv, REG_CR) & REG_CR_BASICCAN_INITIAL_MASK) == REG_CR_BASICCAN_INITIAL && - (priv->read_reg(priv, REG_SR) == REG_SR_BASICCAN_INITIAL) && + (priv->read_reg(priv, SJA1000_REG_SR) == REG_SR_BASICCAN_INITIAL) && (priv->read_reg(priv, REG_IR) == REG_IR_BASICCAN_INITIAL)) flag = 1; @@ -360,7 +360,7 @@ static inline int plx_pci_check_sja1000(const struct sja1000_priv *priv) * See states on p. 23 of the Datasheet. */ if (priv->read_reg(priv, REG_MOD) == REG_MOD_PELICAN_INITIAL && - priv->read_reg(priv, REG_SR) == REG_SR_PELICAN_INITIAL && + priv->read_reg(priv, SJA1000_REG_SR) == REG_SR_PELICAN_INITIAL && priv->read_reg(priv, REG_IR) == REG_IR_PELICAN_INITIAL) return flag; diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index daf4013a8fc7..e4df307eaa90 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -92,7 +92,7 @@ static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val) */ spin_lock_irqsave(&priv->cmdreg_lock, flags); priv->write_reg(priv, REG_CMR, val); - priv->read_reg(priv, REG_SR); + priv->read_reg(priv, SJA1000_REG_SR); spin_unlock_irqrestore(&priv->cmdreg_lock, flags); } @@ -502,7 +502,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) { n++; - status = priv->read_reg(priv, REG_SR); + status = priv->read_reg(priv, SJA1000_REG_SR); /* check for absent controller due to hw unplug */ if (status == 0xFF && sja1000_is_absent(priv)) return IRQ_NONE; @@ -530,7 +530,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) /* receive interrupt */ while (status & SR_RBS) { sja1000_rx(dev); - status = priv->read_reg(priv, REG_SR); + status = priv->read_reg(priv, SJA1000_REG_SR); /* check for absent controller */ if (status == 0xFF && sja1000_is_absent(priv)) return IRQ_NONE; diff --git a/drivers/net/can/sja1000/sja1000.h b/drivers/net/can/sja1000/sja1000.h index afa99847a510..aa48e053da27 100644 --- a/drivers/net/can/sja1000/sja1000.h +++ b/drivers/net/can/sja1000/sja1000.h @@ -56,7 +56,7 @@ /* SJA1000 registers - manual section 6.4 (Pelican Mode) */ #define REG_MOD 0x00 #define REG_CMR 0x01 -#define REG_SR 0x02 +#define SJA1000_REG_SR 0x02 #define REG_IR 0x03 #define REG_IER 0x04 #define REG_ALC 0x0B -- cgit v1.2.3-55-g7522 From f951b6587b94df2abb8c7a2425f7dcdb4fe647dc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 27 Mar 2013 13:08:44 +0000 Subject: regmap: async: Add missing return Let's only write once... Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 3d2367501fd0..dd82acfbcf4e 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1036,6 +1036,8 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, kfree(async->work_buf); kfree(async); } + + return ret; } trace_regmap_hw_write_start(map->dev, reg, -- cgit v1.2.3-55-g7522 From 9beb09f1cadf33145c307c504f844ae24686c872 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 4 Mar 2013 20:44:39 -0800 Subject: fbdev: sh_mobile_lcdc: fixup B side hsync adjust settings The lcdc B side horizon output is shifted if sh_mobile_lcdc_pan() was called. This patch fixup this issue. It is tested on R8A7740 Armadillo800eva HDMI output. Special thanks to Fukushima-san, and Sano-san Reported-by: Osamu Fukushima Signed-off-by: Hideyuki Sano Signed-off-by: Kuninori Morimoto Acked-by: Laurent Pinchart Signed-off-by: Simon Horman --- drivers/video/sh_mobile_lcdcfb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index 63203acef812..0264704a52be 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -858,6 +858,7 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch) tmp = ((mode->xres & 7) << 24) | ((display_h_total & 7) << 16) | ((mode->hsync_len & 7) << 8) | (hsync_pos & 7); lcdc_write_chan(ch, LDHAJR, tmp); + lcdc_write_chan_mirror(ch, LDHAJR, tmp); } static void sh_mobile_lcdc_overlay_setup(struct sh_mobile_lcdc_overlay *ovl) -- cgit v1.2.3-55-g7522 From 3fd33497f80aa528ded0db2851b48638635d5caa Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 27 Mar 2013 12:47:13 +0100 Subject: can: sja1000: limit PEAK PCAN-PC Card to HAS_IOPORT This patch limits the PEAK PCAN-PC Card driver to systems with ioports. Fixes a compile time breakage on SH: drivers/net/can/sja1000/peak_pcmcia.c:626:2: error: implicit declaration of function 'ioport_unmap' Reported-by: Fengguang Wu Cc: Paul Mundt Signed-off-by: Marc Kleine-Budde --- drivers/net/can/sja1000/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig index b39ca5b3ea7f..ff2ba86cd4a4 100644 --- a/drivers/net/can/sja1000/Kconfig +++ b/drivers/net/can/sja1000/Kconfig @@ -46,6 +46,7 @@ config CAN_EMS_PCI config CAN_PEAK_PCMCIA tristate "PEAK PCAN-PC Card" depends on PCMCIA + depends on HAS_IOPORT ---help--- This driver is for the PCAN-PC Card PCMCIA adapter (1 or 2 channels) from PEAK-System (http://www.peak-system.com). To compile this -- cgit v1.2.3-55-g7522 From 27b7c63a7c509d797c151e95a641e1d94d94bbd9 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen Date: Wed, 27 Mar 2013 15:04:55 +0200 Subject: drm/i915: Fix build failure ERROR: "__build_bug_on_failed" [drivers/gpu/drm/i915/i915.ko] undefined! Originally reported at http://www.gossamer-threads.com/lists/linux/kernel/1631803 FDO bug #62775 This needs to be backported to both 3.7 and 3.8 stable trees. Doesn't apply straight, but it's a quick change. Signed-off-by: Lauri Kasanen Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=62775 Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 3b11ab0fbc96..9a48e1a2d417 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -57,7 +57,7 @@ eb_create(struct drm_i915_gem_execbuffer2 *args) if (eb == NULL) { int size = args->buffer_count; int count = PAGE_SIZE / sizeof(struct hlist_head) / 2; - BUILD_BUG_ON(!is_power_of_2(PAGE_SIZE / sizeof(struct hlist_head))); + BUILD_BUG_ON_NOT_POWER_OF_2(PAGE_SIZE / sizeof(struct hlist_head)); while (count > 2*size) count >>= 1; eb = kzalloc(count*sizeof(struct hlist_head) + -- cgit v1.2.3-55-g7522 From 54683441a92ebe20c5282465ea6f21e5e74d2974 Mon Sep 17 00:00:00 2001 From: John W. Linville Date: Wed, 27 Mar 2013 10:52:11 -0400 Subject: Revert "brcmsmac: support 4313iPA" This reverts commit b6fc28a158076ca2764edc9a6d1e1402f56e1c0c. This commit is reported to cause a regression in the support for some revisions of 4313 ePA devices. http://marc.info/?l=linux-wireless&m=136360340200943&w=2 Conflicts: drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c Reported-by: David Herrmann Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c | 369 ++++++++------------- .../wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c | 64 ++-- 2 files changed, 162 insertions(+), 271 deletions(-) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c index 21a824232478..18d37645e2cd 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c @@ -1137,9 +1137,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, gain0_15 = ((biq1 & 0xf) << 12) | ((tia & 0xf) << 8) | ((lna2 & 0x3) << 6) | - ((lna2 & 0x3) << 4) | - ((lna1 & 0x3) << 2) | - ((lna1 & 0x3) << 0); + ((lna2 & + 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0); mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); @@ -1157,8 +1156,6 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, } mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0); - mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11); - mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3); } @@ -1331,43 +1328,6 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples) return (iq_est.i_pwr + iq_est.q_pwr) / nsamples; } -static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain, - u16 tia_gain, u16 lna2_gain) -{ - u32 i_thresh_l, q_thresh_l; - u32 i_thresh_h, q_thresh_h; - struct lcnphy_iq_est iq_est_h, iq_est_l; - - wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain, - lna2_gain, 0); - - wlc_lcnphy_rx_gain_override_enable(pi, true); - wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0); - udelay(500); - write_radio_reg(pi, RADIO_2064_REG112, 0); - if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l)) - return false; - - wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0); - udelay(500); - write_radio_reg(pi, RADIO_2064_REG112, 0); - if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h)) - return false; - - i_thresh_l = (iq_est_l.i_pwr << 1); - i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr; - - q_thresh_l = (iq_est_l.q_pwr << 1); - q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr; - if ((iq_est_h.i_pwr > i_thresh_l) && - (iq_est_h.i_pwr < i_thresh_h) && - (iq_est_h.q_pwr > q_thresh_l) && - (iq_est_h.q_pwr < q_thresh_h)) - return true; - - return false; -} - static bool wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, const struct lcnphy_rx_iqcomp *iqcomp, @@ -1382,8 +1342,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old, rfoverride3_old, rfoverride3val_old, rfoverride4_old, rfoverride4val_old, afectrlovr_old, afectrlovrval_old; - int tia_gain, lna2_gain, biq1_gain; - bool set_gain; + int tia_gain; + u32 received_power, rx_pwr_threshold; u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl; u16 values_to_save[11]; s16 *ptr; @@ -1408,134 +1368,126 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, goto cal_done; } - WARN_ON(module != 1); - tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - - for (i = 0; i < 11; i++) - values_to_save[i] = - read_radio_reg(pi, rxiq_cal_rf_reg[i]); - Core1TxControl_old = read_phy_reg(pi, 0x631); - - or_phy_reg(pi, 0x631, 0x0015); - - RFOverride0_old = read_phy_reg(pi, 0x44c); - RFOverrideVal0_old = read_phy_reg(pi, 0x44d); - rfoverride2_old = read_phy_reg(pi, 0x4b0); - rfoverride2val_old = read_phy_reg(pi, 0x4b1); - rfoverride3_old = read_phy_reg(pi, 0x4f9); - rfoverride3val_old = read_phy_reg(pi, 0x4fa); - rfoverride4_old = read_phy_reg(pi, 0x938); - rfoverride4val_old = read_phy_reg(pi, 0x939); - afectrlovr_old = read_phy_reg(pi, 0x43b); - afectrlovrval_old = read_phy_reg(pi, 0x43c); - old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); - old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); - - tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); - if (tx_gain_override_old) { - wlc_lcnphy_get_tx_gain(pi, &old_gains); - tx_gain_index_old = pi_lcn->lcnphy_current_index; - } - - wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); + if (module == 1) { - mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); + tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); + for (i = 0; i < 11; i++) + values_to_save[i] = + read_radio_reg(pi, rxiq_cal_rf_reg[i]); + Core1TxControl_old = read_phy_reg(pi, 0x631); + + or_phy_reg(pi, 0x631, 0x0015); + + RFOverride0_old = read_phy_reg(pi, 0x44c); + RFOverrideVal0_old = read_phy_reg(pi, 0x44d); + rfoverride2_old = read_phy_reg(pi, 0x4b0); + rfoverride2val_old = read_phy_reg(pi, 0x4b1); + rfoverride3_old = read_phy_reg(pi, 0x4f9); + rfoverride3val_old = read_phy_reg(pi, 0x4fa); + rfoverride4_old = read_phy_reg(pi, 0x938); + rfoverride4val_old = read_phy_reg(pi, 0x939); + afectrlovr_old = read_phy_reg(pi, 0x43b); + afectrlovrval_old = read_phy_reg(pi, 0x43c); + old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); + old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); + + tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); + if (tx_gain_override_old) { + wlc_lcnphy_get_tx_gain(pi, &old_gains); + tx_gain_index_old = pi_lcn->lcnphy_current_index; + } - write_radio_reg(pi, RADIO_2064_REG116, 0x06); - write_radio_reg(pi, RADIO_2064_REG12C, 0x07); - write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); - write_radio_reg(pi, RADIO_2064_REG098, 0x03); - write_radio_reg(pi, RADIO_2064_REG00B, 0x7); - mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); - write_radio_reg(pi, RADIO_2064_REG01D, 0x01); - write_radio_reg(pi, RADIO_2064_REG114, 0x01); - write_radio_reg(pi, RADIO_2064_REG02E, 0x10); - write_radio_reg(pi, RADIO_2064_REG12A, 0x08); - - mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); - mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); - mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); + wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); - mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); + mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); - write_phy_reg(pi, 0x6da, 0xffff); - or_phy_reg(pi, 0x6db, 0x3); + mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); - wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch); - set_gain = false; - - lna2_gain = 3; - while ((lna2_gain >= 0) && !set_gain) { - tia_gain = 4; - - while ((tia_gain >= 0) && !set_gain) { - biq1_gain = 6; - - while ((biq1_gain >= 0) && !set_gain) { - set_gain = wlc_lcnphy_rx_iq_cal_gain(pi, - (u16) - biq1_gain, - (u16) - tia_gain, - (u16) - lna2_gain); - biq1_gain -= 1; - } + write_radio_reg(pi, RADIO_2064_REG116, 0x06); + write_radio_reg(pi, RADIO_2064_REG12C, 0x07); + write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); + write_radio_reg(pi, RADIO_2064_REG098, 0x03); + write_radio_reg(pi, RADIO_2064_REG00B, 0x7); + mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); + write_radio_reg(pi, RADIO_2064_REG01D, 0x01); + write_radio_reg(pi, RADIO_2064_REG114, 0x01); + write_radio_reg(pi, RADIO_2064_REG02E, 0x10); + write_radio_reg(pi, RADIO_2064_REG12A, 0x08); + + mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); + mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); + mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); + + mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); + + wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0); + write_phy_reg(pi, 0x6da, 0xffff); + or_phy_reg(pi, 0x6db, 0x3); + wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch); + wlc_lcnphy_rx_gain_override_enable(pi, true); + + tia_gain = 8; + rx_pwr_threshold = 950; + while (tia_gain > 0) { tia_gain -= 1; + wlc_lcnphy_set_rx_gain_by_distribution(pi, + 0, 0, 2, 2, + (u16) + tia_gain, 1, 0); + udelay(500); + + received_power = + wlc_lcnphy_measure_digital_power(pi, 2000); + if (received_power < rx_pwr_threshold) + break; } - lna2_gain -= 1; - } + result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff); - if (set_gain) - result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024); - else - result = false; + wlc_lcnphy_stop_tx_tone(pi); - wlc_lcnphy_stop_tx_tone(pi); + write_phy_reg(pi, 0x631, Core1TxControl_old); - write_phy_reg(pi, 0x631, Core1TxControl_old); - - write_phy_reg(pi, 0x44c, RFOverrideVal0_old); - write_phy_reg(pi, 0x44d, RFOverrideVal0_old); - write_phy_reg(pi, 0x4b0, rfoverride2_old); - write_phy_reg(pi, 0x4b1, rfoverride2val_old); - write_phy_reg(pi, 0x4f9, rfoverride3_old); - write_phy_reg(pi, 0x4fa, rfoverride3val_old); - write_phy_reg(pi, 0x938, rfoverride4_old); - write_phy_reg(pi, 0x939, rfoverride4val_old); - write_phy_reg(pi, 0x43b, afectrlovr_old); - write_phy_reg(pi, 0x43c, afectrlovrval_old); - write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); - write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); + write_phy_reg(pi, 0x44c, RFOverrideVal0_old); + write_phy_reg(pi, 0x44d, RFOverrideVal0_old); + write_phy_reg(pi, 0x4b0, rfoverride2_old); + write_phy_reg(pi, 0x4b1, rfoverride2val_old); + write_phy_reg(pi, 0x4f9, rfoverride3_old); + write_phy_reg(pi, 0x4fa, rfoverride3val_old); + write_phy_reg(pi, 0x938, rfoverride4_old); + write_phy_reg(pi, 0x939, rfoverride4val_old); + write_phy_reg(pi, 0x43b, afectrlovr_old); + write_phy_reg(pi, 0x43c, afectrlovrval_old); + write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); + write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); - wlc_lcnphy_clear_trsw_override(pi); + wlc_lcnphy_clear_trsw_override(pi); - mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); + mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); - for (i = 0; i < 11; i++) - write_radio_reg(pi, rxiq_cal_rf_reg[i], - values_to_save[i]); + for (i = 0; i < 11; i++) + write_radio_reg(pi, rxiq_cal_rf_reg[i], + values_to_save[i]); - if (tx_gain_override_old) - wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); - else - wlc_lcnphy_disable_tx_gain_override(pi); + if (tx_gain_override_old) + wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); + else + wlc_lcnphy_disable_tx_gain_override(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); - wlc_lcnphy_rx_gain_override_enable(pi, false); + wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); + wlc_lcnphy_rx_gain_override_enable(pi, false); + } cal_done: kfree(ptr); @@ -1829,17 +1781,6 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel) write_radio_reg(pi, RADIO_2064_REG038, 3); write_radio_reg(pi, RADIO_2064_REG091, 7); } - - if (!(pi->sh->boardflags & BFL_FEM)) { - u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc, - 0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0}; - - write_radio_reg(pi, RADIO_2064_REG02A, 0xf); - write_radio_reg(pi, RADIO_2064_REG091, 0x3); - write_radio_reg(pi, RADIO_2064_REG038, 0x3); - - write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]); - } } static int @@ -2034,16 +1975,6 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos) } else { mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1); mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); - mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0); - mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2); - mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0); - mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4); - mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0); - mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77); - mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1); - mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7); - mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1); - mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4); } } else { mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2); @@ -2130,14 +2061,12 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi) (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12)); mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5)); - mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0)); } static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) { struct phytbl_info tab; u32 rfseq, ind; - u8 tssi_sel; tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; tab.tbl_width = 32; @@ -2159,13 +2088,7 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4); - if (pi->sh->boardflags & BFL_FEM) { - tssi_sel = 0x1; - wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); - } else { - tssi_sel = 0xe; - wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA); - } + wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14); mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15); @@ -2201,10 +2124,9 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0); if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel); + mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe); mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); } else { - mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1); mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1); mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3); } @@ -2251,10 +2173,6 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8); - mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0); - mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0); - mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); - wlc_lcnphy_pwrctrl_rssiparams(pi); } @@ -2873,8 +2791,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) read_radio_reg(pi, RADIO_2064_REG007) & 1; u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10; u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4; - u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi); - idleTssi = read_phy_reg(pi, 0x4ab); suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & MCTL_EN_MAC)); @@ -2892,12 +2808,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4); mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2); wlc_lcnphy_tssi_setup(pi); - - mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0)); - mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6)); - - wlc_lcnphy_set_bbmult(pi, 0x0); - wlc_phy_do_dummy_tx(pi, true, OFF); idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0)) >> 0); @@ -2919,7 +2829,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12); - wlc_lcnphy_set_bbmult(pi, SAVE_bbmult); wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old); wlc_lcnphy_set_tx_gain(pi, &old_gains); wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); @@ -3133,11 +3042,6 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi) wlc_lcnphy_write_table(pi, &tab); tab.tbl_offset++; } - mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0); - mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0); - mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8); - mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4); - mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2); mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7); @@ -3939,6 +3843,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi) target_gains.pad_gain = 21; target_gains.dac_gain = 0; wlc_lcnphy_set_tx_gain(pi, &target_gains); + wlc_lcnphy_set_tx_pwr_by_index(pi, 16); if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) { @@ -3949,7 +3854,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi) lcnphy_recal ? LCNPHY_CAL_RECAL : LCNPHY_CAL_FULL), false); } else { - wlc_lcnphy_set_tx_pwr_by_index(pi, 16); wlc_lcnphy_tx_iqlo_soft_cal_full(pi); } @@ -4374,22 +4278,17 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi, if (CHSPEC_IS5G(pi->radio_chanspec)) pa_gain = 0x70; else - pa_gain = 0x60; + pa_gain = 0x70; if (pi->sh->boardflags & BFL_FEM) pa_gain = 0x10; - tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; tab.tbl_width = 32; tab.tbl_len = 1; tab.tbl_ptr = &val; for (j = 0; j < 128; j++) { - if (pi->sh->boardflags & BFL_FEM) - gm_gain = gain_table[j].gm; - else - gm_gain = 15; - + gm_gain = gain_table[j].gm; val = (((u32) pa_gain << 24) | (gain_table[j].pad << 16) | (gain_table[j].pga << 8) | gm_gain); @@ -4600,10 +4499,7 @@ static void wlc_radio_2064_init(struct brcms_phy *pi) write_phy_reg(pi, 0x4ea, 0x4688); - if (pi->sh->boardflags & BFL_FEM) - mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); - else - mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0); + mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6); @@ -4614,13 +4510,6 @@ static void wlc_radio_2064_init(struct brcms_phy *pi) wlc_lcnphy_rcal(pi); wlc_lcnphy_rc_cal(pi); - - if (!(pi->sh->boardflags & BFL_FEM)) { - write_radio_reg(pi, RADIO_2064_REG032, 0x6f); - write_radio_reg(pi, RADIO_2064_REG033, 0x19); - write_radio_reg(pi, RADIO_2064_REG039, 0xe); - } - } static void wlc_lcnphy_radio_init(struct brcms_phy *pi) @@ -4650,20 +4539,22 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi) wlc_lcnphy_write_table(pi, &tab); } - if (!(pi->sh->boardflags & BFL_FEM)) { - tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; - tab.tbl_width = 16; - tab.tbl_ptr = &val; - tab.tbl_len = 1; + tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; + tab.tbl_width = 16; + tab.tbl_ptr = &val; + tab.tbl_len = 1; - val = 150; - tab.tbl_offset = 0; - wlc_lcnphy_write_table(pi, &tab); + val = 114; + tab.tbl_offset = 0; + wlc_lcnphy_write_table(pi, &tab); - val = 220; - tab.tbl_offset = 1; - wlc_lcnphy_write_table(pi, &tab); - } + val = 130; + tab.tbl_offset = 1; + wlc_lcnphy_write_table(pi, &tab); + + val = 6; + tab.tbl_offset = 8; + wlc_lcnphy_write_table(pi, &tab); if (CHSPEC_IS2G(pi->radio_chanspec)) { if (pi->sh->boardflags & BFL_FEM) @@ -5055,7 +4946,6 @@ void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec) wlc_lcnphy_load_tx_iir_filter(pi, true, 3); mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3); - wlc_lcnphy_tssi_setup(pi); } void wlc_phy_detach_lcnphy(struct brcms_phy *pi) @@ -5094,7 +4984,8 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi) if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) return false; - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { + if ((pi->sh->boardflags & BFL_FEM) && + (LCNREV_IS(pi->pubpi.phy_rev, 1))) { if (pi_lcn->lcnphy_tempsense_option == 3) { pi->hwpwrctrl = true; pi->hwpwrctrl_capable = true; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c index b7e95acc2084..622c01ca72c5 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c @@ -1992,70 +1992,70 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = { }; static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = { - 0x0009, 0x000a, - 0x0005, - 0x0006, 0x0009, - 0x000a, - 0x0005, 0x0006, - 0x0009, - 0x000a, 0x0005, - 0x0006, - 0x0009, 0x000a, - 0x0005, - 0x0006, 0x0009, - 0x000a, - 0x0005, 0x0006, - 0x0009, - 0x000a, 0x0005, - 0x0006, - 0x0009, 0x000a, - 0x0005, - 0x0006, 0x0009, - 0x000a, - 0x0005, 0x0006, - 0x0009, - 0x000a, 0x0005, - 0x0006, - 0x0009, 0x000a, - 0x0005, - 0x0006, 0x0009, - 0x000a, - 0x0005, 0x0006, - 0x0009, - 0x000a, 0x0005, - 0x0006, + 0x000a, 0x0009, + 0x0006, + 0x0005, 0x000a, + 0x0009, + 0x0006, 0x0005, + 0x000a, + 0x0009, 0x0006, + 0x0005, + 0x000a, 0x0009, + 0x0006, + 0x0005, 0x000a, + 0x0009, + 0x0006, 0x0005, + 0x000a, + 0x0009, 0x0006, + 0x0005, + 0x000a, 0x0009, + 0x0006, + 0x0005, 0x000a, + 0x0009, + 0x0006, 0x0005, + 0x000a, + 0x0009, 0x0006, + 0x0005, + 0x000a, 0x0009, + 0x0006, + 0x0005, 0x000a, + 0x0009, + 0x0006, 0x0005, + 0x000a, + 0x0009, 0x0006, + 0x0005, }; static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = { -- cgit v1.2.3-55-g7522 From e67dd874e60529dbd2e8232babb1e23479ba2ffa Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 19 Mar 2013 07:52:48 +0100 Subject: b43: N-PHY: increase initial value of "mind" in RSSI calibration We're using "mind" variable to find the VCM that got the best polling results. For each VCM we calculte "currd" which is compared to the "mind". For PHY rev3+ "currd" gets values around 14k-40k. Looking for a value smaller than 40 makes no sense, so increase the initial value. This fixes a regression introduced in 3.4 by commit: e0c9a0219a8f542e3946fe972a68aacf8c3f906c (my BCM4322 performance dropped from 18,4Mb/s to 9,26Mb/s) Signed-off-by: Rafał Miłecki Cc: stable@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 3c35382ee6c2..e014a7a8154d 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1615,7 +1615,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) } for (i = 0; i < 4; i += 2) { s32 curr; - s32 mind = 40; + s32 mind = 0x100000; s32 minpoll = 249; u8 minvcm = 0; if (2 * core != i) @@ -1799,7 +1799,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) } for (i = 0; i < 4; i++) { - s32 mind = 40; + s32 mind = 0x100000; u8 minvcm = 0; s32 minpoll = 249; s32 curr; -- cgit v1.2.3-55-g7522 From b251412db99ccd4495ce372fec7daee27bf06923 Mon Sep 17 00:00:00 2001 From: Iestyn C. Elfick Date: Wed, 20 Mar 2013 14:02:31 -0500 Subject: b43: A fix for DMA transmission sequence errors Intermittently, b43 will report "Out of order TX status report on DMA ring". When this happens, the driver must be reset before communication can resume. The cause of the problem is believed to be an error in the closed-source firmware; however, all versions of the firmware are affected. This change uses the observation that the expected status is always 2 less than the observed value, and supplies a fake status report to skip one header/data pair. Not all devices suffer from this problem, but it can occur several times per second under heavy load. As each occurence kills the unmodified driver, this patch makes if possible for the affected devices to function. The patch logs only the first instance of the reset operation to prevent spamming the logs. Tested-by: Chris Vine Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/b43/dma.c | 65 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 38bc5a7997ff..122146943bf2 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1487,8 +1487,12 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, const struct b43_dma_ops *ops; struct b43_dmaring *ring; struct b43_dmadesc_meta *meta; + static const struct b43_txstatus fake; /* filled with 0 */ + const struct b43_txstatus *txstat; int slot, firstused; bool frame_succeed; + int skip; + static u8 err_out1, err_out2; ring = parse_cookie(dev, status->cookie, &slot); if (unlikely(!ring)) @@ -1501,13 +1505,36 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, firstused = ring->current_slot - ring->used_slots + 1; if (firstused < 0) firstused = ring->nr_slots + firstused; + + skip = 0; if (unlikely(slot != firstused)) { /* This possibly is a firmware bug and will result in - * malfunction, memory leaks and/or stall of DMA functionality. */ - b43dbg(dev->wl, "Out of order TX status report on DMA ring %d. " - "Expected %d, but got %d\n", - ring->index, firstused, slot); - return; + * malfunction, memory leaks and/or stall of DMA functionality. + */ + if (slot == next_slot(ring, next_slot(ring, firstused))) { + /* If a single header/data pair was missed, skip over + * the first two slots in an attempt to recover. + */ + slot = firstused; + skip = 2; + if (!err_out1) { + /* Report the error once. */ + b43dbg(dev->wl, + "Skip on DMA ring %d slot %d.\n", + ring->index, slot); + err_out1 = 1; + } + } else { + /* More than a single header/data pair were missed. + * Report this error once. + */ + if (!err_out2) + b43dbg(dev->wl, + "Out of order TX status report on DMA ring %d. Expected %d, but got %d\n", + ring->index, firstused, slot); + err_out2 = 1; + return; + } } ops = ring->ops; @@ -1522,11 +1549,13 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, slot, firstused, ring->index); break; } + if (meta->skb) { struct b43_private_tx_info *priv_info = - b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); + b43_get_priv_tx_info(IEEE80211_SKB_CB(meta->skb)); - unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1); + unmap_descbuffer(ring, meta->dmaaddr, + meta->skb->len, 1); kfree(priv_info->bouncebuffer); priv_info->bouncebuffer = NULL; } else { @@ -1538,8 +1567,9 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, struct ieee80211_tx_info *info; if (unlikely(!meta->skb)) { - /* This is a scatter-gather fragment of a frame, so - * the skb pointer must not be NULL. */ + /* This is a scatter-gather fragment of a frame, + * so the skb pointer must not be NULL. + */ b43dbg(dev->wl, "TX status unexpected NULL skb " "at slot %d (first=%d) on ring %d\n", slot, firstused, ring->index); @@ -1550,9 +1580,18 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, /* * Call back to inform the ieee80211 subsystem about - * the status of the transmission. + * the status of the transmission. When skipping over + * a missed TX status report, use a status structure + * filled with zeros to indicate that the frame was not + * sent (frame_count 0) and not acknowledged */ - frame_succeed = b43_fill_txstatus_report(dev, info, status); + if (unlikely(skip)) + txstat = &fake; + else + txstat = status; + + frame_succeed = b43_fill_txstatus_report(dev, info, + txstat); #ifdef CONFIG_B43_DEBUG if (frame_succeed) ring->nr_succeed_tx_packets++; @@ -1580,12 +1619,14 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, /* Everything unmapped and free'd. So it's not used anymore. */ ring->used_slots--; - if (meta->is_last_fragment) { + if (meta->is_last_fragment && !skip) { /* This is the last scatter-gather * fragment of the frame. We are done. */ break; } slot = next_slot(ring, slot); + if (skip > 0) + --skip; } if (ring->stopped) { B43_WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME); -- cgit v1.2.3-55-g7522 From 7fc0357479eeff4ca808c4d8c09bc7631f576b8d Mon Sep 17 00:00:00 2001 From: Luis R. Rodriguez Date: Mon, 25 Mar 2013 11:27:46 -0700 Subject: ath9k: avoid queueing hw check work when suspended The following issue was reported. WARNING: at net/mac80211/util.c:599 ieee80211_can_queue_work.isra.7+0x32/0x40 [mac80211]() Hardware name: iMac12,1 queueing ieee80211 work while going to suspend Pid: 0, comm: swapper/0 Tainted: PF O 3.8.2-206.fc18.x86_64 #1 Call Trace: Mar 16 09:39:17 Parags-iMac kernel: [ 3993.642992] [] warn_slowpath_common+0x7f/0xc0 [] ? ath_start_rx_poll+0x70/0x70 [ath9k] ] warn_slowpath_fmt+0x46/0x50 [] ieee80211_can_queue_work.isra.7+0x32/0x40 Fix this by avoiding to queue the work if our device has already been marked as suspended or stopped. Reported-by: Parag Warudkar Tested-by: Parag Warudkar Cc: stable@vger.kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/link.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index 39c84ecf6a42..7fdac6c7b3ea 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c @@ -170,7 +170,8 @@ void ath_rx_poll(unsigned long data) { struct ath_softc *sc = (struct ath_softc *)data; - ieee80211_queue_work(sc->hw, &sc->hw_check_work); + if (!test_bit(SC_OP_INVALID, &sc->sc_flags)) + ieee80211_queue_work(sc->hw, &sc->hw_check_work); } /* -- cgit v1.2.3-55-g7522 From ace5af39866da7d45f43774150dace19a73716d6 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Tue, 26 Mar 2013 17:35:23 +0000 Subject: iwlegacy: 4965-rs: avoid null pointer dereference error il4965_rs_initialize_lq checks to see if sta is null, however, before that check il4965_rs_use_green dereferences sta when intializing use_green. Avoid a potential null pointer dereference error by only calling il4965_rs_use_green after we are sure sta is not null. Smatch analysis: drivers/net/wireless/iwlegacy/4965-rs.c:2160 il4965_rs_initialize_lq() warn: variable dereferenced before check 'sta' (see line 2155) Signed-off-by: Colin Ian King Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/4965-rs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c index e8324b5e5bfe..6c7493c2d698 100644 --- a/drivers/net/wireless/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/iwlegacy/4965-rs.c @@ -2152,7 +2152,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf, int rate_idx; int i; u32 rate; - u8 use_green = il4965_rs_use_green(il, sta); + u8 use_green; u8 active_tbl = 0; u8 valid_tx_ant; struct il_station_priv *sta_priv; @@ -2160,6 +2160,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf, if (!sta || !lq_sta) return; + use_green = il4965_rs_use_green(il, sta); sta_priv = (void *)sta->drv_priv; i = lq_sta->last_txrate_idx; -- cgit v1.2.3-55-g7522 From 8ac3e99e693cb876776646c07f0a954a17ee3017 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 26 Mar 2013 14:40:51 -0500 Subject: libertas: drop maintainership Would be better maintained by somebody who actualy has time for it. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- MAINTAINERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 95616582c728..92efc747e726 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5043,9 +5043,8 @@ S: Maintained F: drivers/net/ethernet/marvell/sk* MARVELL LIBERTAS WIRELESS DRIVER -M: Dan Williams L: libertas-dev@lists.infradead.org -S: Maintained +S: Orphan F: drivers/net/wireless/libertas/ MARVELL MV643XX ETHERNET DRIVER -- cgit v1.2.3-55-g7522 From 2e1253d640eb7f8707d2591c93097c1e9f9c71d5 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Wed, 27 Mar 2013 08:37:08 +0100 Subject: b43: N-PHY: use more bits for offset in RSSI calibration When calculating "offset" for final RSSI calibration we're using numbers bigger than s8 can hold. We have for example: offset[j] = 232 - poll_results[j]; formula. If poll_results[j] is small enough (it usually is) we treat number's bit as a sign bit. For example 232 - 1 becomes: 0xE8 - 0x1 = 0xE7, which is not 231 but -25. This code was introduced in e0c9a0219a8f542e3946fe972a68aacf8c3f906c and caused stability regression on some cards, for ex. BCM4322. Signed-off-by: Rafał Miłecki Cc: stable@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index e014a7a8154d..e8486c1e091a 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1564,7 +1564,7 @@ static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) u16 clip_off[2] = { 0xFFFF, 0xFFFF }; u8 vcm_final = 0; - s8 offset[4]; + s32 offset[4]; s32 results[8][4] = { }; s32 results_min[4] = { }; s32 poll_results[4] = { }; @@ -1732,7 +1732,7 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) u8 regs_save_radio[2]; u16 regs_save_phy[2]; - s8 offset[4]; + s32 offset[4]; u8 core; u8 rail; -- cgit v1.2.3-55-g7522 From 5389090b59f7f72a30e25f5fd1fc560340543970 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 27 Mar 2013 03:57:10 +0000 Subject: netfilter: nf_conntrack: fix error return code Fix to return a negative error code from the error handling case instead of 0, as returned elsewhere in function nf_conntrack_standalone_init(). Signed-off-by: Wei Yongjun Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_standalone.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c index 6bcce401fd1c..fedee3943661 100644 --- a/net/netfilter/nf_conntrack_standalone.c +++ b/net/netfilter/nf_conntrack_standalone.c @@ -568,6 +568,7 @@ static int __init nf_conntrack_standalone_init(void) register_net_sysctl(&init_net, "net", nf_ct_netfilter_table); if (!nf_ct_netfilter_header) { pr_err("nf_conntrack: can't register to sysctl.\n"); + ret = -ENOMEM; goto out_sysctl; } #endif -- cgit v1.2.3-55-g7522 From 14109a59caf93e6eae726a34bf2f0897508ec8c1 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Tue, 26 Mar 2013 16:12:03 +0000 Subject: enet: fec: fix fail resume from suspend state Without this patch 1. boot with nfs (no_console_suspend) 2. echo mem >/sys/power/state 3. wakeup by wakesource 4. print "eth0: tx queue full" This fix above problem by reinit bd queue at restart function Signed-off-by: Frank Li Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 82 ++++++++++++++++++++++-------------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 911d0253dbb2..f292c3aa423f 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -345,6 +345,53 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) return NETDEV_TX_OK; } +/* Init RX & TX buffer descriptors + */ +static void fec_enet_bd_init(struct net_device *dev) +{ + struct fec_enet_private *fep = netdev_priv(dev); + struct bufdesc *bdp; + unsigned int i; + + /* Initialize the receive buffer descriptors. */ + bdp = fep->rx_bd_base; + for (i = 0; i < RX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. */ + if (bdp->cbd_bufaddr) + bdp->cbd_sc = BD_ENET_RX_EMPTY; + else + bdp->cbd_sc = 0; + bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); + } + + /* Set the last buffer to wrap */ + bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); + bdp->cbd_sc |= BD_SC_WRAP; + + fep->cur_rx = fep->rx_bd_base; + + /* ...and the same for transmit */ + bdp = fep->tx_bd_base; + fep->cur_tx = bdp; + for (i = 0; i < TX_RING_SIZE; i++) { + + /* Initialize the BD for every fragment in the page. */ + bdp->cbd_sc = 0; + if (bdp->cbd_bufaddr && fep->tx_skbuff[i]) { + dev_kfree_skb_any(fep->tx_skbuff[i]); + fep->tx_skbuff[i] = NULL; + } + bdp->cbd_bufaddr = 0; + bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); + } + + /* Set the last buffer to wrap */ + bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); + bdp->cbd_sc |= BD_SC_WRAP; + fep->dirty_tx = bdp; +} + /* This function is called to start or restart the FEC during a link * change. This only happens when switching between half and full * duplex. @@ -388,6 +435,8 @@ fec_restart(struct net_device *ndev, int duplex) /* Set maximum receive buffer size. */ writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE); + fec_enet_bd_init(ndev); + /* Set receive and transmit descriptor base. */ writel(fep->bd_dma, fep->hwp + FEC_R_DES_START); if (fep->bufdesc_ex) @@ -397,7 +446,6 @@ fec_restart(struct net_device *ndev, int duplex) writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, fep->hwp + FEC_X_DES_START); - fep->cur_rx = fep->rx_bd_base; for (i = 0; i <= TX_RING_MOD_MASK; i++) { if (fep->tx_skbuff[i]) { @@ -1597,8 +1645,6 @@ static int fec_enet_init(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); struct bufdesc *cbd_base; - struct bufdesc *bdp; - unsigned int i; /* Allocate memory for buffer descriptors. */ cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma, @@ -1608,6 +1654,7 @@ static int fec_enet_init(struct net_device *ndev) return -ENOMEM; } + memset(cbd_base, 0, PAGE_SIZE); spin_lock_init(&fep->hw_lock); fep->netdev = ndev; @@ -1631,35 +1678,6 @@ static int fec_enet_init(struct net_device *ndev) writel(FEC_RX_DISABLED_IMASK, fep->hwp + FEC_IMASK); netif_napi_add(ndev, &fep->napi, fec_enet_rx_napi, FEC_NAPI_WEIGHT); - /* Initialize the receive buffer descriptors. */ - bdp = fep->rx_bd_base; - for (i = 0; i < RX_RING_SIZE; i++) { - - /* Initialize the BD for every fragment in the page. */ - bdp->cbd_sc = 0; - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); - } - - /* Set the last buffer to wrap */ - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); - bdp->cbd_sc |= BD_SC_WRAP; - - /* ...and the same for transmit */ - bdp = fep->tx_bd_base; - fep->cur_tx = bdp; - for (i = 0; i < TX_RING_SIZE; i++) { - - /* Initialize the BD for every fragment in the page. */ - bdp->cbd_sc = 0; - bdp->cbd_bufaddr = 0; - bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); - } - - /* Set the last buffer to wrap */ - bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); - bdp->cbd_sc |= BD_SC_WRAP; - fep->dirty_tx = bdp; - fec_restart(ndev, 0); return 0; -- cgit v1.2.3-55-g7522 From fcca143d696092110ae1e361866576804fe887f3 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 27 Mar 2013 03:22:45 +0000 Subject: rtnetlink: fix error return code in rtnl_link_fill() Fix to return a negative error code from the error handling case instead of 0(possible overwrite to 0 by ops->fill_xstats call), as returned elsewhere in this function. Signed-off-by: Wei Yongjun Signed-off-by: David S. Miller --- net/core/rtnetlink.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 5fb8d7e47294..b65441da74ab 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -496,8 +496,10 @@ static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev) } if (ops->fill_info) { data = nla_nest_start(skb, IFLA_INFO_DATA); - if (data == NULL) + if (data == NULL) { + err = -EMSGSIZE; goto err_cancel_link; + } err = ops->fill_info(skb, dev); if (err < 0) goto err_cancel_data; -- cgit v1.2.3-55-g7522 From b56d6b3fca6d1214dbc9c5655f26e5d4ec04afc8 Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Wed, 27 Mar 2013 04:41:59 +0000 Subject: drivers: net: ethernet: cpsw: use netif_wake_queue() while restarting tx queue To restart tx queue use netif_wake_queue() intead of netif_start_queue() so that net schedule will restart transmission immediately which will increase network performance while doing huge data transfers. Reported-by: Dan Franke Suggested-by: Sriramakrishnan A G Signed-off-by: Mugunthan V N Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index df32a090d08e..80cad06e5eb2 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -436,7 +436,7 @@ void cpsw_tx_handler(void *token, int len, int status) * queue is stopped then start the queue as we have free desc for tx */ if (unlikely(netif_queue_stopped(ndev))) - netif_start_queue(ndev); + netif_wake_queue(ndev); cpts_tx_timestamp(priv->cpts, skb); priv->stats.tx_packets++; priv->stats.tx_bytes += len; -- cgit v1.2.3-55-g7522 From 7e51cde276ca820d526c6c21cf8147df595a36bf Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Wed, 27 Mar 2013 04:42:00 +0000 Subject: drivers: net: ethernet: davinci_emac: use netif_wake_queue() while restarting tx queue To restart tx queue use netif_wake_queue() intead of netif_start_queue() so that net schedule will restart transmission immediately which will increase network performance while doing huge data transfers. Reported-by: Dan Franke Suggested-by: Sriramakrishnan A G Signed-off-by: Mugunthan V N Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/davinci_emac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index ae1b77aa199f..72300bc9e378 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1053,7 +1053,7 @@ static void emac_tx_handler(void *token, int len, int status) * queue is stopped then start the queue as we have free desc for tx */ if (unlikely(netif_queue_stopped(ndev))) - netif_start_queue(ndev); + netif_wake_queue(ndev); ndev->stats.tx_packets++; ndev->stats.tx_bytes += len; dev_kfree_skb_any(skb); -- cgit v1.2.3-55-g7522 From ea872d7712528ad991bdabb63515bc00ee10993e Mon Sep 17 00:00:00 2001 From: Sergey Popovich Date: Wed, 27 Mar 2013 05:41:59 +0000 Subject: sch: add missing u64 in psched_ratecfg_precompute() It seems that commit commit 292f1c7ff6cc10516076ceeea45ed11833bb71c7 Author: Jiri Pirko Date: Tue Feb 12 00:12:03 2013 +0000 sch: make htb_rate_cfg and functions around that generic adds little regression. Before: # tc qdisc add dev eth0 root handle 1: htb default ffff # tc class add dev eth0 classid 1:ffff htb rate 5Gbit # tc -s class show dev eth0 class htb 1:ffff root prio 0 rate 5000Mbit ceil 5000Mbit burst 625b cburst 625b Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0) rate 0bit 0pps backlog 0b 0p requeues 0 lended: 0 borrowed: 0 giants: 0 tokens: 31 ctokens: 31 After: # tc qdisc add dev eth0 root handle 1: htb default ffff # tc class add dev eth0 classid 1:ffff htb rate 5Gbit # tc -s class show dev eth0 class htb 1:ffff root prio 0 rate 1544Mbit ceil 1544Mbit burst 625b cburst 625b Sent 5073 bytes 41 pkt (dropped 0, overlimits 0 requeues 0) rate 1976bit 2pps backlog 0b 0p requeues 0 lended: 41 borrowed: 0 giants: 0 tokens: 1802 ctokens: 1802 This probably due to lost u64 cast of rate parameter in psched_ratecfg_precompute() (net/sched/sch_generic.c). Signed-off-by: Sergey Popovich Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/sched/sch_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index ffad48109a22..eac7e0ee23c1 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -904,7 +904,7 @@ void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate) u64 mult; int shift; - r->rate_bps = rate << 3; + r->rate_bps = (u64)rate << 3; r->shift = 0; r->mult = 1; /* -- cgit v1.2.3-55-g7522 From 715230a44310a8cf66fbfb5a46f9a62a9b2de424 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 27 Mar 2013 06:40:50 +0000 Subject: tg3: fix length overflow in VPD firmware parsing Commit 184b89044fb6e2a74611dafa69b1dce0d98612c6 ("tg3: Use VPD fw version when present") introduced VPD parsing that contained a potential length overflow. Limit the hardware's reported firmware string length (max 255 bytes) to stay inside the driver's firmware string length (32 bytes). On overflow, truncate the formatted firmware string instead of potentially overwriting portions of the tg3 struct. http://cansecwest.com/slides/2013/PrivateCore%20CSW%202013.pdf Signed-off-by: Kees Cook Reported-by: Oded Horovitz Reported-by: Brad Spengler Cc: stable@vger.kernel.org Cc: Matt Carlson Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 67d2663b3974..17a972734ba7 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -14604,8 +14604,11 @@ static void tg3_read_vpd(struct tg3 *tp) if (j + len > block_end) goto partno; - memcpy(tp->fw_ver, &vpd_data[j], len); - strncat(tp->fw_ver, " bc ", vpdlen - len - 1); + if (len >= sizeof(tp->fw_ver)) + len = sizeof(tp->fw_ver) - 1; + memset(tp->fw_ver, 0, sizeof(tp->fw_ver)); + snprintf(tp->fw_ver, sizeof(tp->fw_ver), "%.*s bc ", len, + &vpd_data[j]); } partno: -- cgit v1.2.3-55-g7522 From 24f11a5cf538a8fcc10d61f457e9a2094fb965b4 Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 27 Mar 2013 06:54:00 +0000 Subject: line up comment for ndo_bridge_getlink Signed-off-by: Dmitry Kravkov Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b3d00fa4b314..8bfa95600e48 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -895,7 +895,7 @@ struct netdev_fcoe_hbainfo { * * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh) * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq, - * struct net_device *dev) + * struct net_device *dev, u32 filter_mask) * * int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier); * Called to change device carrier. Soft-devices (like dummy, team, etc) -- cgit v1.2.3-55-g7522 From e73081d9afd4b5fe285d2a585a73d9c6f73ab0dd Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 26 Mar 2013 10:26:15 +0000 Subject: ARM: ux500: Apply the TCPM and TCDM locations and sizes to dbx5x0 DT This fixes a regression introduced by commit: 05ec260 mfd:db8500-prcmu: update resource passing All DBx5x0 based SoCs have access to two Tightly Coupled Memory (TCM) locations based on the PRCMU itself. One area from program memory (TCPM) and one for data memory (TCDM). The PRCMU needs to know where these are in order to function correctly. However, these are currently passed though platform device resources, which can only be obtained if Device Tree booting isn't in use. Thus we must also support them in DT by supplying them through the PRCMU node. Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- arch/arm/boot/dts/dbx5x0.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/dbx5x0.dtsi b/arch/arm/boot/dts/dbx5x0.dtsi index 9de93096601a..aaa63d0a8096 100644 --- a/arch/arm/boot/dts/dbx5x0.dtsi +++ b/arch/arm/boot/dts/dbx5x0.dtsi @@ -191,8 +191,8 @@ prcmu: prcmu@80157000 { compatible = "stericsson,db8500-prcmu"; - reg = <0x80157000 0x1000>; - reg-names = "prcmu"; + reg = <0x80157000 0x1000>, <0x801b0000 0x8000>, <0x801b8000 0x1000>; + reg-names = "prcmu", "prcmu-tcpm", "prcmu-tcdm"; interrupts = <0 47 0x4>; #address-cells = <1>; #size-cells = <1>; -- cgit v1.2.3-55-g7522 From 26135256d3e7d4d12c6268623edc1740888c041f Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 27 Mar 2013 10:47:38 +0000 Subject: ARM: ux500: Stop passing ios_handler() as an MMCI power controlling call-back This fixes a regression introduced during the v3.9 merge window. Now MMCI on/off functionality is using the regulator framework from the MMCI driver, if we provide the ios_handler call-back we essentially duplicate functionality, which causes a large mess and lots of booting issues. Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/board-mop500-sdi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 051b62c27102..7f2cb6c5e2c1 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -81,7 +81,6 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { #endif struct mmci_platform_data mop500_sdi0_data = { - .ios_handler = mop500_sdi0_ios_handler, .ocr_mask = MMC_VDD_29_30, .f_max = 50000000, .capabilities = MMC_CAP_4_BIT_DATA | -- cgit v1.2.3-55-g7522 From 265c3c0a64df50c0e8fe55cfe8af8851ed5feca5 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Wed, 27 Mar 2013 14:13:53 +0000 Subject: ARM: ux500: Enable the clock controlling Ethernet on Snowball This fixes a regression introduced by common clk enablement. On some u8500 based boards, the FMSC clock which is usually used for flash, is wired up to the SMSC911x Ethernet driver. However, the SMSC911x doesn't have common clk support yet, rendering it unusable. Prior to the introduction of common clk the FMSC clock was default on; however, common clk disables all clocks by default and insists drivers take responsibility to enable theirs. This fix enables the FMSC clock on Snowball, subsequently turning on the SMSC911x Ethernet chip. It will be removed when the driver is compatible with common clk. Signed-off-by: Lee Jones Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/board-mop500.c | 12 ++++++++++++ arch/arm/mach-ux500/board-mop500.h | 1 + arch/arm/mach-ux500/cpu-db8500.c | 5 +++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index b03457881c4b..87d2d7b38ce9 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -439,6 +440,15 @@ static void mop500_prox_deactivate(struct device *dev) regulator_put(prox_regulator); } +void mop500_snowball_ethernet_clock_enable(void) +{ + struct clk *clk; + + clk = clk_get_sys("fsmc", NULL); + if (!IS_ERR(clk)) + clk_prepare_enable(clk); +} + static struct cryp_platform_data u8500_cryp1_platform_data = { .mem_to_engine = { .dir = STEDMA40_MEM_TO_PERIPH, @@ -683,6 +693,8 @@ static void __init snowball_init_machine(void) mop500_audio_init(parent); mop500_uart_init(parent); + mop500_snowball_ethernet_clock_enable(); + /* This board has full regulator constraints */ regulator_has_full_constraints(); } diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h index eaa605f5d90d..d38951be70df 100644 --- a/arch/arm/mach-ux500/board-mop500.h +++ b/arch/arm/mach-ux500/board-mop500.h @@ -104,6 +104,7 @@ void __init mop500_pinmaps_init(void); void __init snowball_pinmaps_init(void); void __init hrefv60_pinmaps_init(void); void mop500_audio_init(struct device *parent); +void mop500_snowball_ethernet_clock_enable(void); int __init mop500_uib_init(void); void mop500_uib_i2c_add(int busnum, struct i2c_board_info *info, diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 19235cf7bbe3..f1a581844372 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -312,9 +312,10 @@ static void __init u8500_init_machine(void) /* Pinmaps must be in place before devices register */ if (of_machine_is_compatible("st-ericsson,mop500")) mop500_pinmaps_init(); - else if (of_machine_is_compatible("calaosystems,snowball-a9500")) + else if (of_machine_is_compatible("calaosystems,snowball-a9500")) { snowball_pinmaps_init(); - else if (of_machine_is_compatible("st-ericsson,hrefv60+")) + mop500_snowball_ethernet_clock_enable(); + } else if (of_machine_is_compatible("st-ericsson,hrefv60+")) hrefv60_pinmaps_init(); else if (of_machine_is_compatible("st-ericsson,ccu9540")) {} /* TODO: Add pinmaps for ccu9540 board. */ -- cgit v1.2.3-55-g7522 From 8abbbaf6adb46157b6bd416f7616b555cc6a332f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 27 Mar 2013 21:42:00 +0100 Subject: drm: don't unlock in the addfb error paths We don't grab the modeset locks any more since commit 468174f748603497e73dba9b5c6d1d9f71121486 Author: Daniel Vetter Date: Tue Dec 11 00:09:12 2012 +0100 drm: push modeset_lock_all into ->fb_create driver callbacks Reported-by: Ray Strode Cc: Ray Strode Cc: Dave Airlie Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 792c3e3795ca..dd64a06dc5b4 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2326,7 +2326,6 @@ int drm_mode_addfb(struct drm_device *dev, fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r); if (IS_ERR(fb)) { DRM_DEBUG_KMS("could not create framebuffer\n"); - drm_modeset_unlock_all(dev); return PTR_ERR(fb); } @@ -2506,7 +2505,6 @@ int drm_mode_addfb2(struct drm_device *dev, fb = dev->mode_config.funcs->fb_create(dev, file_priv, r); if (IS_ERR(fb)) { DRM_DEBUG_KMS("could not create framebuffer\n"); - drm_modeset_unlock_all(dev); return PTR_ERR(fb); } -- cgit v1.2.3-55-g7522 From b8730b403aee94db4631bfefb546a6ce8c287dc2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 27 Mar 2013 20:49:58 +0100 Subject: iwlwifi: dvm: fix the passive-no-RX workaround Alex Romosan reported that since the mac80211 changes in "mac80211: start auth/assoc timeout on frame status" and the subsequent fixes in "mac80211: fix auth/assoc timeout handling" (commits 1672c0e31917 and 89afe614c0c) there's sometimes an issue connecting to a 5 GHz network with the iwlwifi DVM driver. The reason appears to be that since these commits any bad TX status makes mac80211 immediately try again, causing all of the authentication attempts to be quickly rejected by the firmware as it hasn't heard a beacon yet. Before, it would wait for the timeout regardless of status. To fix this, invoke the passive-no-RX workaround when not associated yet as well. This will cause the first frame to get lost, but then the driver will stop the queues and the second attempt will only be transmitted after hearing a beacon, thus delaying it appropriately to not make the firmware reject it again. Reported-by: Alex Romosan Tested-by: Alex Romosan Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/rxon.c | 18 ++++++++---------- drivers/net/wireless/iwlwifi/dvm/tx.c | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index 23be948cf162..a82b6b39d4ff 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c @@ -1419,6 +1419,14 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); + if (changes & BSS_CHANGED_IDLE && bss_conf->idle) { + /* + * If we go idle, then clearly no "passive-no-rx" + * workaround is needed any more, this is a reset. + */ + iwlagn_lift_passive_no_rx(priv); + } + if (unlikely(!iwl_is_ready(priv))) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); mutex_unlock(&priv->mutex); @@ -1450,16 +1458,6 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, priv->timestamp = bss_conf->sync_tsf; ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; } else { - /* - * If we disassociate while there are pending - * frames, just wake up the queues and let the - * frames "escape" ... This shouldn't really - * be happening to start with, but we should - * not get stuck in this case either since it - * can happen if userspace gets confused. - */ - iwlagn_lift_passive_no_rx(priv); - ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; if (ctx->ctxid == IWL_RXON_CTX_BSS) diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 6aec2df3bb27..d1a670d7b10c 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -1192,7 +1192,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, memset(&info->status, 0, sizeof(info->status)); if (status == TX_STATUS_FAIL_PASSIVE_NO_RX && - iwl_is_associated_ctx(ctx) && ctx->vif && + ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) { /* block and stop all queues */ priv->passive_no_rx = true; -- cgit v1.2.3-55-g7522 From 2992714d431976c4b154875bd18ba61bf4df3b93 Mon Sep 17 00:00:00 2001 From: Eric Hutter Date: Mon, 18 Mar 2013 19:48:56 +0100 Subject: ARM: kirkwood: Fix chip-delay for GoFlex Net This fixes "Too few good blocks within range" issues on GoFlex Net by setting chip-delay to 40. The basic problem was discussed at http://forum.doozan.com/read.php?2,7451 Signed-off-by: Eric Hutter Acked-by: Andrew Lunn Cc: # v3.6.x Signed-off-by: Jason Cooper --- arch/arm/boot/dts/kirkwood-goflexnet.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts index bd83b8fc7c83..c3573be7b92c 100644 --- a/arch/arm/boot/dts/kirkwood-goflexnet.dts +++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts @@ -77,6 +77,7 @@ }; nand@3000000 { + chip-delay = <40>; status = "okay"; partition@0 { -- cgit v1.2.3-55-g7522 From 7f23f62fc31c5c97947414c0937a72e08a947a41 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Wed, 20 Mar 2013 16:09:35 +0100 Subject: arm: mvebu: Use local interrupt only for the timer 0 The commit 3a6f08a37 "arm: mvebu: Add support for local interrupt", managed the 28th first interrupts as local interrupt to match the hardware specification. Among these interrupts there are the Gigabits Ethernet ones used by the mvneta driver. Unfortunately the state of the percpu_irq API prevents the driver to use it. Indeed the interrupts have to be freed when the .stop() function is called. As the free_percpu_irq() function don't disable the interrupt line, we have to do it on each CPU before calling this. The function disable_percpu_irq() only disable the percpu on the current CPU and there is no function which allows to disable a percpu irq on a given CPU. Waiting for the extension of the percpu_irq API, this fix allows to use again the mvneta driver. Signed-off-by: Gregory CLEMENT Tested-by: Thomas Petazzoni Tested-by: Masami Hiramatsu Signed-off-by: Jason Cooper --- arch/arm/mach-mvebu/irq-armada-370-xp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-mvebu/irq-armada-370-xp.c b/arch/arm/mach-mvebu/irq-armada-370-xp.c index 274ff58271de..6a9195e10579 100644 --- a/arch/arm/mach-mvebu/irq-armada-370-xp.c +++ b/arch/arm/mach-mvebu/irq-armada-370-xp.c @@ -44,6 +44,8 @@ #define ARMADA_370_XP_MAX_PER_CPU_IRQS (28) +#define ARMADA_370_XP_TIMER0_PER_CPU_IRQ (5) + #define ACTIVE_DOORBELLS (8) static DEFINE_RAW_SPINLOCK(irq_controller_lock); @@ -62,7 +64,7 @@ static void armada_370_xp_irq_mask(struct irq_data *d) #ifdef CONFIG_SMP irq_hw_number_t hwirq = irqd_to_hwirq(d); - if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS) + if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) writel(hwirq, main_int_base + ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS); else @@ -79,7 +81,7 @@ static void armada_370_xp_irq_unmask(struct irq_data *d) #ifdef CONFIG_SMP irq_hw_number_t hwirq = irqd_to_hwirq(d); - if (hwirq > ARMADA_370_XP_MAX_PER_CPU_IRQS) + if (hwirq != ARMADA_370_XP_TIMER0_PER_CPU_IRQ) writel(hwirq, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); else @@ -147,7 +149,7 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h, writel(hw, main_int_base + ARMADA_370_XP_INT_SET_ENABLE_OFFS); irq_set_status_flags(virq, IRQ_LEVEL); - if (hw < ARMADA_370_XP_MAX_PER_CPU_IRQS) { + if (hw == ARMADA_370_XP_TIMER0_PER_CPU_IRQ) { irq_set_percpu_devid(virq); irq_set_chip_and_handler(virq, &armada_370_xp_irq_chip, handle_percpu_devid_irq); -- cgit v1.2.3-55-g7522 From 0d0644ebc63bce3784ebea28d0355071b4e90525 Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Sat, 23 Mar 2013 13:56:58 +0100 Subject: ARM: Kirkwood: fix unused mvsdio gpio pins mvsdio_platform_data allows to pass card detect and write protect gpio numbers to the driver. Some kirkwood boards don't use both pins as they are not connected, and don't set the corresponding value in platform_data. This will leave the unset values in platform_data initialized as 0, which is in fact a valid gpio pin. mvsdio will grab that pin and configure it as gpio, which in turn breaks nand controller as mpp0 also carries nand_io2. This patch fixes the above by initializing unused gpio functions in the platform_data with an invalid (-1) value. Signed-off-by: Sebastian Hesselbarth Reported-by: Soeren Moch Signed-off-by: Jason Cooper --- arch/arm/mach-kirkwood/guruplug-setup.c | 2 ++ arch/arm/mach-kirkwood/openrd-setup.c | 1 + arch/arm/mach-kirkwood/rd88f6281-setup.c | 1 + 3 files changed, 4 insertions(+) diff --git a/arch/arm/mach-kirkwood/guruplug-setup.c b/arch/arm/mach-kirkwood/guruplug-setup.c index 1c6e736cbbf8..08dd739aa709 100644 --- a/arch/arm/mach-kirkwood/guruplug-setup.c +++ b/arch/arm/mach-kirkwood/guruplug-setup.c @@ -53,6 +53,8 @@ static struct mv_sata_platform_data guruplug_sata_data = { static struct mvsdio_platform_data guruplug_mvsdio_data = { /* unfortunately the CD signal has not been connected */ + .gpio_card_detect = -1, + .gpio_write_protect = -1, }; static struct gpio_led guruplug_led_pins[] = { diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c index 8ddd69fdc937..6a6eb548307d 100644 --- a/arch/arm/mach-kirkwood/openrd-setup.c +++ b/arch/arm/mach-kirkwood/openrd-setup.c @@ -55,6 +55,7 @@ static struct mv_sata_platform_data openrd_sata_data = { static struct mvsdio_platform_data openrd_mvsdio_data = { .gpio_card_detect = 29, /* MPP29 used as SD card detect */ + .gpio_write_protect = -1, }; static unsigned int openrd_mpp_config[] __initdata = { diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c index c7d93b48926b..d24223166e06 100644 --- a/arch/arm/mach-kirkwood/rd88f6281-setup.c +++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c @@ -69,6 +69,7 @@ static struct mv_sata_platform_data rd88f6281_sata_data = { static struct mvsdio_platform_data rd88f6281_mvsdio_data = { .gpio_card_detect = 28, + .gpio_write_protect = -1, }; static unsigned int rd88f6281_mpp_config[] __initdata = { -- cgit v1.2.3-55-g7522 From 835f6322c691600da5b7fb526f07b1d21d0c88ef Mon Sep 17 00:00:00 2001 From: Alexander Clouter Date: Tue, 26 Mar 2013 21:44:46 +0000 Subject: arm: orion5x: fix orion5x.dtsi gpio parameters orion5x.dtsi is missing the gpio alias as well as including a typo ('ngpio' instead of 'ngpios') that prevented the orion-gpio driver from loading. Also missing were the interrupt-controller properties. This patches resolves those glitches. Signed-off-by: Alexander Clouter Acked-by: Andrew Lunn Signed-off-by: Jason Cooper --- arch/arm/boot/dts/orion5x.dtsi | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/orion5x.dtsi b/arch/arm/boot/dts/orion5x.dtsi index 8aad00f81ed9..7c2a3263c166 100644 --- a/arch/arm/boot/dts/orion5x.dtsi +++ b/arch/arm/boot/dts/orion5x.dtsi @@ -13,6 +13,9 @@ compatible = "marvell,orion5x"; interrupt-parent = <&intc>; + aliases { + gpio0 = &gpio0; + }; intc: interrupt-controller { compatible = "marvell,orion-intc", "marvell,intc"; interrupt-controller; @@ -32,7 +35,9 @@ #gpio-cells = <2>; gpio-controller; reg = <0x10100 0x40>; - ngpio = <32>; + ngpios = <32>; + interrupt-controller; + #interrupt-cells = <2>; interrupts = <6>, <7>, <8>, <9>; }; -- cgit v1.2.3-55-g7522 From e0656a9cbbd0444aaec493ed8a9420d07c356639 Mon Sep 17 00:00:00 2001 From: Alexander Clouter Date: Tue, 26 Mar 2013 21:44:49 +0000 Subject: arm: orion5x: correct IRQ used in dtsi for mv_cesa The crypto functionality in the orion5x dtsi uses the Ethernet IRQ and so things do not work and there is much grumbling at boot time. The IRQ for the crypto should be 28, and not 22, and that is what this patch corrects. Signed-off-by: Alexander Clouter Acked-by: Andrew Lunn Signed-off-by: Jason Cooper --- arch/arm/boot/dts/orion5x.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/orion5x.dtsi b/arch/arm/boot/dts/orion5x.dtsi index 7c2a3263c166..f7bec3b1ba32 100644 --- a/arch/arm/boot/dts/orion5x.dtsi +++ b/arch/arm/boot/dts/orion5x.dtsi @@ -96,7 +96,7 @@ reg = <0x90000 0x10000>, <0xf2200000 0x800>; reg-names = "regs", "sram"; - interrupts = <22>; + interrupts = <28>; status = "okay"; }; }; -- cgit v1.2.3-55-g7522 From 879d68a445dd7073a8c022fcdd21dc27eca7f192 Mon Sep 17 00:00:00 2001 From: Ryan Press Date: Tue, 26 Mar 2013 16:32:31 -0700 Subject: arm: mvebu: Fix pinctrl for Armada 370 Mirabox SDIO port. The previous configuration used the wrong "clk" pin. Without this change mv_sdio worked because the bootloader would set the pin up, but with a bootloader that does not set the pin, mv_sdio fails to detect any card. I have tested this change using a mwifiex_sdio wireless network adapter over the SDIO interface. Signed-off-by: Ryan Press Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-370-mirabox.dts | 2 +- arch/arm/boot/dts/armada-370.dtsi | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts index dd0c57dd9f30..3234875824dc 100644 --- a/arch/arm/boot/dts/armada-370-mirabox.dts +++ b/arch/arm/boot/dts/armada-370-mirabox.dts @@ -54,7 +54,7 @@ }; mvsdio@d00d4000 { - pinctrl-0 = <&sdio_pins2>; + pinctrl-0 = <&sdio_pins3>; pinctrl-names = "default"; status = "okay"; /* diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi index 8188d138020e..a195debb67d3 100644 --- a/arch/arm/boot/dts/armada-370.dtsi +++ b/arch/arm/boot/dts/armada-370.dtsi @@ -59,6 +59,12 @@ "mpp50", "mpp51", "mpp52"; marvell,function = "sd0"; }; + + sdio_pins3: sdio-pins3 { + marvell,pins = "mpp48", "mpp49", "mpp50", + "mpp51", "mpp52", "mpp53"; + marvell,function = "sd0"; + }; }; gpio0: gpio@d0018100 { -- cgit v1.2.3-55-g7522 From 91c5746425aed8f7188a351f1224a26aa232e4b3 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 27 Mar 2013 18:28:41 +0000 Subject: aoe: reserve enough headroom on skbs Some network drivers use a non default hard_header_len Transmitted skb should take into account dev->hard_header_len, or risk crashes or expensive reallocations. In the case of aoe, lets reserve MAX_HEADER bytes. David reported a crash in defxx driver, solved by this patch. Reported-by: David Oostdyk Tested-by: David Oostdyk Signed-off-by: Eric Dumazet Cc: Ed Cashin Signed-off-by: David S. Miller --- drivers/block/aoe/aoecmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 25ef5c014fca..92b6d7c51e39 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -51,8 +51,9 @@ new_skb(ulong len) { struct sk_buff *skb; - skb = alloc_skb(len, GFP_ATOMIC); + skb = alloc_skb(len + MAX_HEADER, GFP_ATOMIC); if (skb) { + skb_reserve(skb, MAX_HEADER); skb_reset_mac_header(skb); skb_reset_network_header(skb); skb->protocol = __constant_htons(ETH_P_AOE); -- cgit v1.2.3-55-g7522 From b43decd2c513ae44a5462a1a4c2622f0fa77c9e0 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Sun, 24 Mar 2013 15:36:38 +0100 Subject: drm/nouveau: fix handling empty channel list in ioctl's If there are no channels, chan would never end up being NULL, and so the null pointer check would fail. Solve this by initializing chan to NULL, and iterating over temp instead. Fixes oops when running intel-gpu-tools/tests/kms_flip, which attempts to do some intel ioctl's on a nouveau device. Signed-off-by: Maarten Lankhorst Cc: stable@vger.kernel.org [3.7+] Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_abi16.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 3b6dc883e150..5eb3e0da7c6e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -391,7 +391,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_device *device = nv_device(drm->device); struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); - struct nouveau_abi16_chan *chan, *temp; + struct nouveau_abi16_chan *chan = NULL, *temp; struct nouveau_abi16_ntfy *ntfy; struct nouveau_object *object; struct nv_dma_class args = {}; @@ -404,10 +404,11 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) if (unlikely(nv_device(abi16->device)->card_type >= NV_C0)) return nouveau_abi16_put(abi16, -EINVAL); - list_for_each_entry_safe(chan, temp, &abi16->channels, head) { - if (chan->chan->handle == (NVDRM_CHAN | info->channel)) + list_for_each_entry(temp, &abi16->channels, head) { + if (temp->chan->handle == (NVDRM_CHAN | info->channel)) { + chan = temp; break; - chan = NULL; + } } if (!chan) @@ -459,17 +460,18 @@ nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS) { struct drm_nouveau_gpuobj_free *fini = data; struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); - struct nouveau_abi16_chan *chan, *temp; + struct nouveau_abi16_chan *chan = NULL, *temp; struct nouveau_abi16_ntfy *ntfy; int ret; if (unlikely(!abi16)) return -ENOMEM; - list_for_each_entry_safe(chan, temp, &abi16->channels, head) { - if (chan->chan->handle == (NVDRM_CHAN | fini->channel)) + list_for_each_entry(temp, &abi16->channels, head) { + if (temp->chan->handle == (NVDRM_CHAN | fini->channel)) { + chan = temp; break; - chan = NULL; + } } if (!chan) -- cgit v1.2.3-55-g7522 From e4604d8fe8492f8120cf92d4b60b3cc90ba87bd0 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Sun, 24 Mar 2013 12:56:30 +0100 Subject: drm/nouveau: fix NULL ptr dereference from nv50_disp_intr() Op 23-03-13 12:47, Peter Hurley schreef: > On Tue, 2013-03-19 at 11:13 -0400, Peter Hurley wrote: >> On vanilla 3.9.0-rc3, I get this 100% repeatable oops after login when >> the user X session is coming up: > Perhaps I wasn't clear that this happens on every boot and is a > regression from 3.8 > > I'd be happy to help resolve this but time is of the essence; it would > be a shame to have to revert all of this for 3.9 Well it broke on my system too, so it was easy to fix. I didn't even need gdm to trigger it! >8---- This fixes regression caused by 1d7c71a3e2f7 (drm/nouveau/disp: port vblank handling to event interface), which causes a oops in the following way: BUG: unable to handle kernel NULL pointer dereference at 0000000000000001 IP: [<0000000000000001>] 0x0 PGD 0 Oops: 0010 [#1] PREEMPT SMP Modules linked in: ip6table_filter ip6_tables ebtable_nat ebtables ...... CPU 3 Pid: 0, comm: swapper/3 Not tainted 3.9.0-rc3-xeon #rc3 Dell Inc. Precision WorkStation T5400 /0RW203 RIP: 0010:[<0000000000000001>] [<0000000000000001>] 0x0 RSP: 0018:ffff8802afcc3d80 EFLAGS: 00010087 RAX: ffff88029f6e5808 RBX: 0000000000000001 RCX: 0000000000000000 RDX: 0000000000000096 RSI: 0000000000000001 RDI: ffff88029f6e5808 RBP: ffff8802afcc3dc8 R08: 0000000000000000 R09: 0000000000000004 R10: 000000000000002c R11: ffff88029e559a98 R12: ffff8802a376cb78 R13: ffff88029f6e57e0 R14: ffff88029f6e57f8 R15: ffff88029f6e5808 FS: 0000000000000000(0000) GS:ffff8802afcc0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000001 CR3: 000000029fa67000 CR4: 00000000000007e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process swapper/3 (pid: 0, threadinfo ffff8802a355e000, task ffff8802a3535c40) Stack: ffffffffa0159d8a 0000000000000082 ffff88029f6e5820 0000000000000001 ffff88029f71aa00 0000000000000000 0000000000000000 0000000004000000 0000000004000000 ffff8802afcc3e38 ffffffffa01843b5 ffff8802afcc3df8 Call Trace: [] ? nouveau_event_trigger+0xaa/0xe0 [nouveau] [] nv50_disp_intr+0xc5/0x200 [nouveau] [] ? _raw_spin_unlock_irqrestore+0x2c/0x50 [] ? notifier_call_chain+0x4d/0x70 [] nouveau_mc_intr+0xb5/0x110 [nouveau] [] nouveau_irq_handler+0x6f/0x80 [nouveau] [] handle_irq_event_percpu+0x75/0x260 [] handle_irq_event+0x48/0x70 [] handle_fasteoi_irq+0x5a/0x100 [] handle_irq+0x22/0x40 [] do_IRQ+0x5a/0xd0 [] common_interrupt+0x6d/0x6d [] ? native_safe_halt+0x6/0x10 [] default_idle+0x3d/0x170 [] cpu_idle+0x116/0x130 [] start_secondary+0x251/0x258 Code: Bad RIP value. RIP [<0000000000000001>] 0x0 RSP CR2: 0000000000000001 ---[ end trace 907323cb8ce6f301 ]--- Signed-off-by: Maarten Lankhorst Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drm.c | 32 ++++++++++++++++++++------------ drivers/gpu/drm/nouveau/nouveau_drm.h | 2 +- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index d1099365bfc1..c95decf543e9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -71,12 +71,26 @@ module_param_named(modeset, nouveau_modeset, int, 0400); static struct drm_driver driver; +static int +nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head) +{ + struct nouveau_drm *drm = + container_of(event, struct nouveau_drm, vblank[head]); + drm_handle_vblank(drm->dev, head); + return NVKM_EVENT_KEEP; +} + static int nouveau_drm_vblank_enable(struct drm_device *dev, int head) { struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_disp *pdisp = nouveau_disp(drm->device); - nouveau_event_get(pdisp->vblank, head, &drm->vblank); + + if (WARN_ON_ONCE(head > ARRAY_SIZE(drm->vblank))) + return -EIO; + WARN_ON_ONCE(drm->vblank[head].func); + drm->vblank[head].func = nouveau_drm_vblank_handler; + nouveau_event_get(pdisp->vblank, head, &drm->vblank[head]); return 0; } @@ -85,16 +99,11 @@ nouveau_drm_vblank_disable(struct drm_device *dev, int head) { struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_disp *pdisp = nouveau_disp(drm->device); - nouveau_event_put(pdisp->vblank, head, &drm->vblank); -} - -static int -nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head) -{ - struct nouveau_drm *drm = - container_of(event, struct nouveau_drm, vblank); - drm_handle_vblank(drm->dev, head); - return NVKM_EVENT_KEEP; + if (drm->vblank[head].func) + nouveau_event_put(pdisp->vblank, head, &drm->vblank[head]); + else + WARN_ON_ONCE(1); + drm->vblank[head].func = NULL; } static u64 @@ -292,7 +301,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) dev->dev_private = drm; drm->dev = dev; - drm->vblank.func = nouveau_drm_vblank_handler; INIT_LIST_HEAD(&drm->clients); spin_lock_init(&drm->tile.lock); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h index b25df374c901..9c39bafbef2c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -113,7 +113,7 @@ struct nouveau_drm { struct nvbios vbios; struct nouveau_display *display; struct backlight_device *backlight; - struct nouveau_eventh vblank; + struct nouveau_eventh vblank[4]; /* power management */ struct nouveau_pm *pm; -- cgit v1.2.3-55-g7522 From 5b4617d82020addf244c8c5206270e49ef9933d6 Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Thu, 28 Mar 2013 00:07:29 +0400 Subject: HID: fix Masterkit MA901 hid quirks This patch reverts commit 0322bd3980 ("usb hid quirks for Masterkit MA901 usb radio") and adds checks in hid_ignore() for Masterkit MA901 usb radio device. This usb radio device shares USB ID with many Atmel V-USB (and probably other) devices so patch sorts things out by checking name, vendor, product of hid device. Signed-off-by: Alexey Klimov Acked-by: Mauro Carvalho Chehab Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 13 ++++++++++++- drivers/hid/hid-ids.h | 5 ++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 512b01c04ea7..aa341d135867 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2077,7 +2077,6 @@ static const struct hid_device_id hid_ignore_list[] = { { 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_MASTERKIT, USB_DEVICE_ID_MASTERKIT_MA901RADIO) }, { 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) }, @@ -2244,6 +2243,18 @@ bool hid_ignore(struct hid_device *hdev) hdev->product <= USB_DEVICE_ID_VELLEMAN_K8061_LAST)) return true; break; + case USB_VENDOR_ID_ATMEL_V_USB: + /* Masterkit MA901 usb radio based on Atmel tiny85 chip and + * it has the same USB ID as many Atmel V-USB devices. This + * usb radio is handled by radio-ma901.c driver so we want + * ignore the hid. Check the name, bus, product and ignore + * if we have MA901 usb radio. + */ + if (hdev->product == USB_DEVICE_ID_ATMEL_V_USB && + hdev->bus == BUS_USB && + strncmp(hdev->name, "www.masterkit.ru MA901", 22) == 0) + return true; + break; } if (hdev->type == HID_TYPE_USBMOUSE && diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index c4388776f4e4..5309fd5eb0eb 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -158,6 +158,8 @@ #define USB_VENDOR_ID_ATMEL 0x03eb #define USB_DEVICE_ID_ATMEL_MULTITOUCH 0x211c #define USB_DEVICE_ID_ATMEL_MXT_DIGITIZER 0x2118 +#define USB_VENDOR_ID_ATMEL_V_USB 0x16c0 +#define USB_DEVICE_ID_ATMEL_V_USB 0x05df #define USB_VENDOR_ID_AUREAL 0x0755 #define USB_DEVICE_ID_AUREAL_W01RN 0x2626 @@ -557,9 +559,6 @@ #define USB_VENDOR_ID_MADCATZ 0x0738 #define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 -#define USB_VENDOR_ID_MASTERKIT 0x16c0 -#define USB_DEVICE_ID_MASTERKIT_MA901RADIO 0x05df - #define USB_VENDOR_ID_MCC 0x09db #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 #define USB_DEVICE_ID_MCC_PMD1208LS 0x007a -- cgit v1.2.3-55-g7522 From 30b29537bcba070b3df8d7d24c1975676a1a6a4f Mon Sep 17 00:00:00 2001 From: Alexey Klimov Date: Thu, 28 Mar 2013 00:08:19 +0400 Subject: media: radio-ma901: return ENODEV in probe if usb_device doesn't match Masterkit MA901 usb radio device shares USB ID with Atmel V-USB devices. This patch adds additional checks in usb_ma901radio_probe() and if product or manufacturer doesn't match we return -ENODEV and don't continue. This allows hid drivers to handle not MA901 device. Signed-off-by: Alexey Klimov Acked-by: Mauro Carvalho Chehab Signed-off-by: Jiri Kosina --- drivers/media/radio/radio-ma901.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/media/radio/radio-ma901.c b/drivers/media/radio/radio-ma901.c index c61f590029ad..348dafc0318a 100644 --- a/drivers/media/radio/radio-ma901.c +++ b/drivers/media/radio/radio-ma901.c @@ -347,9 +347,20 @@ static void usb_ma901radio_release(struct v4l2_device *v4l2_dev) static int usb_ma901radio_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_device *dev = interface_to_usbdev(intf); struct ma901radio_device *radio; int retval = 0; + /* Masterkit MA901 usb radio has the same USB ID as many others + * Atmel V-USB devices. Let's make additional checks to be sure + * that this is our device. + */ + + if (dev->product && dev->manufacturer && + (strncmp(dev->product, "MA901", 5) != 0 + || strncmp(dev->manufacturer, "www.masterkit.ru", 16) != 0)) + return -ENODEV; + radio = kzalloc(sizeof(struct ma901radio_device), GFP_KERNEL); if (!radio) { dev_err(&intf->dev, "kzalloc for ma901radio_device failed\n"); -- cgit v1.2.3-55-g7522 From 35e5cbc0af240778e61113286c019837e06aeec6 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 29 Mar 2013 15:39:16 +0100 Subject: reiserfs: Fix warning and inode leak when deleting inode with xattrs After commit 21d8a15a (lookup_one_len: don't accept . and ..) reiserfs started failing to delete xattrs from inode. This was due to a buggy test for '.' and '..' in fill_with_dentries() which resulted in passing '.' and '..' entries to lookup_one_len() in some cases. That returned error and so we failed to iterate over all xattrs of and inode. Fix the test in fill_with_dentries() along the lines of the one in lookup_one_len(). Reported-by: Pawel Zawora CC: stable@vger.kernel.org Signed-off-by: Jan Kara --- fs/reiserfs/xattr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index c196369fe408..4cce1d9552fb 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -187,8 +187,8 @@ fill_with_dentries(void *buf, const char *name, int namelen, loff_t offset, if (dbuf->count == ARRAY_SIZE(dbuf->dentries)) return -ENOSPC; - if (name[0] == '.' && (name[1] == '\0' || - (name[1] == '.' && name[2] == '\0'))) + if (name[0] == '.' && (namelen < 2 || + (namelen == 2 && name[1] == '.'))) return 0; dentry = lookup_one_len(name, dbuf->xadir, namelen); -- cgit v1.2.3-55-g7522 From 9cfe8b156c21cf340b3a10ecb3022fbbc1c39185 Mon Sep 17 00:00:00 2001 From: Mirko Lindner Date: Tue, 26 Mar 2013 06:38:35 +0000 Subject: sky2: Receive Overflows not counted The sky2 driver doesn't count the Receive Overflows because the MAC interrupt for this event is not set in the MAC's interrupt mask. The MAC's interrupt mask is set only for Transmit FIFO Underruns. Fix: The correct setting should be (GM_IS_TX_FF_UR | GM_IS_RX_FF_OR) Otherwise the Receive Overflow event will not generate any interrupt. The Receive Overflow interrupt is handled correctly Signed-off-by: Mirko Lindner Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/sky2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/sky2.h b/drivers/net/ethernet/marvell/sky2.h index 615ac63ea860..ec6dcd80152b 100644 --- a/drivers/net/ethernet/marvell/sky2.h +++ b/drivers/net/ethernet/marvell/sky2.h @@ -2074,7 +2074,7 @@ enum { GM_IS_RX_FF_OR = 1<<1, /* Receive FIFO Overrun */ GM_IS_RX_COMPL = 1<<0, /* Frame Reception Complete */ -#define GMAC_DEF_MSK GM_IS_TX_FF_UR +#define GMAC_DEF_MSK (GM_IS_TX_FF_UR | GM_IS_RX_FF_OR) }; /* GMAC_LINK_CTRL 16 bit GMAC Link Control Reg (YUKON only) */ -- cgit v1.2.3-55-g7522 From 74f9f42c1c1650e74fb464f76644c9041f996851 Mon Sep 17 00:00:00 2001 From: Mirko Lindner Date: Tue, 26 Mar 2013 06:38:42 +0000 Subject: sky2: Threshold for Pause Packet is set wrong The sky2 driver sets the Rx Upper Threshold for Pause Packet generation to a wrong value which leads to only 2kB of RAM remaining space. This can lead to Rx overflow errors even with activated flow-control. Fix: We should increase the value to 8192/8 Signed-off-by: Mirko Lindner Acked-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/sky2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index fc07ca35721b..6a0e671fcecd 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -1067,7 +1067,7 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 space) sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp); sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2); - tp = space - 2048/8; + tp = space - 8192/8; sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp); sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4); } else { -- cgit v1.2.3-55-g7522 From 1c4a154e5253687c51123956dfcee9e9dfa8542d Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Tue, 26 Mar 2013 08:13:34 +0000 Subject: ipv6: don't accept node local multicast traffic from the wire Erik Hugne's errata proposal (Errata ID: 3480) to RFC4291 has been verified: http://www.rfc-editor.org/errata_search.php?eid=3480 We have to check for pkt_type and loopback flag because either the packets are allowed to travel over the loopback interface (in which case pkt_type is PACKET_HOST and IFF_LOOPBACK flag is set) or they travel over a non-loopback interface back to us (in which case PACKET_TYPE is PACKET_LOOPBACK and IFF_LOOPBACK flag is not set). Cc: Erik Hugne Cc: YOSHIFUJI Hideaki Signed-off-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- net/ipv6/ip6_input.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index e33fe0ab2568..2bab2aa59745 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -118,6 +118,18 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt ipv6_addr_loopback(&hdr->daddr)) goto err; + /* RFC4291 Errata ID: 3480 + * Interface-Local scope spans only a single interface on a + * node and is useful only for loopback transmission of + * multicast. Packets with interface-local scope received + * from another node must be discarded. + */ + if (!(skb->pkt_type == PACKET_LOOPBACK || + dev->flags & IFF_LOOPBACK) && + ipv6_addr_is_multicast(&hdr->daddr) && + IPV6_ADDR_MC_SCOPE(&hdr->daddr) == 1) + goto err; + /* RFC4291 2.7 * Nodes must not originate a packet to a multicast address whose scope * field contains the reserved value 0; if such a packet is received, it -- cgit v1.2.3-55-g7522 From 1bc7db16782c2a581fb4d53ca853631050f31611 Mon Sep 17 00:00:00 2001 From: nikolay@redhat.com Date: Wed, 27 Mar 2013 03:32:41 +0000 Subject: bonding: fix disabling of arp_interval and miimon Currently if either arp_interval or miimon is disabled, they both get disabled, and upon disabling they get executed once more which is not the proper behaviour. Also when doing a no-op and disabling an already disabled one, the other again gets disabled. Also fix the error messages with the proper valid ranges, and a small typo fix in the up delay error message (outputting "down delay", instead of "up delay"). Signed-off-by: Nikolay Aleksandrov Signed-off-by: David S. Miller --- drivers/net/bonding/bond_sysfs.c | 92 +++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index db103e03ba05..ea7a388f4843 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -527,7 +527,7 @@ static ssize_t bonding_store_arp_interval(struct device *d, goto out; } if (new_value < 0) { - pr_err("%s: Invalid arp_interval value %d not in range 1-%d; rejected.\n", + pr_err("%s: Invalid arp_interval value %d not in range 0-%d; rejected.\n", bond->dev->name, new_value, INT_MAX); ret = -EINVAL; goto out; @@ -542,14 +542,15 @@ static ssize_t bonding_store_arp_interval(struct device *d, pr_info("%s: Setting ARP monitoring interval to %d.\n", bond->dev->name, new_value); bond->params.arp_interval = new_value; - if (bond->params.miimon) { - pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", - bond->dev->name, bond->dev->name); - bond->params.miimon = 0; - } - if (!bond->params.arp_targets[0]) { - pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", - bond->dev->name); + if (new_value) { + if (bond->params.miimon) { + pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", + bond->dev->name, bond->dev->name); + bond->params.miimon = 0; + } + if (!bond->params.arp_targets[0]) + pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", + bond->dev->name); } if (bond->dev->flags & IFF_UP) { /* If the interface is up, we may need to fire off @@ -557,10 +558,13 @@ static ssize_t bonding_store_arp_interval(struct device *d, * timer will get fired off when the open function * is called. */ - cancel_delayed_work_sync(&bond->mii_work); - queue_delayed_work(bond->wq, &bond->arp_work, 0); + if (!new_value) { + cancel_delayed_work_sync(&bond->arp_work); + } else { + cancel_delayed_work_sync(&bond->mii_work); + queue_delayed_work(bond->wq, &bond->arp_work, 0); + } } - out: rtnl_unlock(); return ret; @@ -702,7 +706,7 @@ static ssize_t bonding_store_downdelay(struct device *d, } if (new_value < 0) { pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", - bond->dev->name, new_value, 1, INT_MAX); + bond->dev->name, new_value, 0, INT_MAX); ret = -EINVAL; goto out; } else { @@ -757,8 +761,8 @@ static ssize_t bonding_store_updelay(struct device *d, goto out; } if (new_value < 0) { - pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", - bond->dev->name, new_value, 1, INT_MAX); + pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n", + bond->dev->name, new_value, 0, INT_MAX); ret = -EINVAL; goto out; } else { @@ -968,37 +972,37 @@ static ssize_t bonding_store_miimon(struct device *d, } if (new_value < 0) { pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n", - bond->dev->name, new_value, 1, INT_MAX); + bond->dev->name, new_value, 0, INT_MAX); ret = -EINVAL; goto out; - } else { - pr_info("%s: Setting MII monitoring interval to %d.\n", - bond->dev->name, new_value); - bond->params.miimon = new_value; - if (bond->params.updelay) - pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", - bond->dev->name, - bond->params.updelay * bond->params.miimon); - if (bond->params.downdelay) - pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", - bond->dev->name, - bond->params.downdelay * bond->params.miimon); - if (bond->params.arp_interval) { - pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", - bond->dev->name); - bond->params.arp_interval = 0; - if (bond->params.arp_validate) { - bond->params.arp_validate = - BOND_ARP_VALIDATE_NONE; - } - } - - if (bond->dev->flags & IFF_UP) { - /* If the interface is up, we may need to fire off - * the MII timer. If the interface is down, the - * timer will get fired off when the open function - * is called. - */ + } + pr_info("%s: Setting MII monitoring interval to %d.\n", + bond->dev->name, new_value); + bond->params.miimon = new_value; + if (bond->params.updelay) + pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", + bond->dev->name, + bond->params.updelay * bond->params.miimon); + if (bond->params.downdelay) + pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", + bond->dev->name, + bond->params.downdelay * bond->params.miimon); + if (new_value && bond->params.arp_interval) { + pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", + bond->dev->name); + bond->params.arp_interval = 0; + if (bond->params.arp_validate) + bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; + } + if (bond->dev->flags & IFF_UP) { + /* If the interface is up, we may need to fire off + * the MII timer. If the interface is down, the + * timer will get fired off when the open function + * is called. + */ + if (!new_value) { + cancel_delayed_work_sync(&bond->mii_work); + } else { cancel_delayed_work_sync(&bond->arp_work); queue_delayed_work(bond->wq, &bond->mii_work, 0); } -- cgit v1.2.3-55-g7522 From ff7f3efb9abf986f4ecd8793a9593f7ca4d6431a Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Fri, 29 Mar 2013 13:50:21 -0400 Subject: tile: expect new initramfs name from hypervisor file system The current Tilera boot infrastructure now provides the initramfs to Linux as a Tilera-hypervisor file named "initramfs", rather than "initramfs.cpio.gz", as before. (This makes it reasonable to use other compression techniques than gzip on the file without having to worry about the name causing confusion.) Adapt to use the new name, but also fall back to checking for the old name. Cc'ing to stable so that older kernels will remain compatible with newer Tilera boot infrastructure. Signed-off-by: Chris Metcalf Cc: stable@vger.kernel.org --- arch/tile/kernel/setup.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index d1e15f7b59c6..7a5aa1a7864e 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c @@ -1004,15 +1004,8 @@ void __cpuinit setup_cpu(int boot) #ifdef CONFIG_BLK_DEV_INITRD -/* - * Note that the kernel can potentially support other compression - * techniques than gz, though we don't do so by default. If we ever - * decide to do so we can either look for other filename extensions, - * or just allow a file with this name to be compressed with an - * arbitrary compressor (somewhat counterintuitively). - */ static int __initdata set_initramfs_file; -static char __initdata initramfs_file[128] = "initramfs.cpio.gz"; +static char __initdata initramfs_file[128] = "initramfs"; static int __init setup_initramfs_file(char *str) { @@ -1026,9 +1019,9 @@ static int __init setup_initramfs_file(char *str) early_param("initramfs_file", setup_initramfs_file); /* - * We look for an "initramfs.cpio.gz" file in the hvfs. - * If there is one, we allocate some memory for it and it will be - * unpacked to the initramfs. + * We look for a file called "initramfs" in the hvfs. If there is one, we + * allocate some memory for it and it will be unpacked to the initramfs. + * If it's compressed, the initd code will uncompress it first. */ static void __init load_hv_initrd(void) { @@ -1038,10 +1031,16 @@ static void __init load_hv_initrd(void) fd = hv_fs_findfile((HV_VirtAddr) initramfs_file); if (fd == HV_ENOENT) { - if (set_initramfs_file) + if (set_initramfs_file) { pr_warning("No such hvfs initramfs file '%s'\n", initramfs_file); - return; + return; + } else { + /* Try old backwards-compatible name. */ + fd = hv_fs_findfile((HV_VirtAddr)"initramfs.cpio.gz"); + if (fd == HV_ENOENT) + return; + } } BUG_ON(fd < 0); stat = hv_fs_fstat(fd); -- cgit v1.2.3-55-g7522 From 50eab0503a7579ada512e4968738b7c9737cf36e Mon Sep 17 00:00:00 2001 From: Li RongQing Date: Wed, 27 Mar 2013 23:42:41 +0000 Subject: net: fix the use of this_cpu_ptr flush_tasklet is not percpu var, and percpu is percpu var, and this_cpu_ptr(&info->cache->percpu->flush_tasklet) is not equal to &this_cpu_ptr(info->cache->percpu)->flush_tasklet 1f743b076(use this_cpu_ptr per-cpu helper) introduced this bug. Signed-off-by: Li RongQing Signed-off-by: David S. Miller --- net/core/flow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/flow.c b/net/core/flow.c index c56ea6f7f6c7..2bfd081c59f7 100644 --- a/net/core/flow.c +++ b/net/core/flow.c @@ -328,7 +328,7 @@ static void flow_cache_flush_per_cpu(void *data) struct flow_flush_info *info = data; struct tasklet_struct *tasklet; - tasklet = this_cpu_ptr(&info->cache->percpu->flush_tasklet); + tasklet = &this_cpu_ptr(info->cache->percpu)->flush_tasklet; tasklet->data = (unsigned long)info; tasklet_schedule(tasklet); } -- cgit v1.2.3-55-g7522 From 4c51e53689569398d656e631c17308d9b8e84650 Mon Sep 17 00:00:00 2001 From: Steve Glendinning Date: Thu, 28 Mar 2013 02:34:41 +0000 Subject: smsc75xx: fix jumbo frame support This patch enables RX of jumbo frames for LAN7500. Previously the driver would transmit jumbo frames succesfully but would drop received jumbo frames (incrementing the interface errors count). With this patch applied the device can succesfully receive jumbo frames up to MTU 9000 (9014 bytes on the wire including ethernet header). Signed-off-by: Steve Glendinning Signed-off-by: David S. Miller --- drivers/net/usb/smsc75xx.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 9abe51710f22..1a15ec14c386 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -914,8 +914,12 @@ static int smsc75xx_set_rx_max_frame_length(struct usbnet *dev, int size) static int smsc75xx_change_mtu(struct net_device *netdev, int new_mtu) { struct usbnet *dev = netdev_priv(netdev); + int ret; + + if (new_mtu > MAX_SINGLE_PACKET_SIZE) + return -EINVAL; - int ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu); + ret = smsc75xx_set_rx_max_frame_length(dev, new_mtu + ETH_HLEN); if (ret < 0) { netdev_warn(dev->net, "Failed to set mac rx frame length\n"); return ret; @@ -1324,7 +1328,7 @@ static int smsc75xx_reset(struct usbnet *dev) netif_dbg(dev, ifup, dev->net, "FCT_TX_CTL set to 0x%08x\n", buf); - ret = smsc75xx_set_rx_max_frame_length(dev, 1514); + ret = smsc75xx_set_rx_max_frame_length(dev, dev->net->mtu + ETH_HLEN); if (ret < 0) { netdev_warn(dev->net, "Failed to set max rx frame length\n"); return ret; @@ -2134,8 +2138,8 @@ static int smsc75xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb) else if (rx_cmd_a & (RX_CMD_A_LONG | RX_CMD_A_RUNT)) dev->net->stats.rx_frame_errors++; } else { - /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */ - if (unlikely(size > (ETH_FRAME_LEN + 12))) { + /* MAX_SINGLE_PACKET_SIZE + 4(CRC) + 2(COE) + 4(Vlan) */ + if (unlikely(size > (MAX_SINGLE_PACKET_SIZE + ETH_HLEN + 12))) { netif_dbg(dev, rx_err, dev->net, "size err rx_cmd_a=0x%08x\n", rx_cmd_a); -- cgit v1.2.3-55-g7522 From a561cf7edf9863198bfccecfc5cfe26d951ebd20 Mon Sep 17 00:00:00 2001 From: Shmulik Ladkani Date: Wed, 27 Mar 2013 23:13:26 +0000 Subject: net: core: Remove redundant call to 'nf_reset' in 'dev_forward_skb' 'nf_reset' is called just prior calling 'netif_rx'. No need to call it twice. Reported-by: Igor Michailov Signed-off-by: Shmulik Ladkani Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/core/dev.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index b13e5c766c11..6591440cc03d 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1624,7 +1624,6 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) } skb_orphan(skb); - nf_reset(skb); if (unlikely(!is_skb_forwardable(dev, skb))) { atomic_long_inc(&dev->rx_dropped); -- cgit v1.2.3-55-g7522 From dc574f1d52d893f516f3786ff7635450bac00eef Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 28 Mar 2013 11:32:44 +0000 Subject: net: calxedaxgmac: fix rx ring handling when OOM If skb allocation for the rx ring fails repeatedly, we can reach a point were the ring is empty. In this condition, the driver is out of sync with the h/w. While this has always been possible, the removal of the skb recycling seems to have made triggering this problem easier. Signed-off-by: Rob Herring Signed-off-by: David S. Miller --- drivers/net/ethernet/calxeda/xgmac.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index a170065b5973..bb1e80bfa78a 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c @@ -1141,6 +1141,9 @@ static int xgmac_rx(struct xgmac_priv *priv, int limit) struct sk_buff *skb; int frame_len; + if (!dma_ring_cnt(priv->rx_head, priv->rx_tail, DMA_RX_RING_SZ)) + break; + entry = priv->rx_tail; p = priv->dma_rx + entry; if (desc_get_owner(p)) -- cgit v1.2.3-55-g7522 From e6c3827dcfe53dd78b824d2ee4007a216ada739e Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 28 Mar 2013 11:32:45 +0000 Subject: net: calxedaxgmac: Wake-on-LAN fixes WOL is broken because the magic packet status bit is getting set rather than the enable bit. The PMT interrupt is not getting serviced because the PMT interrupt is also enabled on the global interrupt, but not cleared by the global interrupt and the global interrupt is higher priority. This fixes both of these issues to get WOL working. There's still a problem with receive after resume, but at least now we can wake-up. Signed-off-by: Rob Herring Signed-off-by: David S. Miller --- drivers/net/ethernet/calxeda/xgmac.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index bb1e80bfa78a..b0ebc9f6d55e 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c @@ -163,6 +163,7 @@ #define XGMAC_FLOW_CTRL_FCB_BPA 0x00000001 /* Flow Control Busy ... */ /* XGMAC_INT_STAT reg */ +#define XGMAC_INT_STAT_PMTIM 0x00800000 /* PMT Interrupt Mask */ #define XGMAC_INT_STAT_PMT 0x0080 /* PMT Interrupt Status */ #define XGMAC_INT_STAT_LPI 0x0040 /* LPI Interrupt Status */ @@ -960,6 +961,9 @@ static int xgmac_hw_init(struct net_device *dev) writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_STATUS); writel(DMA_INTR_DEFAULT_MASK, ioaddr + XGMAC_DMA_INTR_ENA); + /* Mask power mgt interrupt */ + writel(XGMAC_INT_STAT_PMTIM, ioaddr + XGMAC_INT_STAT); + /* XGMAC requires AXI bus init. This is a 'magic number' for now */ writel(0x0077000E, ioaddr + XGMAC_DMA_AXI_BUS); @@ -1828,7 +1832,7 @@ static void xgmac_pmt(void __iomem *ioaddr, unsigned long mode) unsigned int pmt = 0; if (mode & WAKE_MAGIC) - pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_MAGIC_PKT; + pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_MAGIC_PKT_EN; if (mode & WAKE_UCAST) pmt |= XGMAC_PMT_POWERDOWN | XGMAC_PMT_GLBL_UNICAST; -- cgit v1.2.3-55-g7522 From cd68ddd4c29ab523440299f24ff2417fe7a0dca6 Mon Sep 17 00:00:00 2001 From: Vijay Subramanian Date: Thu, 28 Mar 2013 13:52:00 +0000 Subject: net: fq_codel: Fix off-by-one error Currently, we hold a max of sch->limit -1 number of packets instead of sch->limit packets. Fix this off-by-one error. Signed-off-by: Vijay Subramanian Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/sched/sch_fq_codel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 4e606fcb2534..55786283a3df 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -195,7 +195,7 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch) flow->deficit = q->quantum; flow->dropped = 0; } - if (++sch->q.qlen < sch->limit) + if (++sch->q.qlen <= sch->limit) return NET_XMIT_SUCCESS; q->drop_overlimit++; -- cgit v1.2.3-55-g7522 From 188ab1b105c96656f6bcfb49d0d8bb1b1936b632 Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Thu, 28 Mar 2013 18:10:50 +0000 Subject: atl1e: drop pci-msi support because of packet corruption Usage of pci-msi results in corrupted dma packet transfers to the host. Reported-by: rebelyouth Cc: Huang, Xiong Tested-by: Christian Sünkenberg Signed-off-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- drivers/net/ethernet/atheros/atl1e/atl1e.h | 1 - drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 19 ++----------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e.h b/drivers/net/ethernet/atheros/atl1e/atl1e.h index 829b5ad71d0d..edfdf6b950e7 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e.h +++ b/drivers/net/ethernet/atheros/atl1e/atl1e.h @@ -438,7 +438,6 @@ struct atl1e_adapter { struct atl1e_hw hw; struct atl1e_hw_stats hw_stats; - bool have_msi; u32 wol; u16 link_speed; u16 link_duplex; diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 92f4734f860d..f73d5609439a 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -1849,34 +1849,19 @@ static void atl1e_free_irq(struct atl1e_adapter *adapter) struct net_device *netdev = adapter->netdev; free_irq(adapter->pdev->irq, netdev); - - if (adapter->have_msi) - pci_disable_msi(adapter->pdev); } static int atl1e_request_irq(struct atl1e_adapter *adapter) { struct pci_dev *pdev = adapter->pdev; struct net_device *netdev = adapter->netdev; - int flags = 0; int err = 0; - adapter->have_msi = true; - err = pci_enable_msi(pdev); - if (err) { - netdev_dbg(netdev, - "Unable to allocate MSI interrupt Error: %d\n", err); - adapter->have_msi = false; - } - - if (!adapter->have_msi) - flags |= IRQF_SHARED; - err = request_irq(pdev->irq, atl1e_intr, flags, netdev->name, netdev); + err = request_irq(pdev->irq, atl1e_intr, IRQF_SHARED, netdev->name, + netdev); if (err) { netdev_dbg(adapter->netdev, "Unable to allocate interrupt Error: %d\n", err); - if (adapter->have_msi) - pci_disable_msi(pdev); return err; } netdev_dbg(netdev, "atl1e_request_irq OK\n"); -- cgit v1.2.3-55-g7522 From 8622315e0142eba78ec0a8075b5a6fd481a059a4 Mon Sep 17 00:00:00 2001 From: Manish Chopra Date: Thu, 28 Mar 2013 23:54:08 +0000 Subject: MAINTAINERS: Update netxen_nic maintainers list o Add myself to netxen_nic maintainers list Signed-off-by: Manish Chopra Signed-off-by: David S. Miller --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 457ff5c52396..6e6d606e13dc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5562,6 +5562,7 @@ F: include/uapi/linux/if_* F: include/uapi/linux/netdevice.h NETXEN (1/10) GbE SUPPORT +M: Manish Chopra M: Sony Chacko M: Rajesh Borundia L: netdev@vger.kernel.org -- cgit v1.2.3-55-g7522 From 00cfec37484761a44a3b6f4675a54caa618210ae Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 29 Mar 2013 03:01:22 +0000 Subject: net: add a synchronize_net() in netdev_rx_handler_unregister() commit 35d48903e97819 (bonding: fix rx_handler locking) added a race in bonding driver, reported by Steven Rostedt who did a very good diagnosis : I'm currently debugging a crash in an old 3.0-rt kernel that one of our customers is seeing. The bug happens with a stress test that loads and unloads the bonding module in a loop (I don't know all the details as I'm not the one that is directly interacting with the customer). But the bug looks to be something that may still be present and possibly present in mainline too. It will just be much harder to trigger it in mainline. In -rt, interrupts are threads, and can schedule in and out just like any other thread. Note, mainline now supports interrupt threads so this may be easily reproducible in mainline as well. I don't have the ability to tell the customer to try mainline or other kernels, so my hands are somewhat tied to what I can do. But according to a core dump, I tracked down that the eth irq thread crashed in bond_handle_frame() here: slave = bond_slave_get_rcu(skb->dev); bond = slave->bond; <--- BUG the slave returned was NULL and accessing slave->bond caused a NULL pointer dereference. Looking at the code that unregisters the handler: void netdev_rx_handler_unregister(struct net_device *dev) { ASSERT_RTNL(); RCU_INIT_POINTER(dev->rx_handler, NULL); RCU_INIT_POINTER(dev->rx_handler_data, NULL); } Which is basically: dev->rx_handler = NULL; dev->rx_handler_data = NULL; And looking at __netif_receive_skb() we have: rx_handler = rcu_dereference(skb->dev->rx_handler); if (rx_handler) { if (pt_prev) { ret = deliver_skb(skb, pt_prev, orig_dev); pt_prev = NULL; } switch (rx_handler(&skb)) { My question to all of you is, what stops this interrupt from happening while the bonding module is unloading? What happens if the interrupt triggers and we have this: CPU0 CPU1 ---- ---- rx_handler = skb->dev->rx_handler netdev_rx_handler_unregister() { dev->rx_handler = NULL; dev->rx_handler_data = NULL; rx_handler() bond_handle_frame() { slave = skb->dev->rx_handler; bond = slave->bond; <-- NULL pointer dereference!!! What protection am I missing in the bond release handler that would prevent the above from happening? We can fix bug this in two ways. First is adding a test in bond_handle_frame() and others to check if rx_handler_data is NULL. A second way is adding a synchronize_net() in netdev_rx_handler_unregister() to make sure that a rcu protected reader has the guarantee to see a non NULL rx_handler_data. The second way is better as it avoids an extra test in fast path. Reported-by: Steven Rostedt Signed-off-by: Eric Dumazet Cc: Jiri Pirko Cc: Paul E. McKenney Acked-by: Steven Rostedt Reviewed-by: Paul E. McKenney Signed-off-by: David S. Miller --- net/core/dev.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/core/dev.c b/net/core/dev.c index 6591440cc03d..13e6447f0398 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3313,6 +3313,7 @@ int netdev_rx_handler_register(struct net_device *dev, if (dev->rx_handler) return -EBUSY; + /* Note: rx_handler_data must be set before rx_handler */ rcu_assign_pointer(dev->rx_handler_data, rx_handler_data); rcu_assign_pointer(dev->rx_handler, rx_handler); @@ -3333,6 +3334,11 @@ void netdev_rx_handler_unregister(struct net_device *dev) ASSERT_RTNL(); RCU_INIT_POINTER(dev->rx_handler, NULL); + /* a reader seeing a non NULL rx_handler in a rcu_read_lock() + * section has a guarantee to see a non NULL rx_handler_data + * as well. + */ + synchronize_net(); RCU_INIT_POINTER(dev->rx_handler_data, NULL); } EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); -- cgit v1.2.3-55-g7522 From 14bc435ea54cb888409efb54fc6b76c13ef530e9 Mon Sep 17 00:00:00 2001 From: Max.Nekludov@us.elster.com Date: Fri, 29 Mar 2013 05:27:36 +0000 Subject: ks8851: Fix interpretation of rxlen field. According to the Datasheet (page 52): 15-12 Reserved 11-0 RXBC Receive Byte Count This field indicates the present received frame byte size. The code has a bug: rxh = ks8851_rdreg32(ks, KS_RXFHSR); rxstat = rxh & 0xffff; rxlen = rxh >> 16; // BUG!!! 0xFFF mask should be applied Signed-off-by: Max Nekludov Signed-off-by: David S. Miller --- drivers/net/ethernet/micrel/ks8851.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 33bcb63d56a2..8fb481252e2c 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -528,7 +528,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) for (; rxfc != 0; rxfc--) { rxh = ks8851_rdreg32(ks, KS_RXFHSR); rxstat = rxh & 0xffff; - rxlen = rxh >> 16; + rxlen = (rxh >> 16) & 0xfff; netif_dbg(ks, rx_status, ks->netdev, "rx: stat 0x%04x, len 0x%04x\n", rxstat, rxlen); -- cgit v1.2.3-55-g7522 From 165b1b8bbc17c9469b053bab78b11b7cbce6d161 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Fri, 29 Mar 2013 16:30:07 +0530 Subject: virtio: console: rename cvq_lock to c_ivq_lock The cvq_lock was taken for the c_ivq. Rename the lock to make that obvious. We'll also add a lock around the c_ovq in the next commit, so there's no ambiguity. Signed-off-by: Amit Shah Reviewed-by: Asias He Reviewed-by: Wanlong Gao Signed-off-by: Rusty Russell Cc: stable@kernel.org --- drivers/char/virtio_console.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index e6ba6b7887e9..2dd9134faa27 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -149,7 +149,7 @@ struct ports_device { spinlock_t ports_lock; /* To protect the vq operations for the control channel */ - spinlock_t cvq_lock; + spinlock_t c_ivq_lock; /* The current config space is stored here */ struct virtio_console_config config; @@ -1709,23 +1709,23 @@ static void control_work_handler(struct work_struct *work) portdev = container_of(work, struct ports_device, control_work); vq = portdev->c_ivq; - spin_lock(&portdev->cvq_lock); + spin_lock(&portdev->c_ivq_lock); while ((buf = virtqueue_get_buf(vq, &len))) { - spin_unlock(&portdev->cvq_lock); + spin_unlock(&portdev->c_ivq_lock); buf->len = len; buf->offset = 0; handle_control_message(portdev, buf); - spin_lock(&portdev->cvq_lock); + spin_lock(&portdev->c_ivq_lock); if (add_inbuf(portdev->c_ivq, buf) < 0) { dev_warn(&portdev->vdev->dev, "Error adding buffer to queue\n"); free_buf(buf, false); } } - spin_unlock(&portdev->cvq_lock); + spin_unlock(&portdev->c_ivq_lock); } static void out_intr(struct virtqueue *vq) @@ -1996,10 +1996,11 @@ static int virtcons_probe(struct virtio_device *vdev) if (multiport) { unsigned int nr_added_bufs; - spin_lock_init(&portdev->cvq_lock); + spin_lock_init(&portdev->c_ivq_lock); INIT_WORK(&portdev->control_work, &control_work_handler); - nr_added_bufs = fill_queue(portdev->c_ivq, &portdev->cvq_lock); + nr_added_bufs = fill_queue(portdev->c_ivq, + &portdev->c_ivq_lock); if (!nr_added_bufs) { dev_err(&vdev->dev, "Error allocating buffers for control queue\n"); @@ -2150,7 +2151,7 @@ static int virtcons_restore(struct virtio_device *vdev) return ret; if (use_multiport(portdev)) - fill_queue(portdev->c_ivq, &portdev->cvq_lock); + fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); list_for_each_entry(port, &portdev->ports, list) { port->in_vq = portdev->in_vqs[port->id]; -- cgit v1.2.3-55-g7522 From 9ba5c80b1aea8648a3efe5f22dc1f7cacdfbeeb8 Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Fri, 29 Mar 2013 16:30:08 +0530 Subject: virtio: console: add locking around c_ovq operations When multiple ovq operations are being performed (lots of open/close operations on virtio_console fds), the __send_control_msg() function can get confused without locking. A simple recipe to cause badness is: * create a QEMU VM with two virtio-serial ports * in the guest, do while true;do echo abc >/dev/vport0p1;done while true;do echo edf >/dev/vport0p2;done In one run, this caused a panic in __send_control_msg(). In another, I got virtio_console virtio0: control-o:id 0 is not a head! This also results repeated messages similar to these on the host: qemu-kvm: virtio-serial-bus: Unexpected port id 478762112 for device virtio-serial-bus.0 qemu-kvm: virtio-serial-bus: Unexpected port id 478762368 for device virtio-serial-bus.0 Reported-by: FuXiangChun Signed-off-by: Amit Shah Reviewed-by: Wanlong Gao Reviewed-by: Asias He Signed-off-by: Rusty Russell Cc: stable@kernel.org --- drivers/char/virtio_console.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 2dd9134faa27..ce5f3fc25d6d 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -150,6 +150,7 @@ struct ports_device { /* To protect the vq operations for the control channel */ spinlock_t c_ivq_lock; + spinlock_t c_ovq_lock; /* The current config space is stored here */ struct virtio_console_config config; @@ -569,11 +570,14 @@ static ssize_t __send_control_msg(struct ports_device *portdev, u32 port_id, vq = portdev->c_ovq; sg_init_one(sg, &cpkt, sizeof(cpkt)); + + spin_lock(&portdev->c_ovq_lock); if (virtqueue_add_buf(vq, sg, 1, 0, &cpkt, GFP_ATOMIC) == 0) { virtqueue_kick(vq); while (!virtqueue_get_buf(vq, &len)) cpu_relax(); } + spin_unlock(&portdev->c_ovq_lock); return 0; } @@ -1997,6 +2001,7 @@ static int virtcons_probe(struct virtio_device *vdev) unsigned int nr_added_bufs; spin_lock_init(&portdev->c_ivq_lock); + spin_lock_init(&portdev->c_ovq_lock); INIT_WORK(&portdev->control_work, &control_work_handler); nr_added_bufs = fill_queue(portdev->c_ivq, -- cgit v1.2.3-55-g7522 From a3d9052c6296ad3398d3ad649c3c682c3e7ecfa6 Mon Sep 17 00:00:00 2001 From: Mac Lin Date: Mon, 25 Mar 2013 17:23:33 +0800 Subject: ARM: cns3xxx: fix mapping of private memory region Since commit 0536bdf33faf (ARM: move iotable mappings within the vmalloc region), the Cavium CNS3xxx cannot boot anymore. This is caused by the pre-defined iotable mappings is not in the vmalloc region. This patch move the iotable mappings into the vmalloc region, and merge the MPCore private memory region (containing the SCU, the GIC and the TWD) as a single region. Signed-off-by: Mac Lin Signed-off-by: Anton Vorontsov Cc: stable@vger.kernel.org [v3.3+] --- arch/arm/mach-cns3xxx/core.c | 16 +++------------- arch/arm/mach-cns3xxx/include/mach/cns3xxx.h | 16 ++++++++-------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/arch/arm/mach-cns3xxx/core.c b/arch/arm/mach-cns3xxx/core.c index e698f26cc0cb..52e4bb5cf12d 100644 --- a/arch/arm/mach-cns3xxx/core.c +++ b/arch/arm/mach-cns3xxx/core.c @@ -22,19 +22,9 @@ static struct map_desc cns3xxx_io_desc[] __initdata = { { - .virtual = CNS3XXX_TC11MP_TWD_BASE_VIRT, - .pfn = __phys_to_pfn(CNS3XXX_TC11MP_TWD_BASE), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT, - .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_CPU_BASE), - .length = SZ_4K, - .type = MT_DEVICE, - }, { - .virtual = CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT, - .pfn = __phys_to_pfn(CNS3XXX_TC11MP_GIC_DIST_BASE), - .length = SZ_4K, + .virtual = CNS3XXX_TC11MP_SCU_BASE_VIRT, + .pfn = __phys_to_pfn(CNS3XXX_TC11MP_SCU_BASE), + .length = SZ_8K, .type = MT_DEVICE, }, { .virtual = CNS3XXX_TIMER1_2_3_BASE_VIRT, diff --git a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h index 191c8e57f289..b1021aafa481 100644 --- a/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h +++ b/arch/arm/mach-cns3xxx/include/mach/cns3xxx.h @@ -94,10 +94,10 @@ #define RTC_INTR_STS_OFFSET 0x34 #define CNS3XXX_MISC_BASE 0x76000000 /* Misc Control */ -#define CNS3XXX_MISC_BASE_VIRT 0xFFF07000 /* Misc Control */ +#define CNS3XXX_MISC_BASE_VIRT 0xFB000000 /* Misc Control */ #define CNS3XXX_PM_BASE 0x77000000 /* Power Management Control */ -#define CNS3XXX_PM_BASE_VIRT 0xFFF08000 +#define CNS3XXX_PM_BASE_VIRT 0xFB001000 #define PM_CLK_GATE_OFFSET 0x00 #define PM_SOFT_RST_OFFSET 0x04 @@ -109,7 +109,7 @@ #define PM_PLL_HM_PD_OFFSET 0x1C #define CNS3XXX_UART0_BASE 0x78000000 /* UART 0 */ -#define CNS3XXX_UART0_BASE_VIRT 0xFFF09000 +#define CNS3XXX_UART0_BASE_VIRT 0xFB002000 #define CNS3XXX_UART1_BASE 0x78400000 /* UART 1 */ #define CNS3XXX_UART1_BASE_VIRT 0xFFF0A000 @@ -130,7 +130,7 @@ #define CNS3XXX_I2S_BASE_VIRT 0xFFF10000 #define CNS3XXX_TIMER1_2_3_BASE 0x7C800000 /* Timer */ -#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFFF10800 +#define CNS3XXX_TIMER1_2_3_BASE_VIRT 0xFB003000 #define TIMER1_COUNTER_OFFSET 0x00 #define TIMER1_AUTO_RELOAD_OFFSET 0x04 @@ -227,16 +227,16 @@ * Testchip peripheral and fpga gic regions */ #define CNS3XXX_TC11MP_SCU_BASE 0x90000000 /* IRQ, Test chip */ -#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFF000000 +#define CNS3XXX_TC11MP_SCU_BASE_VIRT 0xFB004000 #define CNS3XXX_TC11MP_GIC_CPU_BASE 0x90000100 /* Test chip interrupt controller CPU interface */ -#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT 0xFF000100 +#define CNS3XXX_TC11MP_GIC_CPU_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x100) #define CNS3XXX_TC11MP_TWD_BASE 0x90000600 -#define CNS3XXX_TC11MP_TWD_BASE_VIRT 0xFF000600 +#define CNS3XXX_TC11MP_TWD_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x600) #define CNS3XXX_TC11MP_GIC_DIST_BASE 0x90001000 /* Test chip interrupt controller distributor */ -#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT 0xFF001000 +#define CNS3XXX_TC11MP_GIC_DIST_BASE_VIRT (CNS3XXX_TC11MP_SCU_BASE_VIRT + 0x1000) #define CNS3XXX_TC11MP_L220_BASE 0x92002000 /* L220 registers */ #define CNS3XXX_TC11MP_L220_BASE_VIRT 0xFF002000 -- cgit v1.2.3-55-g7522 From 9593b0b1179c526436f14849a9587fd2aae12040 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Thu, 28 Mar 2013 10:39:28 +0100 Subject: NFC: microread: Fix build failure due to a new MEI bus API uuid device_id field is removed and mei_device is renamed mei_cl_device. Signed-off-by: Samuel Ortiz --- drivers/nfc/microread/mei.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/nfc/microread/mei.c b/drivers/nfc/microread/mei.c index eef38cfd812e..ca33ae193935 100644 --- a/drivers/nfc/microread/mei.c +++ b/drivers/nfc/microread/mei.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -32,9 +32,6 @@ #define MICROREAD_DRIVER_NAME "microread" -#define MICROREAD_UUID UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, 0x94, \ - 0xd4, 0x50, 0x26, 0x67, 0x23, 0x77, 0x5c) - struct mei_nfc_hdr { u8 cmd; u8 status; @@ -48,7 +45,7 @@ struct mei_nfc_hdr { #define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD) struct microread_mei_phy { - struct mei_device *mei_device; + struct mei_cl_device *device; struct nfc_hci_dev *hdev; int powered; @@ -105,14 +102,14 @@ static int microread_mei_write(void *phy_id, struct sk_buff *skb) MEI_DUMP_SKB_OUT("mei frame sent", skb); - r = mei_send(phy->device, skb->data, skb->len); + r = mei_cl_send(phy->device, skb->data, skb->len); if (r > 0) r = 0; return r; } -static void microread_event_cb(struct mei_device *device, u32 events, +static void microread_event_cb(struct mei_cl_device *device, u32 events, void *context) { struct microread_mei_phy *phy = context; @@ -120,7 +117,7 @@ static void microread_event_cb(struct mei_device *device, u32 events, if (phy->hard_fault != 0) return; - if (events & BIT(MEI_EVENT_RX)) { + if (events & BIT(MEI_CL_EVENT_RX)) { struct sk_buff *skb; int reply_size; @@ -128,7 +125,7 @@ static void microread_event_cb(struct mei_device *device, u32 events, if (!skb) return; - reply_size = mei_recv(device, skb->data, MEI_NFC_MAX_READ); + reply_size = mei_cl_recv(device, skb->data, MEI_NFC_MAX_READ); if (reply_size < MEI_NFC_HEADER_SIZE) { kfree(skb); return; @@ -149,8 +146,8 @@ static struct nfc_phy_ops mei_phy_ops = { .disable = microread_mei_disable, }; -static int microread_mei_probe(struct mei_device *device, - const struct mei_id *id) +static int microread_mei_probe(struct mei_cl_device *device, + const struct mei_cl_device_id *id) { struct microread_mei_phy *phy; int r; @@ -164,9 +161,9 @@ static int microread_mei_probe(struct mei_device *device, } phy->device = device; - mei_set_clientdata(device, phy); + mei_cl_set_drvdata(device, phy); - r = mei_register_event_cb(device, microread_event_cb, phy); + r = mei_cl_register_event_cb(device, microread_event_cb, phy); if (r) { pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n"); goto err_out; @@ -186,9 +183,9 @@ err_out: return r; } -static int microread_mei_remove(struct mei_device *device) +static int microread_mei_remove(struct mei_cl_device *device) { - struct microread_mei_phy *phy = mei_get_clientdata(device); + struct microread_mei_phy *phy = mei_cl_get_drvdata(device); pr_info("Removing microread\n"); @@ -202,16 +199,15 @@ static int microread_mei_remove(struct mei_device *device) return 0; } -static struct mei_id microread_mei_tbl[] = { - { MICROREAD_DRIVER_NAME, MICROREAD_UUID }, +static struct mei_cl_device_id microread_mei_tbl[] = { + { MICROREAD_DRIVER_NAME }, /* required last entry */ { } }; - MODULE_DEVICE_TABLE(mei, microread_mei_tbl); -static struct mei_driver microread_driver = { +static struct mei_cl_driver microread_driver = { .id_table = microread_mei_tbl, .name = MICROREAD_DRIVER_NAME, @@ -225,7 +221,7 @@ static int microread_mei_init(void) pr_debug(DRIVER_DESC ": %s\n", __func__); - r = mei_driver_register(µread_driver); + r = mei_cl_driver_register(µread_driver); if (r) { pr_err(MICROREAD_DRIVER_NAME ": driver registration failed\n"); return r; @@ -236,7 +232,7 @@ static int microread_mei_init(void) static void microread_mei_exit(void) { - mei_driver_unregister(µread_driver); + mei_cl_driver_unregister(µread_driver); } module_init(microread_mei_init); -- cgit v1.2.3-55-g7522 From 1e1b812bbe1069fc8e2e372dca7d5f541c7a8ceb Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 31 Mar 2013 09:50:07 +0000 Subject: sh_eth: fix handling of no LINK signal The code handling the absent LINK signal (or the absent PSR register -- which reflects the state of this signal) is quite naive and has probably never really worked. It's probably enough to say that this code is executed only on the LINK change interrupt (sic!) but even if we actually have the signal and choose to ignore it (it might be connected to PHY's link/activity LED output as on the Renesas BOCK-W board), sh_eth_adjust_link() on which this code relies to update 'mdp->link' gets executed later than the LINK change interrupt where it is checked, and so RX/TX never get enabled via ECMR register. So, ignore the LINK changed interrupt iff LINK signal is absent (or just chosen not to be used) or PSR register is absent, and enable/disable RX/TX directly in sh_eth_adjust_link() in this case. Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index bf5e3cf97c4d..1ca8b2b10adc 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1216,10 +1216,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) if (felic_stat & ECSR_LCHNG) { /* Link Changed */ if (mdp->cd->no_psr || mdp->no_ether_link) { - if (mdp->link == PHY_DOWN) - link_stat = 0; - else - link_stat = PHY_ST_LINK; + goto ignore_link; } else { link_stat = (sh_eth_read(ndev, PSR)); if (mdp->ether_link_active_low) @@ -1242,6 +1239,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status) } } +ignore_link: if (intr_status & EESR_TWB) { /* Write buck end. unused write back interrupt */ if (intr_status & EESR_TABT) /* Transmit Abort int */ @@ -1392,12 +1390,16 @@ static void sh_eth_adjust_link(struct net_device *ndev) (sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR); new_state = 1; mdp->link = phydev->link; + if (mdp->cd->no_psr || mdp->no_ether_link) + sh_eth_rcv_snd_enable(ndev); } } else if (mdp->link) { new_state = 1; mdp->link = PHY_DOWN; mdp->speed = 0; mdp->duplex = -1; + if (mdp->cd->no_psr || mdp->no_ether_link) + sh_eth_rcv_snd_disable(ndev); } if (new_state && netif_msg_link(mdp)) -- cgit v1.2.3-55-g7522 From 3893b27345ac0ff13c1b9ec20ad50966b810997e Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 31 Mar 2013 09:54:20 +0000 Subject: sh_eth: workaround for spurious ECI interrupt At least on Renesas R8A7778, EESR.ECI interrupt seems to fire regardless of its mask in EESIPR register. I can 100% reproduce it with the following scenario: target is booted with 'ip=on' option, and so IP-Config opens SoC Ether device but doesn't get a proper reply and then succeeds with on-board SMC chip; then I login and try to bring up the SoC Ether device with 'ifconfig', and I get an ECI interrupt once request_irq() is called by sh_eth_open() (while interrupt mask in EESIPR register is all 0), if that interrupt is accompanied by a pending EESR.FRC (frame receive completion) interrupt, I get kernel oops in sh_eth_rx() because sh_eth_ring_init() hasn't been called yet! The solution I worked out is the following: in sh_eth_interrupt(), mask the interrupt status from EESR register with the interrupt mask from EESIPR register in order not to handle the disabled interrupts -- but forcing EESIPR.M_ECI bit in this mask set because we always need to fully handle EESR.ECI interrupt in sh_eth_error() in order to quench it (as it doesn't get cleared by just writing 1 to the this bit as all the other interrupts). While at it, remove unneeded initializer for 'intr_status' variable and give it *unsigned long* type, matching the type of sh_eth_read()'s result; fix comment. Signed-off-by: Sergei Shtylyov Reviewed-by: Max Filippov Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 1ca8b2b10adc..44f7904e5054 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1324,12 +1324,18 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_cpu_data *cd = mdp->cd; irqreturn_t ret = IRQ_NONE; - u32 intr_status = 0; + unsigned long intr_status; spin_lock(&mdp->lock); - /* Get interrpt stat */ + /* Get interrupt status */ intr_status = sh_eth_read(ndev, EESR); + /* Mask it with the interrupt mask, forcing ECI interrupt to be always + * enabled since it's the one that comes thru regardless of the mask, + * and we need to fully handle it in sh_eth_error() in order to quench + * it as it doesn't get cleared by just writing 1 to the ECI bit... + */ + intr_status &= sh_eth_read(ndev, EESIPR) | DMAC_M_ECI; /* Clear interrupt */ if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF | EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF | -- cgit v1.2.3-55-g7522 From 3340d2aae3433ad9147f6bf0adc452b324e31591 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 31 Mar 2013 10:11:04 +0000 Subject: sh_eth: make 'link' field of 'struct sh_eth_private' *int* The 'link' field of 'struct sh_eth_private' has type 'enum phy_state' while the 'link' field of 'struct phy_device' is merely *int* (having values 0 and 1) and the former field gets assigned from the latter. Make the field match, getting rid of incorrectly used PHY_DOWN value in assignments/comparisons. Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 8 ++++---- drivers/net/ethernet/renesas/sh_eth.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 44f7904e5054..6ed333fe5c04 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1377,7 +1377,7 @@ static void sh_eth_adjust_link(struct net_device *ndev) struct phy_device *phydev = mdp->phydev; int new_state = 0; - if (phydev->link != PHY_DOWN) { + if (phydev->link) { if (phydev->duplex != mdp->duplex) { new_state = 1; mdp->duplex = phydev->duplex; @@ -1391,7 +1391,7 @@ static void sh_eth_adjust_link(struct net_device *ndev) if (mdp->cd->set_rate) mdp->cd->set_rate(ndev); } - if (mdp->link == PHY_DOWN) { + if (!mdp->link) { sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR); new_state = 1; @@ -1401,7 +1401,7 @@ static void sh_eth_adjust_link(struct net_device *ndev) } } else if (mdp->link) { new_state = 1; - mdp->link = PHY_DOWN; + mdp->link = 0; mdp->speed = 0; mdp->duplex = -1; if (mdp->cd->no_psr || mdp->no_ether_link) @@ -1422,7 +1422,7 @@ static int sh_eth_phy_init(struct net_device *ndev) snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, mdp->mii_bus->id , mdp->phy_id); - mdp->link = PHY_DOWN; + mdp->link = 0; mdp->speed = 0; mdp->duplex = -1; diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index e6655678458e..828be4515008 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -723,7 +723,7 @@ struct sh_eth_private { u32 phy_id; /* PHY ID */ struct mii_bus *mii_bus; /* MDIO bus control */ struct phy_device *phydev; /* PHY device control */ - enum phy_state link; + int link; phy_interface_t phy_interface; int msg_enable; int speed; -- cgit v1.2.3-55-g7522 From 6741f40d198c6a5feb23653a1efd4ca47f93d83d Mon Sep 17 00:00:00 2001 From: Joseph CHANG Date: Thu, 28 Mar 2013 23:13:42 +0000 Subject: DM9000B: driver initialization upgrade Fix bug for DM9000 revision B which contain a DSP PHY DM9000B use DSP PHY instead previouse DM9000 revisions' analog PHY, So need extra change in initialization, For explicity PHY Reset and PHY init parameter, and first DM9000_NCR reset need NCR_MAC_LBK bit by dm9000_probe(). Following DM9000_NCR reset cause by dm9000_open() clear the NCR_MAC_LBK bit. Without this fix, Power-up FIFO pointers error happen around 2% rate among Davicom's customers' boards. With this fix, All above cases can be solved. Signed-off-by: Joseph CHANG Signed-off-by: David S. Miller --- drivers/net/ethernet/davicom/dm9000.c | 214 +++++++++++++++++----------------- drivers/net/ethernet/davicom/dm9000.h | 11 +- 2 files changed, 120 insertions(+), 105 deletions(-) diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c index 8cdf02503d13..9eada8e86078 100644 --- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c @@ -257,6 +257,107 @@ static void dm9000_dumpblk_32bit(void __iomem *reg, int count) tmp = readl(reg); } +/* + * Sleep, either by using msleep() or if we are suspending, then + * use mdelay() to sleep. + */ +static void dm9000_msleep(board_info_t *db, unsigned int ms) +{ + if (db->in_suspend) + mdelay(ms); + else + msleep(ms); +} + +/* Read a word from phyxcer */ +static int +dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) +{ + board_info_t *db = netdev_priv(dev); + unsigned long flags; + unsigned int reg_save; + int ret; + + mutex_lock(&db->addr_lock); + + spin_lock_irqsave(&db->lock, flags); + + /* Save previous register address */ + reg_save = readb(db->io_addr); + + /* Fill the phyxcer register into REG_0C */ + iow(db, DM9000_EPAR, DM9000_PHY | reg); + + /* Issue phyxcer read command */ + iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS); + + writeb(reg_save, db->io_addr); + spin_unlock_irqrestore(&db->lock, flags); + + dm9000_msleep(db, 1); /* Wait read complete */ + + spin_lock_irqsave(&db->lock, flags); + reg_save = readb(db->io_addr); + + iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */ + + /* The read data keeps on REG_0D & REG_0E */ + ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); + + /* restore the previous address */ + writeb(reg_save, db->io_addr); + spin_unlock_irqrestore(&db->lock, flags); + + mutex_unlock(&db->addr_lock); + + dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret); + return ret; +} + +/* Write a word to phyxcer */ +static void +dm9000_phy_write(struct net_device *dev, + int phyaddr_unused, int reg, int value) +{ + board_info_t *db = netdev_priv(dev); + unsigned long flags; + unsigned long reg_save; + + dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value); + mutex_lock(&db->addr_lock); + + spin_lock_irqsave(&db->lock, flags); + + /* Save previous register address */ + reg_save = readb(db->io_addr); + + /* Fill the phyxcer register into REG_0C */ + iow(db, DM9000_EPAR, DM9000_PHY | reg); + + /* Fill the written data into REG_0D & REG_0E */ + iow(db, DM9000_EPDRL, value); + iow(db, DM9000_EPDRH, value >> 8); + + /* Issue phyxcer write command */ + iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW); + + writeb(reg_save, db->io_addr); + spin_unlock_irqrestore(&db->lock, flags); + + dm9000_msleep(db, 1); /* Wait write complete */ + + spin_lock_irqsave(&db->lock, flags); + reg_save = readb(db->io_addr); + + iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ + + /* restore the previous address */ + writeb(reg_save, db->io_addr); + + spin_unlock_irqrestore(&db->lock, flags); + mutex_unlock(&db->addr_lock); +} + /* dm9000_set_io * * select the specified set of io routines to use with the @@ -795,6 +896,9 @@ dm9000_init_dm9000(struct net_device *dev) iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */ + dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */ + dm9000_phy_write(dev, 0, MII_DM_DSPCR, DSPCR_INIT_PARAM); /* Init */ + ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0; /* if wol is needed, then always set NCR_WAKEEN otherwise we end @@ -1201,109 +1305,6 @@ dm9000_open(struct net_device *dev) return 0; } -/* - * Sleep, either by using msleep() or if we are suspending, then - * use mdelay() to sleep. - */ -static void dm9000_msleep(board_info_t *db, unsigned int ms) -{ - if (db->in_suspend) - mdelay(ms); - else - msleep(ms); -} - -/* - * Read a word from phyxcer - */ -static int -dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) -{ - board_info_t *db = netdev_priv(dev); - unsigned long flags; - unsigned int reg_save; - int ret; - - mutex_lock(&db->addr_lock); - - spin_lock_irqsave(&db->lock,flags); - - /* Save previous register address */ - reg_save = readb(db->io_addr); - - /* Fill the phyxcer register into REG_0C */ - iow(db, DM9000_EPAR, DM9000_PHY | reg); - - iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS); /* Issue phyxcer read command */ - - writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock,flags); - - dm9000_msleep(db, 1); /* Wait read complete */ - - spin_lock_irqsave(&db->lock,flags); - reg_save = readb(db->io_addr); - - iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */ - - /* The read data keeps on REG_0D & REG_0E */ - ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); - - /* restore the previous address */ - writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock,flags); - - mutex_unlock(&db->addr_lock); - - dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret); - return ret; -} - -/* - * Write a word to phyxcer - */ -static void -dm9000_phy_write(struct net_device *dev, - int phyaddr_unused, int reg, int value) -{ - board_info_t *db = netdev_priv(dev); - unsigned long flags; - unsigned long reg_save; - - dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value); - mutex_lock(&db->addr_lock); - - spin_lock_irqsave(&db->lock,flags); - - /* Save previous register address */ - reg_save = readb(db->io_addr); - - /* Fill the phyxcer register into REG_0C */ - iow(db, DM9000_EPAR, DM9000_PHY | reg); - - /* Fill the written data into REG_0D & REG_0E */ - iow(db, DM9000_EPDRL, value); - iow(db, DM9000_EPDRH, value >> 8); - - iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW); /* Issue phyxcer write command */ - - writeb(reg_save, db->io_addr); - spin_unlock_irqrestore(&db->lock, flags); - - dm9000_msleep(db, 1); /* Wait write complete */ - - spin_lock_irqsave(&db->lock,flags); - reg_save = readb(db->io_addr); - - iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ - - /* restore the previous address */ - writeb(reg_save, db->io_addr); - - spin_unlock_irqrestore(&db->lock, flags); - mutex_unlock(&db->addr_lock); -} - static void dm9000_shutdown(struct net_device *dev) { @@ -1502,7 +1503,12 @@ dm9000_probe(struct platform_device *pdev) db->flags |= DM9000_PLATF_SIMPLE_PHY; #endif - dm9000_reset(db); + /* Fixing bug on dm9000_probe, takeover dm9000_reset(db), + * Need 'NCR_MAC_LBK' bit to indeed stable our DM9000 fifo + * while probe stage. + */ + + iow(db, DM9000_NCR, NCR_MAC_LBK | NCR_RST); /* try multiple times, DM9000 sometimes gets the read wrong */ for (i = 0; i < 8; i++) { diff --git a/drivers/net/ethernet/davicom/dm9000.h b/drivers/net/ethernet/davicom/dm9000.h index 55688bd1a3ef..9ce058adabab 100644 --- a/drivers/net/ethernet/davicom/dm9000.h +++ b/drivers/net/ethernet/davicom/dm9000.h @@ -69,7 +69,9 @@ #define NCR_WAKEEN (1<<6) #define NCR_FCOL (1<<4) #define NCR_FDX (1<<3) -#define NCR_LBK (3<<1) + +#define NCR_RESERVED (3<<1) +#define NCR_MAC_LBK (1<<1) #define NCR_RST (1<<0) #define NSR_SPEED (1<<7) @@ -167,5 +169,12 @@ #define ISR_LNKCHNG (1<<5) #define ISR_UNDERRUN (1<<4) +/* Davicom MII registers. + */ + +#define MII_DM_DSPCR 0x1b /* DSP Control Register */ + +#define DSPCR_INIT_PARAM 0xE100 /* DSP init parameter */ + #endif /* _DM9000X_H_ */ -- cgit v1.2.3-55-g7522 From 4e33a0634c051aff538f2daae81eff4b3e191d4a Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 13 Mar 2013 13:25:43 +0800 Subject: ARM: imx: remove duplicated function declaration Commit 13eed98 (arm/imx6q: add device tree machine support) added duplicated function declaration for imx_enable_cpu() and imx_set_cpu_jump(). Remove them. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/common.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 5a800bfcec5b..048e6c850f54 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -122,8 +122,6 @@ static inline void imx_scu_map_io(void) {} static inline void imx_smp_prepare(void) {} static inline void imx_scu_standby_enable(void) {} #endif -extern void imx_enable_cpu(int cpu, bool enable); -extern void imx_set_cpu_jump(int cpu, void *jump_addr); extern void imx_src_init(void); extern void imx_src_prepare_restart(void); extern void imx_gpc_init(void); -- cgit v1.2.3-55-g7522 From fda7f2267ded7e892b07466eaf7173633ccb17ad Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 13 Mar 2013 13:29:35 +0800 Subject: ARM: imx: remove pl310_get_save_ptr() declaration Commit a1f1c7e (arm/imx6q: add suspend/resume support) added declaration for a non-existing function pl310_get_save_ptr() by mistake. Remove it. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 048e6c850f54..d4b2f369751b 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -111,7 +111,6 @@ void tzic_handle_irq(struct pt_regs *); extern void imx_enable_cpu(int cpu, bool enable); extern void imx_set_cpu_jump(int cpu, void *jump_addr); extern void v7_cpu_resume(void); -extern u32 *pl310_get_save_ptr(void); #ifdef CONFIG_SMP extern void v7_secondary_startup(void); extern void imx_scu_map_io(void); -- cgit v1.2.3-55-g7522 From 180cb7d6ab8cb2a48f11fe2bdde85aa3ab359c3a Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Wed, 27 Mar 2013 14:01:34 +0100 Subject: ARM: imx: Remove cpufreq driver The old cpufreq driver is not necessary anymore with DT and cpufreq-cpu0. Signed-off-by: Markus Pargmann Signed-off-by: Shawn Guo --- arch/arm/Kconfig | 7 -- arch/arm/mach-imx/Makefile | 3 +- arch/arm/mach-imx/cpu_op-mx51.c | 31 ----- arch/arm/mach-imx/cpu_op-mx51.h | 14 --- arch/arm/mach-imx/cpufreq.c | 206 ---------------------------------- arch/arm/mach-imx/mach-cpuimx51sd.c | 5 - arch/arm/mach-imx/mach-mx51_babbage.c | 4 - 7 files changed, 1 insertion(+), 269 deletions(-) delete mode 100644 arch/arm/mach-imx/cpu_op-mx51.c delete mode 100644 arch/arm/mach-imx/cpu_op-mx51.h delete mode 100644 arch/arm/mach-imx/cpufreq.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 13b739469c51..c5ed84c2bdda 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -2153,13 +2153,6 @@ if ARCH_HAS_CPUFREQ source "drivers/cpufreq/Kconfig" -config CPU_FREQ_IMX - tristate "CPUfreq driver for i.MX CPUs" - depends on ARCH_MXC && CPU_FREQ - select CPU_FREQ_TABLE - help - This enables the CPUfreq driver for i.MX CPUs. - config CPU_FREQ_SA1100 bool diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index c4ce0906d76a..23555b0c08a9 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -12,7 +12,7 @@ obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci- obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o imx5-pm-$(CONFIG_PM) += pm-imx5.o -obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o $(imx5-pm-y) cpu_op-mx51.o +obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o mm-imx5.o clk-imx51-imx53.o ehci-imx5.o $(imx5-pm-y) obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ clk-pfd.o clk-busy.o clk.o @@ -27,7 +27,6 @@ obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o obj-$(CONFIG_MXC_ULPI) += ulpi.o obj-$(CONFIG_MXC_USE_EPIT) += epit.o obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o -obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o ifeq ($(CONFIG_CPU_IDLE),y) obj-y += cpuidle.o diff --git a/arch/arm/mach-imx/cpu_op-mx51.c b/arch/arm/mach-imx/cpu_op-mx51.c deleted file mode 100644 index b9ef692b61a2..000000000000 --- a/arch/arm/mach-imx/cpu_op-mx51.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include -#include -#include - -#include "hardware.h" - -static struct cpu_op mx51_cpu_op[] = { - { - .cpu_rate = 160000000,}, - { - .cpu_rate = 800000000,}, -}; - -struct cpu_op *mx51_get_cpu_op(int *op) -{ - *op = ARRAY_SIZE(mx51_cpu_op); - return mx51_cpu_op; -} diff --git a/arch/arm/mach-imx/cpu_op-mx51.h b/arch/arm/mach-imx/cpu_op-mx51.h deleted file mode 100644 index 97477fecb469..000000000000 --- a/arch/arm/mach-imx/cpu_op-mx51.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -extern struct cpu_op *mx51_get_cpu_op(int *op); diff --git a/arch/arm/mach-imx/cpufreq.c b/arch/arm/mach-imx/cpufreq.c deleted file mode 100644 index d8c75c3c925d..000000000000 --- a/arch/arm/mach-imx/cpufreq.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -/* - * A driver for the Freescale Semiconductor i.MXC CPUfreq module. - * The CPUFREQ driver is for controlling CPU frequency. It allows you to change - * the CPU clock speed on the fly. - */ - -#include -#include -#include -#include -#include - -#include "hardware.h" - -#define CLK32_FREQ 32768 -#define NANOSECOND (1000 * 1000 * 1000) - -struct cpu_op *(*get_cpu_op)(int *op); - -static int cpu_freq_khz_min; -static int cpu_freq_khz_max; - -static struct clk *cpu_clk; -static struct cpufreq_frequency_table *imx_freq_table; - -static int cpu_op_nr; -static struct cpu_op *cpu_op_tbl; - -static int set_cpu_freq(int freq) -{ - int ret = 0; - int org_cpu_rate; - - org_cpu_rate = clk_get_rate(cpu_clk); - if (org_cpu_rate == freq) - return ret; - - ret = clk_set_rate(cpu_clk, freq); - if (ret != 0) { - printk(KERN_DEBUG "cannot set CPU clock rate\n"); - return ret; - } - - return ret; -} - -static int mxc_verify_speed(struct cpufreq_policy *policy) -{ - if (policy->cpu != 0) - return -EINVAL; - - return cpufreq_frequency_table_verify(policy, imx_freq_table); -} - -static unsigned int mxc_get_speed(unsigned int cpu) -{ - if (cpu) - return 0; - - return clk_get_rate(cpu_clk) / 1000; -} - -static int mxc_set_target(struct cpufreq_policy *policy, - unsigned int target_freq, unsigned int relation) -{ - struct cpufreq_freqs freqs; - int freq_Hz; - int ret = 0; - unsigned int index; - - cpufreq_frequency_table_target(policy, imx_freq_table, - target_freq, relation, &index); - freq_Hz = imx_freq_table[index].frequency * 1000; - - freqs.old = clk_get_rate(cpu_clk) / 1000; - freqs.new = freq_Hz / 1000; - freqs.cpu = 0; - freqs.flags = 0; - cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); - - ret = set_cpu_freq(freq_Hz); - - cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); - - return ret; -} - -static int mxc_cpufreq_init(struct cpufreq_policy *policy) -{ - int ret; - int i; - - printk(KERN_INFO "i.MXC CPU frequency driver\n"); - - if (policy->cpu != 0) - return -EINVAL; - - if (!get_cpu_op) - return -EINVAL; - - cpu_clk = clk_get(NULL, "cpu_clk"); - if (IS_ERR(cpu_clk)) { - printk(KERN_ERR "%s: failed to get cpu clock\n", __func__); - return PTR_ERR(cpu_clk); - } - - cpu_op_tbl = get_cpu_op(&cpu_op_nr); - - cpu_freq_khz_min = cpu_op_tbl[0].cpu_rate / 1000; - cpu_freq_khz_max = cpu_op_tbl[0].cpu_rate / 1000; - - imx_freq_table = kmalloc( - sizeof(struct cpufreq_frequency_table) * (cpu_op_nr + 1), - GFP_KERNEL); - if (!imx_freq_table) { - ret = -ENOMEM; - goto err1; - } - - for (i = 0; i < cpu_op_nr; i++) { - imx_freq_table[i].index = i; - imx_freq_table[i].frequency = cpu_op_tbl[i].cpu_rate / 1000; - - if ((cpu_op_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min) - cpu_freq_khz_min = cpu_op_tbl[i].cpu_rate / 1000; - - if ((cpu_op_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max) - cpu_freq_khz_max = cpu_op_tbl[i].cpu_rate / 1000; - } - - imx_freq_table[i].index = i; - imx_freq_table[i].frequency = CPUFREQ_TABLE_END; - - policy->cur = clk_get_rate(cpu_clk) / 1000; - policy->min = policy->cpuinfo.min_freq = cpu_freq_khz_min; - policy->max = policy->cpuinfo.max_freq = cpu_freq_khz_max; - - /* Manual states, that PLL stabilizes in two CLK32 periods */ - policy->cpuinfo.transition_latency = 2 * NANOSECOND / CLK32_FREQ; - - ret = cpufreq_frequency_table_cpuinfo(policy, imx_freq_table); - - if (ret < 0) { - printk(KERN_ERR "%s: failed to register i.MXC CPUfreq with error code %d\n", - __func__, ret); - goto err; - } - - cpufreq_frequency_table_get_attr(imx_freq_table, policy->cpu); - return 0; -err: - kfree(imx_freq_table); -err1: - clk_put(cpu_clk); - return ret; -} - -static int mxc_cpufreq_exit(struct cpufreq_policy *policy) -{ - cpufreq_frequency_table_put_attr(policy->cpu); - - set_cpu_freq(cpu_freq_khz_max * 1000); - clk_put(cpu_clk); - kfree(imx_freq_table); - return 0; -} - -static struct cpufreq_driver mxc_driver = { - .flags = CPUFREQ_STICKY, - .verify = mxc_verify_speed, - .target = mxc_set_target, - .get = mxc_get_speed, - .init = mxc_cpufreq_init, - .exit = mxc_cpufreq_exit, - .name = "imx", -}; - -static int mxc_cpufreq_driver_init(void) -{ - return cpufreq_register_driver(&mxc_driver); -} - -static void mxc_cpufreq_driver_exit(void) -{ - cpufreq_unregister_driver(&mxc_driver); -} - -module_init(mxc_cpufreq_driver_init); -module_exit(mxc_cpufreq_driver_exit); - -MODULE_AUTHOR("Freescale Semiconductor Inc. Yong Shen "); -MODULE_DESCRIPTION("CPUfreq driver for i.MX"); -MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-imx/mach-cpuimx51sd.c b/arch/arm/mach-imx/mach-cpuimx51sd.c index 9b7393234f6f..9b5ddf5bbd33 100644 --- a/arch/arm/mach-imx/mach-cpuimx51sd.c +++ b/arch/arm/mach-imx/mach-cpuimx51sd.c @@ -33,7 +33,6 @@ #include "common.h" #include "devices-imx51.h" -#include "cpu_op-mx51.h" #include "eukrea-baseboards.h" #include "hardware.h" #include "iomux-mx51.h" @@ -285,10 +284,6 @@ static void __init eukrea_cpuimx51sd_init(void) mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx51sd_pads, ARRAY_SIZE(eukrea_cpuimx51sd_pads)); -#if defined(CONFIG_CPU_FREQ_IMX) - get_cpu_op = mx51_get_cpu_op; -#endif - imx51_add_imx_uart(0, &uart_pdata); imx51_add_mxc_nand(&eukrea_cpuimx51sd_nand_board_info); imx51_add_imx2_wdt(0); diff --git a/arch/arm/mach-imx/mach-mx51_babbage.c b/arch/arm/mach-imx/mach-mx51_babbage.c index 6c4d7feb4520..f3d264a636fa 100644 --- a/arch/arm/mach-imx/mach-mx51_babbage.c +++ b/arch/arm/mach-imx/mach-mx51_babbage.c @@ -27,7 +27,6 @@ #include "common.h" #include "devices-imx51.h" -#include "cpu_op-mx51.h" #include "hardware.h" #include "iomux-mx51.h" @@ -371,9 +370,6 @@ static void __init mx51_babbage_init(void) imx51_soc_init(); -#if defined(CONFIG_CPU_FREQ_IMX) - get_cpu_op = mx51_get_cpu_op; -#endif imx51_babbage_common_init(); imx51_add_imx_uart(0, &uart_pdata); -- cgit v1.2.3-55-g7522 From 375981f2e14868be16cafbffd34a4f16a6ee01c6 Mon Sep 17 00:00:00 2001 From: Girish K S Date: Wed, 13 Mar 2013 12:13:30 +0530 Subject: spi/s3c64xx: modified error interrupt handling and init The status of the interrupt is available in the status register, so reading the clear pending register and writing back the same value will not actually clear the pending interrupts. This patch modifies the interrupt handler to read the status register and clear the corresponding pending bit in the clear pending register. Modified the hwInit function to clear all the pending interrupts. Signed-off-by: Girish K S Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-s3c64xx.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index e862ab8853aa..4188b2faac5c 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -994,25 +994,30 @@ static irqreturn_t s3c64xx_spi_irq(int irq, void *data) { struct s3c64xx_spi_driver_data *sdd = data; struct spi_master *spi = sdd->master; - unsigned int val; + unsigned int val, clr = 0; - val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR); + val = readl(sdd->regs + S3C64XX_SPI_STATUS); - val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR | - S3C64XX_SPI_PND_RX_UNDERRUN_CLR | - S3C64XX_SPI_PND_TX_OVERRUN_CLR | - S3C64XX_SPI_PND_TX_UNDERRUN_CLR; - - writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR); - - if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR) + if (val & S3C64XX_SPI_ST_RX_OVERRUN_ERR) { + clr = S3C64XX_SPI_PND_RX_OVERRUN_CLR; dev_err(&spi->dev, "RX overrun\n"); - if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR) + } + if (val & S3C64XX_SPI_ST_RX_UNDERRUN_ERR) { + clr |= S3C64XX_SPI_PND_RX_UNDERRUN_CLR; dev_err(&spi->dev, "RX underrun\n"); - if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR) + } + if (val & S3C64XX_SPI_ST_TX_OVERRUN_ERR) { + clr |= S3C64XX_SPI_PND_TX_OVERRUN_CLR; dev_err(&spi->dev, "TX overrun\n"); - if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR) + } + if (val & S3C64XX_SPI_ST_TX_UNDERRUN_ERR) { + clr |= S3C64XX_SPI_PND_TX_UNDERRUN_CLR; dev_err(&spi->dev, "TX underrun\n"); + } + + /* Clear the pending irq by setting and then clearing it */ + writel(clr, sdd->regs + S3C64XX_SPI_PENDING_CLR); + writel(0, sdd->regs + S3C64XX_SPI_PENDING_CLR); return IRQ_HANDLED; } @@ -1036,9 +1041,13 @@ static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) writel(0, regs + S3C64XX_SPI_MODE_CFG); writel(0, regs + S3C64XX_SPI_PACKET_CNT); - /* Clear any irq pending bits */ - writel(readl(regs + S3C64XX_SPI_PENDING_CLR), - regs + S3C64XX_SPI_PENDING_CLR); + /* Clear any irq pending bits, should set and clear the bits */ + val = S3C64XX_SPI_PND_RX_OVERRUN_CLR | + S3C64XX_SPI_PND_RX_UNDERRUN_CLR | + S3C64XX_SPI_PND_TX_OVERRUN_CLR | + S3C64XX_SPI_PND_TX_UNDERRUN_CLR; + writel(val, regs + S3C64XX_SPI_PENDING_CLR); + writel(0, regs + S3C64XX_SPI_PENDING_CLR); writel(0, regs + S3C64XX_SPI_SWAP_CFG); -- cgit v1.2.3-55-g7522 From b0b36b861e434ee1c1a64cb39259e262f79af62e Mon Sep 17 00:00:00 2001 From: Bryan Freed Date: Wed, 13 Mar 2013 11:17:40 -0700 Subject: spi: Unlock a spinlock before calling into the controller driver. spi_pump_messages() calls into a controller driver with unprepare_transfer_hardware() which is documented as "This may sleep". As in the prepare_transfer_hardware() call below, we should release the queue_lock spinlock before making the call. Rework the logic a bit to hold queue_lock to protect the 'busy' flag, then release it to call unprepare_transfer_hardware(). Signed-off-by: Bryan Freed Reviewed-by: Doug Anderson Signed-off-by: Doug Anderson Acked-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/spi/spi.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index f996c600eb8c..5b96250b0628 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -543,17 +543,16 @@ static void spi_pump_messages(struct kthread_work *work) /* Lock queue and check for queue work */ spin_lock_irqsave(&master->queue_lock, flags); if (list_empty(&master->queue) || !master->running) { - if (master->busy && master->unprepare_transfer_hardware) { - ret = master->unprepare_transfer_hardware(master); - if (ret) { - spin_unlock_irqrestore(&master->queue_lock, flags); - dev_err(&master->dev, - "failed to unprepare transfer hardware\n"); - return; - } + if (!master->busy) { + spin_unlock_irqrestore(&master->queue_lock, flags); + return; } master->busy = false; spin_unlock_irqrestore(&master->queue_lock, flags); + if (master->unprepare_transfer_hardware && + master->unprepare_transfer_hardware(master)) + dev_err(&master->dev, + "failed to unprepare transfer hardware\n"); return; } -- cgit v1.2.3-55-g7522 From 1ad849aee5f53353ed88d9cd3d68a51b03a7d44f Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Wed, 13 Mar 2013 14:57:43 +0100 Subject: spi/mpc512x-psc: optionally keep PSC SS asserted across xfer segmensts Some SPI slave devices require asserted chip select signal across multiple transfer segments of an SPI message. Currently the driver always de-asserts the internal SS signal for every single transfer segment of the message and ignores the 'cs_change' flag of the transfer description. Disable the internal chip select (SS) only if this is needed and indicated by the 'cs_change' flag. Without this change, each partial transfer of a surrounding multi-part SPI transaction might erroneously change the SS signal, which might prevent slaves from answering the request that was sent in a previous transfer segment because the transaction could be considered aborted (SS was de-asserted before reading the response). Reported-by: Gerhard Sittig Signed-off-by: Anatolij Gustschin Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/spi/spi-mpc512x-psc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 89480b281d74..3e490ee7f275 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -164,7 +164,7 @@ static int mpc512x_psc_spi_transfer_rxtx(struct spi_device *spi, for (i = count; i > 0; i--) { data = tx_buf ? *tx_buf++ : 0; - if (len == EOFBYTE) + if (len == EOFBYTE && t->cs_change) setbits32(&fifo->txcmd, MPC512x_PSC_FIFO_EOF); out_8(&fifo->txdata_8, data); len--; -- cgit v1.2.3-55-g7522 From 2cfda637e29ce9e3df31b59f64516b2e571cc985 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 1 Apr 2013 11:48:59 -0600 Subject: EISA/PCI: Fix bus res reference Matthew found that 3.8.3 is having problems with an old (ancient) PCI-to-EISA bridge, the Intel 82375. It worked with the 3.2 kernel. He identified the 82375, but doesn't assign the struct resource *res pointer inside the struct eisa_root_device, and panics. pci_eisa_init() was using bus->resource[] directly instead of pci_bus_resource_n(). The bus->resource[] array is a PCI-internal implementation detail, and after commit 45ca9e97 (PCI: add helpers for building PCI bus resource lists) and commit 0efd5aab (PCI: add struct pci_host_bridge_window with CPU/bus address offset), bus->resource[] is not used for PCI root buses any more. The 82375 is a subtractive-decode PCI device, so handle it the same way we handle PCI-PCI bridges in subtractive-decode mode in pci_read_bridge_bases(). [bhelgaas: changelog] Reported-by: Matthew Whitehead Tested-by: Matthew Whitehead Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org # v3.3+--- drivers/eisa/pci_eisa.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/eisa/pci_eisa.c b/drivers/eisa/pci_eisa.c index cdae207028a7..ef5c3ec87432 100644 --- a/drivers/eisa/pci_eisa.c +++ b/drivers/eisa/pci_eisa.c @@ -22,7 +22,8 @@ static struct eisa_root_device pci_eisa_root; static int __init pci_eisa_init(struct pci_dev *pdev, const struct pci_device_id *ent) { - int rc; + int rc, i; + struct resource *res, *bus_res = NULL; if ((rc = pci_enable_device (pdev))) { printk (KERN_ERR "pci_eisa : Could not enable device %s\n", @@ -30,9 +31,30 @@ static int __init pci_eisa_init(struct pci_dev *pdev, return rc; } + /* + * The Intel 82375 PCI-EISA bridge is a subtractive-decode PCI + * device, so the resources available on EISA are the same as those + * available on the 82375 bus. This works the same as a PCI-PCI + * bridge in subtractive-decode mode (see pci_read_bridge_bases()). + * We assume other PCI-EISA bridges are similar. + * + * eisa_root_register() can only deal with a single io port resource, + * so we use the first valid io port resource. + */ + pci_bus_for_each_resource(pdev->bus, res, i) + if (res && (res->flags & IORESOURCE_IO)) { + bus_res = res; + break; + } + + if (!bus_res) { + dev_err(&pdev->dev, "No resources available\n"); + return -1; + } + pci_eisa_root.dev = &pdev->dev; - pci_eisa_root.res = pdev->bus->resource[0]; - pci_eisa_root.bus_base_addr = pdev->bus->resource[0]->start; + pci_eisa_root.res = bus_res; + pci_eisa_root.bus_base_addr = bus_res->start; pci_eisa_root.slots = EISA_MAX_SLOTS; pci_eisa_root.dma_mask = pdev->dma_mask; dev_set_drvdata(pci_eisa_root.dev, &pci_eisa_root); -- cgit v1.2.3-55-g7522 From c5fb301ae83bec6892e54984e6ec765c47df8e10 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 27 Mar 2013 21:28:05 -0700 Subject: EISA/PCI: Init EISA early, before PNP Matthew reported kernels fail the pci_eisa probe and are later successful with the virtual_eisa_root_init force probe without slot0. The reason for that is: PNP probing is before pci_eisa_init gets called as pci_eisa_init is called via pci_driver. pnp 00:0f has 0xc80 - 0xc84 reserved. [ 9.700409] pnp 00:0f: [io 0x0c80-0x0c84] so eisa_probe will fail from pci_eisa_init ==>eisa_root_register ==>eisa_probe path. as force_probe is not set in pci_eisa_root, it will bail early when slot0 is not probed and initialized. Try to use subsys_initcall_sync instead, and will keep following sequence: pci_subsys_init pci_eisa_init_early pnpacpi_init/isapnp_init After this patch EISA can be initialized properly, and PNP overlapping resource will not be reserved. [ 10.104434] system 00:0f: [io 0x0c80-0x0c84] could not be reserved Reported-by: Matthew Whitehead Tested-by: Matthew Whitehead Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas Cc: stable@vger.kernel.org--- drivers/eisa/pci_eisa.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/eisa/pci_eisa.c b/drivers/eisa/pci_eisa.c index ef5c3ec87432..6c3fca97d346 100644 --- a/drivers/eisa/pci_eisa.c +++ b/drivers/eisa/pci_eisa.c @@ -19,8 +19,7 @@ /* There is only *one* pci_eisa device per machine, right ? */ static struct eisa_root_device pci_eisa_root; -static int __init pci_eisa_init(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __init pci_eisa_init(struct pci_dev *pdev) { int rc, i; struct resource *res, *bus_res = NULL; @@ -67,22 +66,26 @@ static int __init pci_eisa_init(struct pci_dev *pdev, return 0; } -static struct pci_device_id pci_eisa_pci_tbl[] = { - { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, - PCI_CLASS_BRIDGE_EISA << 8, 0xffff00, 0 }, - { 0, } -}; +/* + * We have to call pci_eisa_init_early() before pnpacpi_init()/isapnp_init(). + * Otherwise pnp resource will get enabled early and could prevent eisa + * to be initialized. + * Also need to make sure pci_eisa_init_early() is called after + * x86/pci_subsys_init(). + * So need to use subsys_initcall_sync with it. + */ +static int __init pci_eisa_init_early(void) +{ + struct pci_dev *dev = NULL; + int ret; -static struct pci_driver __refdata pci_eisa_driver = { - .name = "pci_eisa", - .id_table = pci_eisa_pci_tbl, - .probe = pci_eisa_init, -}; + for_each_pci_dev(dev) + if ((dev->class >> 8) == PCI_CLASS_BRIDGE_EISA) { + ret = pci_eisa_init(dev); + if (ret) + return ret; + } -static int __init pci_eisa_init_module (void) -{ - return pci_register_driver (&pci_eisa_driver); + return 0; } - -device_initcall(pci_eisa_init_module); -MODULE_DEVICE_TABLE(pci, pci_eisa_pci_tbl); +subsys_initcall_sync(pci_eisa_init_early); -- cgit v1.2.3-55-g7522 From 0f1bc12e9eddaba2baf52d020d37670dbabe3702 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Thu, 14 Mar 2013 16:27:05 +0100 Subject: clk: tegra: Allow PLLE training to succeed Under some circumstances the PLLE needs to be retrained, in which case access to the PMC registers is required. Fix this by passing a pointer to the PMC registers instead of NULL when registering the PLLE clock. Signed-off-by: Thierry Reding Acked-By: Peter De Schrijver Signed-off-by: Mike Turquette --- drivers/clk/tegra/clk-tegra20.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 1e2de7305362..f873dcefe0de 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -703,7 +703,7 @@ static void tegra20_pll_init(void) clks[pll_a_out0] = clk; /* PLLE */ - clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, NULL, + clk = tegra_clk_register_plle("pll_e", "pll_ref", clk_base, pmc_base, 0, 100000000, &pll_e_params, 0, pll_e_freq_table, NULL); clk_register_clkdev(clk, "pll_e", NULL); -- cgit v1.2.3-55-g7522 From 901ceba4e81e9dd6b4a3c4c37ee22000a6c5c65f Mon Sep 17 00:00:00 2001 From: Stone Piao Date: Fri, 29 Mar 2013 19:21:21 -0700 Subject: mwifiex: limit channel number not to overflow memory Limit the channel number in scan request, or the driver scan config structure memory will be overflowed. Cc: # 3.5+ Signed-off-by: Stone Piao Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index a44023a7bd57..8aaf56ade4d9 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1892,7 +1892,8 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, } } - for (i = 0; i < request->n_channels; i++) { + for (i = 0; i < min_t(u32, request->n_channels, + MWIFIEX_USER_SCAN_CHAN_MAX); i++) { chan = request->channels[i]; priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; priv->user_scan_cfg->chan_list[i].radio_type = chan->band; -- cgit v1.2.3-55-g7522 From 121cdf08cc854bda4892d2c755e32ef424772ac2 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 26 Mar 2013 17:25:55 -0400 Subject: nouveau: Attempt to use platform-provided ROM image Some platforms only provide their PCI ROM via a platform-specific interface. Fall back to attempting that if all other sources fail. Signed-off-by: Matthew Garrett Signed-off-by: Bjorn Helgaas --- drivers/gpu/drm/nouveau/core/subdev/bios/base.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index e816f06637a7..0e2c1a4f1659 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c @@ -248,6 +248,22 @@ nouveau_bios_shadow_pci(struct nouveau_bios *bios) } } +static void +nouveau_bios_shadow_platform(struct nouveau_bios *bios) +{ + struct pci_dev *pdev = nv_device(bios)->pdev; + size_t size; + + void __iomem *rom = pci_platform_rom(pdev, &size); + if (rom && size) { + bios->data = kmalloc(size, GFP_KERNEL); + if (bios->data) { + memcpy_fromio(bios->data, rom, size); + bios->size = size; + } + } +} + static int nouveau_bios_score(struct nouveau_bios *bios, const bool writeable) { @@ -288,6 +304,7 @@ nouveau_bios_shadow(struct nouveau_bios *bios) { "PROM", nouveau_bios_shadow_prom, false, 0, 0, NULL }, { "ACPI", nouveau_bios_shadow_acpi, true, 0, 0, NULL }, { "PCIROM", nouveau_bios_shadow_pci, true, 0, 0, NULL }, + { "PLATFORM", nouveau_bios_shadow_platform, true, 0, 0, NULL }, {} }; struct methods *mthd, *best; -- cgit v1.2.3-55-g7522 From 06a08570085b3b20c45f45dc66dc46851ecbcb5b Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 26 Mar 2013 17:25:56 -0400 Subject: radeon: Attempt to use platform-provided ROM image Some platforms only provide their PCI ROM via a platform-specific interface. Fall back to attempting that if all other sources fail. Signed-off-by: Matthew Garrett Signed-off-by: Bjorn Helgaas --- drivers/gpu/drm/radeon/radeon_bios.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index b8015913d382..fa3c56fba294 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c @@ -99,6 +99,29 @@ static bool radeon_read_bios(struct radeon_device *rdev) return true; } +static bool radeon_read_platform_bios(struct radeon_device *rdev) +{ + uint8_t __iomem *bios; + size_t size; + + rdev->bios = NULL; + + bios = pci_platform_rom(rdev->pdev, &size); + if (!bios) { + return false; + } + + if (size == 0 || bios[0] != 0x55 || bios[1] != 0xaa) { + return false; + } + rdev->bios = kmemdup(bios, size, GFP_KERNEL); + if (rdev->bios == NULL) { + return false; + } + + return true; +} + #ifdef CONFIG_ACPI /* ATRM is used to get the BIOS on the discrete cards in * dual-gpu systems. @@ -620,6 +643,9 @@ bool radeon_get_bios(struct radeon_device *rdev) if (r == false) { r = radeon_read_disabled_bios(rdev); } + if (r == false) { + r = radeon_read_platform_bios(rdev); + } if (r == false || rdev->bios == NULL) { DRM_ERROR("Unable to locate a BIOS ROM\n"); rdev->bios = NULL; -- cgit v1.2.3-55-g7522 From c1681bf8a7b1b98edee8b862a42c19c4e53205fd Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Mon, 1 Apr 2013 09:47:56 -0700 Subject: loop: prevent bdev freeing while device in use struct block_device lifecycle is defined by its inode (see fs/block_dev.c) - block_device allocated first time we access /dev/loopXX and deallocated on bdev_destroy_inode. When we create the device "losetup /dev/loopXX afile" we want that block_device stay alive until we destroy the loop device with "losetup -d". But because we do not hold /dev/loopXX inode its counter goes 0, and inode/bdev can be destroyed at any moment. Usually it happens at memory pressure or when user drops inode cache (like in the test below). When later in loop_clr_fd() we want to use bdev we have use-after-free error with following stack: BUG: unable to handle kernel NULL pointer dereference at 0000000000000280 bd_set_size+0x10/0xa0 loop_clr_fd+0x1f8/0x420 [loop] lo_ioctl+0x200/0x7e0 [loop] lo_compat_ioctl+0x47/0xe0 [loop] compat_blkdev_ioctl+0x341/0x1290 do_filp_open+0x42/0xa0 compat_sys_ioctl+0xc1/0xf20 do_sys_open+0x16e/0x1d0 sysenter_dispatch+0x7/0x1a To prevent use-after-free we need to grab the device in loop_set_fd() and put it later in loop_clr_fd(). The issue is reprodusible on current Linus head and v3.3. Here is the test: dd if=/dev/zero of=loop.file bs=1M count=1 while [ true ]; do losetup /dev/loop0 loop.file echo 2 > /proc/sys/vm/drop_caches losetup -d /dev/loop0 done [ Doing bdgrab/bput in loop_set_fd/loop_clr_fd is safe, because every time we call loop_set_fd() we check that loop_device->lo_state is Lo_unbound and set it to Lo_bound If somebody will try to set_fd again it will get EBUSY. And if we try to loop_clr_fd() on unbound loop device we'll get ENXIO. loop_set_fd/loop_clr_fd (and any other loop ioctl) is called under loop_device->lo_ctl_mutex. ] Signed-off-by: Anatol Pomozov Cc: Al Viro Signed-off-by: Linus Torvalds --- drivers/block/loop.c | 9 ++++++++- fs/block_dev.c | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index fe5f6403417f..2c127f9c3f3b 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -922,6 +922,11 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode, lo->lo_flags |= LO_FLAGS_PARTSCAN; if (lo->lo_flags & LO_FLAGS_PARTSCAN) ioctl_by_bdev(bdev, BLKRRPART, 0); + + /* Grab the block_device to prevent its destruction after we + * put /dev/loopXX inode. Later in loop_clr_fd() we bdput(bdev). + */ + bdgrab(bdev); return 0; out_clr: @@ -1031,8 +1036,10 @@ static int loop_clr_fd(struct loop_device *lo) memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); memset(lo->lo_crypt_name, 0, LO_NAME_SIZE); memset(lo->lo_file_name, 0, LO_NAME_SIZE); - if (bdev) + if (bdev) { + bdput(bdev); invalidate_bdev(bdev); + } set_capacity(lo->lo_disk, 0); loop_sysfs_exit(lo); if (bdev) { diff --git a/fs/block_dev.c b/fs/block_dev.c index aea605c98ba6..aae187a7f94a 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -551,6 +551,7 @@ struct block_device *bdgrab(struct block_device *bdev) ihold(bdev->bd_inode); return bdev; } +EXPORT_SYMBOL(bdgrab); long nr_blockdev_pages(void) { -- cgit v1.2.3-55-g7522 From da259465d7526804b21d274281fb4d60b4216c82 Mon Sep 17 00:00:00 2001 From: Rafael J. Wysocki Date: Tue, 2 Apr 2013 01:25:09 +0200 Subject: USB / PM: Don't try to hide PM QoS flags from usb_port_device_release() Remove the call to dev_pm_qos_hide_flags(), added by commit 6e30d7cb "usb: Add driver/usb/core/(port.c,hub.h) files", from usb_port_device_release(), because (1) it is completely unnecessary (the flags have been removed already by the PM core during the unregistration of the device object) and (2) it triggers a NULL pointer dereference in sysfs_find_dirent() (dev->kobj.sd is NULL at this point). Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman --- drivers/usb/core/port.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index 797f9d514732..65d4e55552c6 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -67,7 +67,6 @@ static void usb_port_device_release(struct device *dev) { struct usb_port *port_dev = to_usb_port(dev); - dev_pm_qos_hide_flags(dev); kfree(port_dev); } -- cgit v1.2.3-55-g7522 From 0f703069296664eb7c649c837cc8bb936c3ef07f Mon Sep 17 00:00:00 2001 From: Rafael J. Wysocki Date: Tue, 2 Apr 2013 01:25:24 +0200 Subject: PM / QoS: Avoid possible deadlock related to sysfs access Commit b81ea1b (PM / QoS: Fix concurrency issues and memory leaks in device PM QoS) put calls to pm_qos_sysfs_add_latency(), pm_qos_sysfs_add_flags(), pm_qos_sysfs_remove_latency(), and pm_qos_sysfs_remove_flags() under dev_pm_qos_mtx, which was a mistake, because it may lead to deadlocks in some situations. For example, if pm_qos_remote_wakeup_store() is run in parallel with dev_pm_qos_constraints_destroy(), they may deadlock in the following way: ====================================================== [ INFO: possible circular locking dependency detected ] 3.9.0-rc4-next-20130328-sasha-00014-g91a3267 #319 Tainted: G W ------------------------------------------------------- trinity-child6/12371 is trying to acquire lock: (s_active#54){++++.+}, at: [] sysfs_addrm_finish+0x31/0x60 but task is already holding lock: (dev_pm_qos_mtx){+.+.+.}, at: [] dev_pm_qos_constraints_destroy+0x23/0x250 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (dev_pm_qos_mtx){+.+.+.}: [] lock_acquire+0x1aa/0x240 [] __mutex_lock_common+0x59/0x5e0 [] mutex_lock_nested+0x3f/0x50 [] dev_pm_qos_update_flags+0x3f/0xc0 [] pm_qos_remote_wakeup_store+0x3f/0x70 [] dev_attr_store+0x13/0x20 [] sysfs_write_file+0xfa/0x150 [] __kernel_write+0x81/0x150 [] write_pipe_buf+0x4d/0x80 [] splice_from_pipe_feed+0x7c/0x120 [] __splice_from_pipe+0x45/0x80 [] splice_from_pipe+0x4c/0x70 [] default_file_splice_write+0x18/0x30 [] do_splice_from+0x83/0xb0 [] direct_splice_actor+0x1e/0x20 [] splice_direct_to_actor+0xe7/0x200 [] do_splice_direct+0x4c/0x70 [] do_sendfile+0x169/0x300 [] SyS_sendfile64+0x64/0xb0 [] tracesys+0xe1/0xe6 -> #0 (s_active#54){++++.+}: [] __lock_acquire+0x15bf/0x1e50 [] lock_acquire+0x1aa/0x240 [] sysfs_deactivate+0x122/0x1a0 [] sysfs_addrm_finish+0x31/0x60 [] sysfs_hash_and_remove+0x7f/0xb0 [] sysfs_unmerge_group+0x51/0x70 [] pm_qos_sysfs_remove_flags+0x14/0x20 [] __dev_pm_qos_hide_flags+0x30/0x70 [] dev_pm_qos_constraints_destroy+0x35/0x250 [] dpm_sysfs_remove+0x11/0x50 [] device_del+0x3f/0x1b0 [] device_unregister+0x48/0x60 [] usb_hub_remove_port_device+0x1c/0x20 [] hub_disconnect+0xdd/0x160 [] usb_unbind_interface+0x67/0x170 [] __device_release_driver+0x87/0xe0 [] device_release_driver+0x29/0x40 [] bus_remove_device+0x148/0x160 [] device_del+0x14f/0x1b0 [] usb_disable_device+0xf9/0x280 [] usb_set_configuration+0x268/0x840 [] usb_remove_store+0x4c/0x80 [] dev_attr_store+0x13/0x20 [] sysfs_write_file+0xfa/0x150 [] do_loop_readv_writev+0x4d/0x90 [] do_readv_writev+0xf9/0x1e0 [] vfs_writev+0x3a/0x60 [] SyS_writev+0x50/0xd0 [] tracesys+0xe1/0xe6 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(dev_pm_qos_mtx); lock(s_active#54); lock(dev_pm_qos_mtx); lock(s_active#54); *** DEADLOCK *** To avoid that, remove the calls to functions mentioned above from under dev_pm_qos_mtx and introduce a separate lock to prevent races between functions that add or remove device PM QoS sysfs attributes from happening. Reported-by: Sasha Levin Signed-off-by: Rafael J. Wysocki --- drivers/base/power/qos.c | 60 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 5f74587ef258..71671c42ef45 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -46,6 +46,7 @@ #include "power.h" static DEFINE_MUTEX(dev_pm_qos_mtx); +static DEFINE_MUTEX(dev_pm_qos_sysfs_mtx); static BLOCKING_NOTIFIER_HEAD(dev_pm_notifiers); @@ -216,12 +217,17 @@ void dev_pm_qos_constraints_destroy(struct device *dev) struct pm_qos_constraints *c; struct pm_qos_flags *f; - mutex_lock(&dev_pm_qos_mtx); + mutex_lock(&dev_pm_qos_sysfs_mtx); /* * If the device's PM QoS resume latency limit or PM QoS flags have been * exposed to user space, they have to be hidden at this point. */ + pm_qos_sysfs_remove_latency(dev); + pm_qos_sysfs_remove_flags(dev); + + mutex_lock(&dev_pm_qos_mtx); + __dev_pm_qos_hide_latency_limit(dev); __dev_pm_qos_hide_flags(dev); @@ -254,6 +260,8 @@ void dev_pm_qos_constraints_destroy(struct device *dev) out: mutex_unlock(&dev_pm_qos_mtx); + + mutex_unlock(&dev_pm_qos_sysfs_mtx); } /** @@ -558,6 +566,14 @@ static void __dev_pm_qos_drop_user_request(struct device *dev, kfree(req); } +static void dev_pm_qos_drop_user_request(struct device *dev, + enum dev_pm_qos_req_type type) +{ + mutex_lock(&dev_pm_qos_mtx); + __dev_pm_qos_drop_user_request(dev, type); + mutex_unlock(&dev_pm_qos_mtx); +} + /** * dev_pm_qos_expose_latency_limit - Expose PM QoS latency limit to user space. * @dev: Device whose PM QoS latency limit is to be exposed to user space. @@ -581,6 +597,8 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) return ret; } + mutex_lock(&dev_pm_qos_sysfs_mtx); + mutex_lock(&dev_pm_qos_mtx); if (IS_ERR_OR_NULL(dev->power.qos)) @@ -591,26 +609,27 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) if (ret < 0) { __dev_pm_qos_remove_request(req); kfree(req); + mutex_unlock(&dev_pm_qos_mtx); goto out; } - dev->power.qos->latency_req = req; + + mutex_unlock(&dev_pm_qos_mtx); + ret = pm_qos_sysfs_add_latency(dev); if (ret) - __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); + dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); out: - mutex_unlock(&dev_pm_qos_mtx); + mutex_unlock(&dev_pm_qos_sysfs_mtx); return ret; } EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit); static void __dev_pm_qos_hide_latency_limit(struct device *dev) { - if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->latency_req) { - pm_qos_sysfs_remove_latency(dev); + if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->latency_req) __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); - } } /** @@ -619,9 +638,15 @@ static void __dev_pm_qos_hide_latency_limit(struct device *dev) */ void dev_pm_qos_hide_latency_limit(struct device *dev) { + mutex_lock(&dev_pm_qos_sysfs_mtx); + + pm_qos_sysfs_remove_latency(dev); + mutex_lock(&dev_pm_qos_mtx); __dev_pm_qos_hide_latency_limit(dev); mutex_unlock(&dev_pm_qos_mtx); + + mutex_unlock(&dev_pm_qos_sysfs_mtx); } EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit); @@ -649,6 +674,8 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val) } pm_runtime_get_sync(dev); + mutex_lock(&dev_pm_qos_sysfs_mtx); + mutex_lock(&dev_pm_qos_mtx); if (IS_ERR_OR_NULL(dev->power.qos)) @@ -659,16 +686,19 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val) if (ret < 0) { __dev_pm_qos_remove_request(req); kfree(req); + mutex_unlock(&dev_pm_qos_mtx); goto out; } - dev->power.qos->flags_req = req; + + mutex_unlock(&dev_pm_qos_mtx); + ret = pm_qos_sysfs_add_flags(dev); if (ret) - __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); + dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); out: - mutex_unlock(&dev_pm_qos_mtx); + mutex_unlock(&dev_pm_qos_sysfs_mtx); pm_runtime_put(dev); return ret; } @@ -676,10 +706,8 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags); static void __dev_pm_qos_hide_flags(struct device *dev) { - if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->flags_req) { - pm_qos_sysfs_remove_flags(dev); + if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->flags_req) __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); - } } /** @@ -689,9 +717,15 @@ static void __dev_pm_qos_hide_flags(struct device *dev) void dev_pm_qos_hide_flags(struct device *dev) { pm_runtime_get_sync(dev); + mutex_lock(&dev_pm_qos_sysfs_mtx); + + pm_qos_sysfs_remove_flags(dev); + mutex_lock(&dev_pm_qos_mtx); __dev_pm_qos_hide_flags(dev); mutex_unlock(&dev_pm_qos_mtx); + + mutex_unlock(&dev_pm_qos_sysfs_mtx); pm_runtime_put(dev); } EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags); -- cgit v1.2.3-55-g7522 From 5faaa035ddc16d3d2e31c0bfc1c4756b6869dbcc Mon Sep 17 00:00:00 2001 From: Rajagopal Venkat Date: Thu, 21 Mar 2013 13:28:25 +0000 Subject: PM / devfreq: Fix compiler warnings for CONFIG_PM_DEVFREQ unset Fix compiler warnings generated when devfreq is not enabled (CONFIG_PM_DEVFREQ is not set). Signed-off-by: Rajagopal Venkat Acked-by: MyungJoo Ham Signed-off-by: Rafael J. Wysocki --- include/linux/devfreq.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index e83ef39b3bea..fe8c4476f7e4 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -213,7 +213,7 @@ struct devfreq_simple_ondemand_data { #endif #else /* !CONFIG_PM_DEVFREQ */ -static struct devfreq *devfreq_add_device(struct device *dev, +static inline struct devfreq *devfreq_add_device(struct device *dev, struct devfreq_dev_profile *profile, const char *governor_name, void *data) @@ -221,34 +221,34 @@ static struct devfreq *devfreq_add_device(struct device *dev, return NULL; } -static int devfreq_remove_device(struct devfreq *devfreq) +static inline int devfreq_remove_device(struct devfreq *devfreq) { return 0; } -static int devfreq_suspend_device(struct devfreq *devfreq) +static inline int devfreq_suspend_device(struct devfreq *devfreq) { return 0; } -static int devfreq_resume_device(struct devfreq *devfreq) +static inline int devfreq_resume_device(struct devfreq *devfreq) { return 0; } -static struct opp *devfreq_recommended_opp(struct device *dev, +static inline struct opp *devfreq_recommended_opp(struct device *dev, unsigned long *freq, u32 flags) { - return -EINVAL; + return ERR_PTR(-EINVAL); } -static int devfreq_register_opp_notifier(struct device *dev, +static inline int devfreq_register_opp_notifier(struct device *dev, struct devfreq *devfreq) { return -EINVAL; } -static int devfreq_unregister_opp_notifier(struct device *dev, +static inline int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq) { return -EINVAL; -- cgit v1.2.3-55-g7522 From f5c3ef21db149ba573a3f079df287f3d8b05ee13 Mon Sep 17 00:00:00 2001 From: Paolo Pisati Date: Thu, 28 Mar 2013 09:24:29 +0000 Subject: cpufreq: check OF node /cpus presence before dereferencing it Check for the presence of the '/cpus' OF node before dereferencing it blindly: [ 4.181793] Unable to handle kernel NULL pointer dereference at virtual address 0000001c [ 4.181793] pgd = c0004000 [ 4.181823] [0000001c] *pgd=00000000 [ 4.181823] Internal error: Oops: 5 [#1] SMP ARM [ 4.181823] Modules linked in: [ 4.181823] CPU: 1 Tainted: G W (3.8.0-15-generic #25~hbankD) [ 4.181854] PC is at of_get_next_child+0x64/0x70 [ 4.181854] LR is at of_get_next_child+0x24/0x70 [ 4.181854] pc : [] lr : [] psr: 60000113 [ 4.181854] sp : ed891ec0 ip : ed891ec0 fp : ed891ed4 [ 4.181884] r10: c04dafd0 r9 : c098690c r8 : c0936208 [ 4.181884] r7 : ed890000 r6 : c0a63d00 r5 : 00000000 r4 : 00000000 [ 4.181884] r3 : 00000000 r2 : 00000000 r1 : 00000000 r0 : c0b2acc8 [ 4.181884] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel [ 4.181884] Control: 10c5387d Table: adcb804a DAC: 00000015 [ 4.181915] Process swapper/0 (pid: 1, stack limit = 0xed890238) [ 4.181915] Stack: (0xed891ec0 to 0xed892000) [ 4.181915] 1ec0: c09b7b70 00000007 ed891efc ed891ed8 c04daff4 c04fd9c0 00000000 c09b7b70 [ 4.181915] 1ee0: 00000007 c0a63d00 ed890000 c0936208 ed891f54 ed891f00 c00088e0 c04dafdc [ 4.181945] 1f00: ed891f54 ed891f10 c006e940 00000000 00000000 00000007 00000007 c08a4914 [ 4.181945] 1f20: 00000000 c07dbd30 c0a63d00 c09b7b70 00000007 c0a63d00 000000bc c0936208 [ 4.181945] 1f40: c098690c c0986914 ed891f94 ed891f58 c0936a40 c00087bc 00000007 00000007 [ 4.181976] 1f60: c0936208 be8bda20 b6eea010 c0a63d00 c064547c 00000000 00000000 00000000 [ 4.181976] 1f80: 00000000 00000000 ed891fac ed891f98 c0645498 c09368c8 00000000 00000000 [ 4.181976] 1fa0: 00000000 ed891fb0 c0014658 c0645488 00000000 00000000 00000000 00000000 [ 4.182006] 1fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 4.182006] 1fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 [ 4.182037] [] (of_get_next_child+0x64/0x70) from [] (cpu0_cpufreq_driver_init+0x24/0x284) [ 4.182067] [] (cpu0_cpufreq_driver_init+0x24/0x284) from [] (do_one_initcall+0x130/0x1b0) [ 4.182067] [] (do_one_initcall+0x130/0x1b0) from [] (kernel_init_freeable+0x184/0x24c) [ 4.182098] [] (kernel_init_freeable+0x184/0x24c) from [] (kernel_init+0x1c/0xf4) [ 4.182128] [] (kernel_init+0x1c/0xf4) from [] (ret_from_fork+0x14/0x20) [ 4.182128] Code: f57ff04f e320f004 e89da830 e89da830 (e595001c) [ 4.182128] ---[ end trace 634903a22e8609cb ]--- [ 4.182189] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b [ 4.182189] [ 4.642395] CPU0: stopping [rjw: Changelog] Signed-off-by: Paolo Pisati Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq-cpu0.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c index 4e5b7fb8927c..37d23a0f8c56 100644 --- a/drivers/cpufreq/cpufreq-cpu0.c +++ b/drivers/cpufreq/cpufreq-cpu0.c @@ -178,10 +178,16 @@ static struct cpufreq_driver cpu0_cpufreq_driver = { static int cpu0_cpufreq_probe(struct platform_device *pdev) { - struct device_node *np; + struct device_node *np, *parent; int ret; - for_each_child_of_node(of_find_node_by_path("/cpus"), np) { + parent = of_find_node_by_path("/cpus"); + if (!parent) { + pr_err("failed to find OF /cpus\n"); + return -ENOENT; + } + + for_each_child_of_node(parent, np) { if (of_get_property(np, "operating-points", NULL)) break; } -- cgit v1.2.3-55-g7522 From 29896178cff0cd6e4ee78edc26158cc197a6b504 Mon Sep 17 00:00:00 2001 From: Rafael J. Wysocki Date: Mon, 1 Apr 2013 00:21:08 +0000 Subject: ACPI / SPI: Use parent's ACPI_HANDLE() in acpi_register_spi_devices() The ACPI handle of struct spi_master's dev member should not be set, because this causes that struct spi_master to be associated with the ACPI device node corresponding to its parent as the second "physical_device", which is incorrect (this happens during the registration of struct spi_master). Consequently, acpi_register_spi_devices() should use the ACPI handle of the parent of the struct spi_master it is called for rather than that struct spi_master's ACPI handle (which should be NULL). Make that happen and modify the spi-pxa2xx driver, which currently is the only driver for ACPI-enumerated SPI controller chips, not to set the ACPI handle for the struct spi_master it creates. Signed-off-by: Rafael J. Wysocki Acked-by: Mika Westerberg Acked-by: Mark Brown --- drivers/spi/spi-pxa2xx.c | 1 - drivers/spi/spi.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 90b27a3508a6..810413883c79 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1168,7 +1168,6 @@ static int pxa2xx_spi_probe(struct platform_device *pdev) master->dev.parent = &pdev->dev; master->dev.of_node = pdev->dev.of_node; - ACPI_HANDLE_SET(&master->dev, ACPI_HANDLE(&pdev->dev)); /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index f996c600eb8c..5e073d897edb 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -984,7 +984,7 @@ static void acpi_register_spi_devices(struct spi_master *master) acpi_status status; acpi_handle handle; - handle = ACPI_HANDLE(&master->dev); + handle = ACPI_HANDLE(master->dev.parent); if (!handle) return; -- cgit v1.2.3-55-g7522 From ea81531de23cf92085e0601178fae920141caa5d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 21 Mar 2013 12:50:39 +0100 Subject: s390/uaccess: fix page table walk When translating user space addresses to kernel addresses the follow_table() function had two bugs: - PROT_NONE mappings could be read accessed via the kernel mapping. That is e.g. putting a filename into a user page, then protecting the page with PROT_NONE and afterwards issuing the "open" syscall with a pointer to the filename would incorrectly succeed. - when walking the page tables it used the pgd/pud/pmd/pte primitives which with dynamic page tables give no indication which real level of page tables is being walked (region2, region3, segment or page table). So in case of an exception the translation exception code passed to __handle_fault() is not necessarily correct. This is not really an issue since __handle_fault() doesn't evaluate the code. Only in case of e.g. a SIGBUS this code gets passed to user space. If user space can do something sane with the value is a different question though. To fix these issues don't use any Linux primitives. Only walk the page tables like the hardware would do it, however we leave quite some checks away since we know that we only have full size page tables and each index is within bounds. In theory this should fix all issues... Signed-off-by: Heiko Carstens Reviewed-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pgtable.h | 1 + arch/s390/lib/uaccess_pt.c | 81 +++++++++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 4a2930844d43..1686d8f0f878 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -344,6 +344,7 @@ extern unsigned long MODULES_END; #define _REGION3_ENTRY_CO 0x100 /* change-recording override */ /* Bits in the segment table entry */ +#define _SEGMENT_ENTRY_ORIGIN_LARGE ~0xfffffUL /* large page address */ #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ #define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ #define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index 6771fdd89377..466fb3383960 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c @@ -77,42 +77,69 @@ static size_t copy_in_kernel(size_t count, void __user *to, * >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occured and the address * contains the (negative) exception code. */ -static __always_inline unsigned long follow_table(struct mm_struct *mm, - unsigned long addr, int write) +#ifdef CONFIG_64BIT +static unsigned long follow_table(struct mm_struct *mm, + unsigned long address, int write) { - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *ptep; + unsigned long *table = (unsigned long *)__pa(mm->pgd); + + switch (mm->context.asce_bits & _ASCE_TYPE_MASK) { + case _ASCE_TYPE_REGION1: + table = table + ((address >> 53) & 0x7ff); + if (unlikely(*table & _REGION_ENTRY_INV)) + return -0x39UL; + table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); + case _ASCE_TYPE_REGION2: + table = table + ((address >> 42) & 0x7ff); + if (unlikely(*table & _REGION_ENTRY_INV)) + return -0x3aUL; + table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); + case _ASCE_TYPE_REGION3: + table = table + ((address >> 31) & 0x7ff); + if (unlikely(*table & _REGION_ENTRY_INV)) + return -0x3bUL; + table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); + case _ASCE_TYPE_SEGMENT: + table = table + ((address >> 20) & 0x7ff); + if (unlikely(*table & _SEGMENT_ENTRY_INV)) + return -0x10UL; + if (unlikely(*table & _SEGMENT_ENTRY_LARGE)) { + if (write && (*table & _SEGMENT_ENTRY_RO)) + return -0x04UL; + return (*table & _SEGMENT_ENTRY_ORIGIN_LARGE) + + (address & ~_SEGMENT_ENTRY_ORIGIN_LARGE); + } + table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); + } + table = table + ((address >> 12) & 0xff); + if (unlikely(*table & _PAGE_INVALID)) + return -0x11UL; + if (write && (*table & _PAGE_RO)) + return -0x04UL; + return (*table & PAGE_MASK) + (address & ~PAGE_MASK); +} - pgd = pgd_offset(mm, addr); - if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) - return -0x3aUL; +#else /* CONFIG_64BIT */ - pud = pud_offset(pgd, addr); - if (pud_none(*pud) || unlikely(pud_bad(*pud))) - return -0x3bUL; +static unsigned long follow_table(struct mm_struct *mm, + unsigned long address, int write) +{ + unsigned long *table = (unsigned long *)__pa(mm->pgd); - pmd = pmd_offset(pud, addr); - if (pmd_none(*pmd)) + table = table + ((address >> 20) & 0x7ff); + if (unlikely(*table & _SEGMENT_ENTRY_INV)) return -0x10UL; - if (pmd_large(*pmd)) { - if (write && (pmd_val(*pmd) & _SEGMENT_ENTRY_RO)) - return -0x04UL; - return (pmd_val(*pmd) & HPAGE_MASK) + (addr & ~HPAGE_MASK); - } - if (unlikely(pmd_bad(*pmd))) - return -0x10UL; - - ptep = pte_offset_map(pmd, addr); - if (!pte_present(*ptep)) + table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); + table = table + ((address >> 12) & 0xff); + if (unlikely(*table & _PAGE_INVALID)) return -0x11UL; - if (write && (!pte_write(*ptep) || !pte_dirty(*ptep))) + if (write && (*table & _PAGE_RO)) return -0x04UL; - - return (pte_val(*ptep) & PAGE_MASK) + (addr & ~PAGE_MASK); + return (*table & PAGE_MASK) + (address & ~PAGE_MASK); } +#endif /* CONFIG_64BIT */ + static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr, size_t n, int write_user) { -- cgit v1.2.3-55-g7522 From 765a0cac566c938821ae26efb4aa53b7502ee82c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 23 Mar 2013 10:29:01 +0100 Subject: s390/mm: provide emtpy check_pgt_cache() function All architectures need to provide a check_pgt_cache() function. The s390 one got lost somewhere. So reintroduce it to prevent future compile errors e.g. if Thomas Gleixner's idle loop rework patches get merged. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/pgtable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 1686d8f0f878..4a5443118cfb 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -1532,7 +1532,8 @@ extern int s390_enable_sie(void); /* * No page table caches to initialise */ -#define pgtable_cache_init() do { } while (0) +static inline void pgtable_cache_init(void) { } +static inline void check_pgt_cache(void) { } #include -- cgit v1.2.3-55-g7522 From 2ef5692efad330b67a234e2c49edad38538751e7 Mon Sep 17 00:00:00 2001 From: Mengdong Lin Date: Thu, 28 Mar 2013 05:20:22 -0400 Subject: ALSA: hda - bug fix on return value when getting HDMI ELD info In function snd_hdmi_get_eld(), the variable 'ret' should be initialized to 0. Otherwise it will be returned uninitialized as non-zero after ELD info is got successfully. Thus hdmi_present_sense() will always assume ELD info is invalid by mistake, and /proc file system cannot show the proper ELD info. Signed-off-by: Mengdong Lin Cc: stable@vger.kernel.org Acked-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_eld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 7dd846380a50..d0d7ac1e99d2 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -320,7 +320,7 @@ int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid, unsigned char *buf, int *eld_size) { int i; - int ret; + int ret = 0; int size; /* -- cgit v1.2.3-55-g7522 From 10250911c6f3531e9c2f4f1c6017782bc9bcd6d4 Mon Sep 17 00:00:00 2001 From: Mengdong Lin Date: Thu, 28 Mar 2013 05:21:28 -0400 Subject: ALSA: hda - bug fix on HDMI ELD debug message This patch let ELD debug message show 'pin_eld->monitor_present' which reflects the real pin response to verb GET_PIN_SENSE. 'eld->monitor_present' should not be used here because 'eld' is a temp structure now and so its "monitor_present" is not set. Signed-off-by: Mengdong Lin Acked-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 78e1827d0a95..de8ac5c07fd0 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1196,7 +1196,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) _snd_printd(SND_PR_VERBOSE, "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", - codec->addr, pin_nid, eld->monitor_present, eld->eld_valid); + codec->addr, pin_nid, pin_eld->monitor_present, eld->eld_valid); if (eld->eld_valid) { if (snd_hdmi_get_eld(codec, pin_nid, eld->eld_buffer, -- cgit v1.2.3-55-g7522 From 477fc03f5baaf5906ce04beba7dbcd0e5d1e9b30 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 29 Mar 2013 03:40:00 +0200 Subject: fbmon: use VESA_DMT_VSYNC_HIGH to fix typo VESA_DMT_VSYNC_HIGH should be used instead of VESA_DMT_HSYNC_HIGH, because FB_SYNC_VERT_HIGH_ACT is related to vsync, not to hsync. Signed-off-by: Jingoo Han Acked-by: Steffen Trumtrar Signed-off-by: Tomi Valkeinen --- drivers/video/fbmon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 94ad0f71383c..7f6709991a5c 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c @@ -1400,7 +1400,7 @@ int fb_videomode_from_videomode(const struct videomode *vm, fbmode->vmode = 0; if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH) fbmode->sync |= FB_SYNC_HOR_HIGH_ACT; - if (vm->dmt_flags & VESA_DMT_HSYNC_HIGH) + if (vm->dmt_flags & VESA_DMT_VSYNC_HIGH) fbmode->sync |= FB_SYNC_VERT_HIGH_ACT; if (vm->data_flags & DISPLAY_FLAGS_INTERLACED) fbmode->vmode |= FB_VMODE_INTERLACED; -- cgit v1.2.3-55-g7522 From 090da752cdd6f0786eee68c8dea8db7c8abd3798 Mon Sep 17 00:00:00 2001 From: Wang YanQing Date: Sat, 30 Mar 2013 04:53:00 +0200 Subject: video:uvesafb: Fix dereference NULL pointer code path platform_device_alloc could failed and return NULL, we should check this before call platform_device_put. Signed-off-by: Wang YanQing Signed-off-by: Tomi Valkeinen --- drivers/video/uvesafb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index b75db0186488..d4284458377e 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c @@ -1973,7 +1973,8 @@ static int uvesafb_init(void) err = -ENOMEM; if (err) { - platform_device_put(uvesafb_device); + if (uvesafb_device) + platform_device_put(uvesafb_device); platform_driver_unregister(&uvesafb_driver); cn_del_callback(&uvesafb_cn_id); return err; -- cgit v1.2.3-55-g7522 From 5fe839d997f955e9e62b70d798d3faaa19620383 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 5 Feb 2013 15:36:16 -0200 Subject: ARM: imx: avic: Move avic_saved_mask_reg under CONFIG_PM When building a kernel with CONFIG_PM undefined, the following warning happens: arch/arm/mach-imx/avic.c:57:12: warning: 'avic_saved_mask_reg' defined but not used [-Wunused-variable] Move avic_saved_mask_reg definition inside the '#ifdef CONFIG_PM' block to avoid the warning. Signed-off-by: Fabio Estevam Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/avic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/avic.c b/arch/arm/mach-imx/avic.c index 0eff23ed92b9..49c87e7aa817 100644 --- a/arch/arm/mach-imx/avic.c +++ b/arch/arm/mach-imx/avic.c @@ -54,8 +54,6 @@ void __iomem *avic_base; static struct irq_domain *domain; -static u32 avic_saved_mask_reg[2]; - #ifdef CONFIG_MXC_IRQ_PRIOR static int avic_irq_set_priority(unsigned char irq, unsigned char prio) { @@ -113,6 +111,8 @@ static struct mxc_extra_irq avic_extra_irq = { }; #ifdef CONFIG_PM +static u32 avic_saved_mask_reg[2]; + static void avic_irq_suspend(struct irq_data *d) { struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); -- cgit v1.2.3-55-g7522 From 9591b8204b9fb9dab616e5e525d4d7676c4982f2 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 29 Jan 2013 10:17:35 -0200 Subject: ARM: imx: clk-imx27: Do not register peripheral clock for SSI imx ssi block has two types of clocks: - ipg: bus clock, the clock needed for accessing registers. - per: peripheral clock, the clock needed for generating the bit rate. Currently ssi driver only supports slave mode and thus need only to handle the ipg clock, because the peripheral clock comes from the master codec. Only register the ipg clock and do not register the peripheral clock for ssi Signed-off-by: Fabio Estevam Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx27.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c index 30b3242a7d49..8e3b65719106 100644 --- a/arch/arm/mach-imx/clk-imx27.c +++ b/arch/arm/mach-imx/clk-imx27.c @@ -278,8 +278,6 @@ int __init mx27_clocks_init(unsigned long fref) clk_register_clkdev(clk[scc_ipg_gate], "scc", NULL); clk_register_clkdev(clk[cpu_div], "cpu", NULL); clk_register_clkdev(clk[emi_ahb_gate], "emi_ahb" , NULL); - clk_register_clkdev(clk[ssi1_baud_gate], "bitrate" , "imx-ssi.0"); - clk_register_clkdev(clk[ssi2_baud_gate], "bitrate" , "imx-ssi.1"); mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1); -- cgit v1.2.3-55-g7522 From beb0ff390e208e71668a1389e3db02631a88cff5 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Tue, 2 Apr 2013 12:26:15 +0000 Subject: cpufreq: Correct header guards typo It should be "governor". Signed-off-by: Borislav Petkov Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq_governor.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index 46bde01eee62..cc4bd2f6838a 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h @@ -14,8 +14,8 @@ * published by the Free Software Foundation. */ -#ifndef _CPUFREQ_GOVERNER_H -#define _CPUFREQ_GOVERNER_H +#ifndef _CPUFREQ_GOVERNOR_H +#define _CPUFREQ_GOVERNOR_H #include #include @@ -175,4 +175,4 @@ bool need_load_eval(struct cpu_dbs_common_info *cdbs, unsigned int sampling_rate); int cpufreq_governor_dbs(struct dbs_data *dbs_data, struct cpufreq_policy *policy, unsigned int event); -#endif /* _CPUFREQ_GOVERNER_H */ +#endif /* _CPUFREQ_GOVERNOR_H */ -- cgit v1.2.3-55-g7522 From b34bb1ee71158d5b0f9028fb98afd026202bcfe9 Mon Sep 17 00:00:00 2001 From: Rafael J. Wysocki Date: Mon, 1 Apr 2013 00:25:03 +0000 Subject: ACPI / I2C: Use parent's ACPI_HANDLE() in acpi_i2c_register_devices() The ACPI handle of struct i2c_adapter's dev member should not be set, because this causes that struct i2c_adapter to be associated with the ACPI device node corresponding to its parent as the second "physical_device", which is incorrect (this happens during the registration of struct i2c_adapter). Consequently, acpi_i2c_register_devices() should use the ACPI handle of the parent of the struct i2c_adapter it is called for rather than the struct i2c_adapter's ACPI handle (which should be NULL). Make that happen and modify the i2c-designware-platdrv driver, which currently is the only driver for ACPI-enumerated I2C controller chips, not to set the ACPI handle for the struct i2c_adapter it creates. Signed-off-by: Rafael J. Wysocki Reviewed-by: Aaron Lu Acked-by: Mika Westerberg Acked-by: Wolfram Sang --- drivers/acpi/acpi_i2c.c | 2 +- drivers/i2c/busses/i2c-designware-platdrv.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/acpi/acpi_i2c.c b/drivers/acpi/acpi_i2c.c index 82045e3f5cac..a82c7626aa9b 100644 --- a/drivers/acpi/acpi_i2c.c +++ b/drivers/acpi/acpi_i2c.c @@ -90,7 +90,7 @@ void acpi_i2c_register_devices(struct i2c_adapter *adapter) acpi_handle handle; acpi_status status; - handle = ACPI_HANDLE(&adapter->dev); + handle = ACPI_HANDLE(adapter->dev.parent); if (!handle) return; diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 0ceb6e1b0f65..e3085c487ace 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -182,7 +182,6 @@ static int dw_i2c_probe(struct platform_device *pdev) adap->algo = &i2c_dw_algo; adap->dev.parent = &pdev->dev; adap->dev.of_node = pdev->dev.of_node; - ACPI_HANDLE_SET(&adap->dev, ACPI_HANDLE(&pdev->dev)); r = i2c_add_numbered_adapter(adap); if (r) { -- cgit v1.2.3-55-g7522 From 6240a10dc55a954ce05a86d2f4bc27e473b6352c Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Tue, 2 Apr 2013 01:56:54 +0200 Subject: cpuidle / ACPI: recover percpu ACPI processor cstate Commit ac3ebafa81af76d6 "ACPI / idle: remove usage of the statedata" changed the percpu processor cstate to a unified cstate in ACPI idle. That caused all our NHM boxes to boot hang or panic. 2178751 Task dump for CPU 1: 2178752 swapper/1 R running task 6736 0 1 0x00000000 2178753 ffff8801e8029dc8 ffffffff8101cf96 ffff8801e8029e28 ffffffff813d294b 2178754 0000000000000f99 0000000000000003 00000000003cf654 0000000025c17d03 2178755 ffff8801e8029e38 ffff8801e74fc000 00000002590dc5c4 ffffffff8163cdb0 2178756 Call Trace: 2178757 [] ? acpi_processor_ffh_cstate_enter+0x2d/0x2f 2178758 [] acpi_idle_enter_bm+0x1b1/0x236 2178759 [] ? disable_cpuidle+0x10/0x10 2178760 [] cpuidle_enter+0x12/0x14 2178761 [] cpuidle_wrap_enter+0x2f/0x6d 2178762 [] cpuidle_enter_tk+0x10/0x12 2178763 [] cpuidle_enter_state+0x12/0x3a 2178764 [] cpuidle_idle_call+0xe8/0x161 2178765 [] cpu_idle+0x5e/0xa4 2178766 [] start_secondary+0x1a9/0x1ad 2178767 Task dump for CPU 2: In fact, the ACPI idle is based on the assumption of difference percpu cstate structures that are necessary for the implementation to work cprrectly. A unique acpi_processor_cx is not sifficient by far. This patch is just a quick fix re-introducing the percpu cstates. If someone really wants to unify the ACPI cstates, please make sure that the whole software infrastructure is changed and take hardware as well as many different kinds of BIOS settings into account. [rjw: Changelog] Reported-by: LKP project Reported-by: Xie ChanglongX Tested-by: Yinghai Lu Signed-off-by: Alex Shi Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_idle.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index fc95308e9a11..ee255c60bdac 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -66,7 +66,8 @@ module_param(latency_factor, uint, 0644); static DEFINE_PER_CPU(struct cpuidle_device *, acpi_cpuidle_device); -static struct acpi_processor_cx *acpi_cstate[CPUIDLE_STATE_MAX]; +static DEFINE_PER_CPU(struct acpi_processor_cx * [CPUIDLE_STATE_MAX], + acpi_cstate); static int disabled_by_idle_boot_param(void) { @@ -722,7 +723,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct acpi_processor *pr; - struct acpi_processor_cx *cx = acpi_cstate[index]; + struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); pr = __this_cpu_read(processors); @@ -745,7 +746,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, */ static int acpi_idle_play_dead(struct cpuidle_device *dev, int index) { - struct acpi_processor_cx *cx = acpi_cstate[index]; + struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); ACPI_FLUSH_CPU_CACHE(); @@ -775,7 +776,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct acpi_processor *pr; - struct acpi_processor_cx *cx = acpi_cstate[index]; + struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); pr = __this_cpu_read(processors); @@ -833,7 +834,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { struct acpi_processor *pr; - struct acpi_processor_cx *cx = acpi_cstate[index]; + struct acpi_processor_cx *cx = per_cpu(acpi_cstate[index], dev->cpu); pr = __this_cpu_read(processors); @@ -960,7 +961,7 @@ static int acpi_processor_setup_cpuidle_cx(struct acpi_processor *pr, !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) continue; #endif - acpi_cstate[count] = cx; + per_cpu(acpi_cstate[count], dev->cpu) = cx; count++; if (count == CPUIDLE_STATE_MAX) -- cgit v1.2.3-55-g7522 From 585b9f0bfdbdb4e41993f52f470eef7f093de0a2 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 2 Apr 2013 21:51:27 +0800 Subject: ARM: imx: remove Makefile.boot Since we have converted IMX to multiplatform build, Makefile.boot is not used anyway. Remove it. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Makefile.boot | 35 ----------------------------------- 1 file changed, 35 deletions(-) delete mode 100644 arch/arm/mach-imx/Makefile.boot diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot deleted file mode 100644 index 41ba1bb0437b..000000000000 --- a/arch/arm/mach-imx/Makefile.boot +++ /dev/null @@ -1,35 +0,0 @@ -zreladdr-$(CONFIG_SOC_IMX1) += 0x08008000 -params_phys-$(CONFIG_SOC_IMX1) := 0x08000100 -initrd_phys-$(CONFIG_SOC_IMX1) := 0x08800000 - -zreladdr-$(CONFIG_SOC_IMX21) += 0xC0008000 -params_phys-$(CONFIG_SOC_IMX21) := 0xC0000100 -initrd_phys-$(CONFIG_SOC_IMX21) := 0xC0800000 - -zreladdr-$(CONFIG_SOC_IMX25) += 0x80008000 -params_phys-$(CONFIG_SOC_IMX25) := 0x80000100 -initrd_phys-$(CONFIG_SOC_IMX25) := 0x80800000 - -zreladdr-$(CONFIG_SOC_IMX27) += 0xA0008000 -params_phys-$(CONFIG_SOC_IMX27) := 0xA0000100 -initrd_phys-$(CONFIG_SOC_IMX27) := 0xA0800000 - -zreladdr-$(CONFIG_SOC_IMX31) += 0x80008000 -params_phys-$(CONFIG_SOC_IMX31) := 0x80000100 -initrd_phys-$(CONFIG_SOC_IMX31) := 0x80800000 - -zreladdr-$(CONFIG_SOC_IMX35) += 0x80008000 -params_phys-$(CONFIG_SOC_IMX35) := 0x80000100 -initrd_phys-$(CONFIG_SOC_IMX35) := 0x80800000 - -zreladdr-$(CONFIG_SOC_IMX51) += 0x90008000 -params_phys-$(CONFIG_SOC_IMX51) := 0x90000100 -initrd_phys-$(CONFIG_SOC_IMX51) := 0x90800000 - -zreladdr-$(CONFIG_SOC_IMX53) += 0x70008000 -params_phys-$(CONFIG_SOC_IMX53) := 0x70000100 -initrd_phys-$(CONFIG_SOC_IMX53) := 0x70800000 - -zreladdr-$(CONFIG_SOC_IMX6Q) += 0x10008000 -params_phys-$(CONFIG_SOC_IMX6Q) := 0x10000100 -initrd_phys-$(CONFIG_SOC_IMX6Q) := 0x10800000 -- cgit v1.2.3-55-g7522 From 50dc3ef5365a8109a27084e62f2a17af02a06596 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 2 Apr 2013 22:06:01 +0800 Subject: ARM: imx: remove mx6q.h Those stuff defined in mx6q.h is used nowhere now. Remove the header. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/hardware.h | 1 - arch/arm/mach-imx/mx6q.h | 31 ------------------------------- 2 files changed, 32 deletions(-) delete mode 100644 arch/arm/mach-imx/mx6q.h diff --git a/arch/arm/mach-imx/hardware.h b/arch/arm/mach-imx/hardware.h index 911e9b31b03f..356131f7b591 100644 --- a/arch/arm/mach-imx/hardware.h +++ b/arch/arm/mach-imx/hardware.h @@ -102,7 +102,6 @@ #include "mxc.h" -#include "mx6q.h" #include "mx51.h" #include "mx53.h" #include "mx3x.h" diff --git a/arch/arm/mach-imx/mx6q.h b/arch/arm/mach-imx/mx6q.h deleted file mode 100644 index 19d3f54db5af..000000000000 --- a/arch/arm/mach-imx/mx6q.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2011 Linaro Ltd. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#ifndef __MACH_MX6Q_H__ -#define __MACH_MX6Q_H__ - -#define MX6Q_IO_P2V(x) IMX_IO_P2V(x) -#define MX6Q_IO_ADDRESS(x) IOMEM(MX6Q_IO_P2V(x)) - -/* - * The following are the blocks that need to be statically mapped. - * For other blocks, the base address really should be retrieved from - * device tree. - */ -#define MX6Q_SCU_BASE_ADDR 0x00a00000 -#define MX6Q_SCU_SIZE 0x1000 -#define MX6Q_CCM_BASE_ADDR 0x020c4000 -#define MX6Q_CCM_SIZE 0x4000 -#define MX6Q_ANATOP_BASE_ADDR 0x020c8000 -#define MX6Q_ANATOP_SIZE 0x1000 - -#endif /* __MACH_MX6Q_H__ */ -- cgit v1.2.3-55-g7522 From fcd99434fb5c137274d2e15dd2a6a7455f0f29ff Mon Sep 17 00:00:00 2001 From: Veaceslav Falico Date: Tue, 2 Apr 2013 05:15:16 +0000 Subject: bonding: get netdev_rx_handler_unregister out of locks Now that netdev_rx_handler_unregister contains synchronize_net(), we need to call it outside of bond->lock, cause it might sleep. Also, remove the already unneded synchronize_net(). Signed-off-by: Veaceslav Falico Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6bbd90e1123c..a51241b2e621 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1976,12 +1976,11 @@ static int __bond_release_one(struct net_device *bond_dev, return -EINVAL; } + write_unlock_bh(&bond->lock); /* unregister rx_handler early so bond_handle_frame wouldn't be called * for this slave anymore. */ netdev_rx_handler_unregister(slave_dev); - write_unlock_bh(&bond->lock); - synchronize_net(); write_lock_bh(&bond->lock); if (!all && !bond->params.fail_over_mac) { -- cgit v1.2.3-55-g7522 From bab6a9eac05360db25c81b0090f6b1195dd986cc Mon Sep 17 00:00:00 2001 From: Yan Burman Date: Tue, 2 Apr 2013 16:49:45 +0300 Subject: net/mlx4_en: Fix setting initial MAC address Commit 6bbb6d9 "net/mlx4_en: Optimize Rx fast path filter checks" introduced a regression under which the MAC address read from the card was not converted correctly (the most significant byte was not handled), fix that. Reviewed-by: Or Gerlitz Signed-off-by: Yan Burman Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index f278b10ef714..30d78f806dc3 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -411,8 +411,8 @@ static int mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) static void mlx4_en_u64_to_mac(unsigned char dst_mac[ETH_ALEN + 2], u64 src_mac) { - unsigned int i; - for (i = ETH_ALEN - 1; i; --i) { + int i; + for (i = ETH_ALEN - 1; i >= 0; --i) { dst_mac[i] = src_mac & 0xff; src_mac >>= 8; } -- cgit v1.2.3-55-g7522 From 2dc958fa2fe6987e7ab106bd97029a09a82fcd8d Mon Sep 17 00:00:00 2001 From: Stanislav Kinsbursky Date: Mon, 1 Apr 2013 11:40:51 +0400 Subject: ipc: set msg back to -EAGAIN if copy wasn't performed Make sure that msg pointer is set back to error value in case of MSG_COPY flag is set and desired message to copy wasn't found. This garantees that msg is either a error pointer or a copy address. Otherwise the last message in queue will be freed without unlinking from the queue (which leads to memory corruption) and the dummy allocated copy won't be released. Signed-off-by: Stanislav Kinsbursky Signed-off-by: Linus Torvalds --- ipc/msg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ipc/msg.c b/ipc/msg.c index 31cd1bf6af27..fede1d06ef30 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -872,6 +872,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, goto out_unlock; break; } + msg = ERR_PTR(-EAGAIN); } else break; msg_counter++; -- cgit v1.2.3-55-g7522 From f0f6ee1f70c4eaab9d52cf7d255df4bd89f8d1c2 Mon Sep 17 00:00:00 2001 From: Vasily Averin Date: Mon, 1 Apr 2013 03:01:32 +0000 Subject: cbq: incorrect processing of high limits currently cbq works incorrectly for limits > 10% real link bandwidth, and practically does not work for limits > 50% real link bandwidth. Below are results of experiments taken on 1 Gbit link In shaper | Actual Result -----------+--------------- 100M | 108 Mbps 200M | 244 Mbps 300M | 412 Mbps 500M | 893 Mbps This happen because of q->now changes incorrectly in cbq_dequeue(): when it is called before real end of packet transmitting, L2T is greater than real time delay, q_now gets an extra boost but never compensate it. To fix this problem we prevent change of q->now until its synchronization with real time. Signed-off-by: Vasily Averin Reviewed-by: Alexey Kuznetsov Acked-by: Eric Dumazet Signed-off-by: David S. Miller --- net/sched/sch_cbq.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 13aa47aa2ffb..1bc210ffcba2 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -962,8 +962,11 @@ cbq_dequeue(struct Qdisc *sch) cbq_update(q); if ((incr -= incr2) < 0) incr = 0; + q->now += incr; + } else { + if (now > q->now) + q->now = now; } - q->now += incr; q->now_rt = now; for (;;) { -- cgit v1.2.3-55-g7522 From 25fb6ca4ed9cad72f14f61629b68dc03c0d9713f Mon Sep 17 00:00:00 2001 From: Balakumaran Kannan Date: Tue, 2 Apr 2013 16:15:05 +0530 Subject: net IPv6 : Fix broken IPv6 routing table after loopback down-up IPv6 Routing table becomes broken once we do ifdown, ifup of the loopback(lo) interface. After down-up, routes of other interface's IPv6 addresses through 'lo' are lost. IPv6 addresses assigned to all interfaces are routed through 'lo' for internal communication. Once 'lo' is down, those routing entries are removed from routing table. But those removed entries are not being re-created properly when 'lo' is brought up. So IPv6 addresses of other interfaces becomes unreachable from the same machine. Also this breaks communication with other machines because of NDISC packet processing failure. This patch fixes this issue by reading all interface's IPv6 addresses and adding them to IPv6 routing table while bringing up 'lo'. ==Testing== Before applying the patch: $ route -A inet6 Kernel IPv6 routing table Destination Next Hop Flag Met Ref Use If 2000::20/128 :: U 256 0 0 eth0 fe80::/64 :: U 256 0 0 eth0 ::/0 :: !n -1 1 1 lo ::1/128 :: Un 0 1 0 lo 2000::20/128 :: Un 0 1 0 lo fe80::xxxx:xxxx:xxxx:xxxx/128 :: Un 0 1 0 lo ff00::/8 :: U 256 0 0 eth0 ::/0 :: !n -1 1 1 lo $ sudo ifdown lo $ sudo ifup lo $ route -A inet6 Kernel IPv6 routing table Destination Next Hop Flag Met Ref Use If 2000::20/128 :: U 256 0 0 eth0 fe80::/64 :: U 256 0 0 eth0 ::/0 :: !n -1 1 1 lo ::1/128 :: Un 0 1 0 lo ff00::/8 :: U 256 0 0 eth0 ::/0 :: !n -1 1 1 lo $ After applying the patch: $ route -A inet6 Kernel IPv6 routing table Destination Next Hop Flag Met Ref Use If 2000::20/128 :: U 256 0 0 eth0 fe80::/64 :: U 256 0 0 eth0 ::/0 :: !n -1 1 1 lo ::1/128 :: Un 0 1 0 lo 2000::20/128 :: Un 0 1 0 lo fe80::xxxx:xxxx:xxxx:xxxx/128 :: Un 0 1 0 lo ff00::/8 :: U 256 0 0 eth0 ::/0 :: !n -1 1 1 lo $ sudo ifdown lo $ sudo ifup lo $ route -A inet6 Kernel IPv6 routing table Destination Next Hop Flag Met Ref Use If 2000::20/128 :: U 256 0 0 eth0 fe80::/64 :: U 256 0 0 eth0 ::/0 :: !n -1 1 1 lo ::1/128 :: Un 0 1 0 lo 2000::20/128 :: Un 0 1 0 lo fe80::xxxx:xxxx:xxxx:xxxx/128 :: Un 0 1 0 lo ff00::/8 :: U 256 0 0 eth0 ::/0 :: !n -1 1 1 lo $ Signed-off-by: Balakumaran Kannan Signed-off-by: Maruthi Thotad Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 26512250e095..a459c4f5b769 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2529,6 +2529,9 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) static void init_loopback(struct net_device *dev) { struct inet6_dev *idev; + struct net_device *sp_dev; + struct inet6_ifaddr *sp_ifa; + struct rt6_info *sp_rt; /* ::1 */ @@ -2540,6 +2543,30 @@ static void init_loopback(struct net_device *dev) } add_addr(idev, &in6addr_loopback, 128, IFA_HOST); + + /* Add routes to other interface's IPv6 addresses */ + for_each_netdev(dev_net(dev), sp_dev) { + if (!strcmp(sp_dev->name, dev->name)) + continue; + + idev = __in6_dev_get(sp_dev); + if (!idev) + continue; + + read_lock_bh(&idev->lock); + list_for_each_entry(sp_ifa, &idev->addr_list, if_list) { + + if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) + continue; + + sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); + + /* Failure cases are ignored */ + if (!IS_ERR(sp_rt)) + ip6_ins_rt(sp_rt); + } + read_unlock_bh(&idev->lock); + } } static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr) -- cgit v1.2.3-55-g7522 From 990454b5a48babde44a23c0f22bae5523f4fdf13 Mon Sep 17 00:00:00 2001 From: Reilly Grant Date: Mon, 1 Apr 2013 11:41:52 -0700 Subject: VSOCK: Handle changes to the VMCI context ID. The VMCI context ID of a virtual machine may change at any time. There is a VMCI event which signals this but datagrams may be processed before this is handled. It is therefore necessary to be flexible about the destination context ID of any datagrams received. (It can be assumed to be correct because it is provided by the hypervisor.) The context ID on existing sockets should be updated to reflect how the hypervisor is currently referring to the system. Signed-off-by: Reilly Grant Acked-by: Andy King Signed-off-by: David S. Miller --- net/vmw_vsock/af_vsock.c | 6 +++--- net/vmw_vsock/vmci_transport.c | 31 ++++++++++++++++++++----------- net/vmw_vsock/vsock_addr.c | 10 ---------- net/vmw_vsock/vsock_addr.h | 2 -- 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index ca511c4f388a..d8079daf1bde 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -207,7 +207,7 @@ static struct sock *__vsock_find_bound_socket(struct sockaddr_vm *addr) struct vsock_sock *vsk; list_for_each_entry(vsk, vsock_bound_sockets(addr), bound_table) - if (vsock_addr_equals_addr_any(addr, &vsk->local_addr)) + if (addr->svm_port == vsk->local_addr.svm_port) return sk_vsock(vsk); return NULL; @@ -220,8 +220,8 @@ static struct sock *__vsock_find_connected_socket(struct sockaddr_vm *src, list_for_each_entry(vsk, vsock_connected_sockets(src, dst), connected_table) { - if (vsock_addr_equals_addr(src, &vsk->remote_addr) - && vsock_addr_equals_addr(dst, &vsk->local_addr)) { + if (vsock_addr_equals_addr(src, &vsk->remote_addr) && + dst->svm_port == vsk->local_addr.svm_port) { return sk_vsock(vsk); } } diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index a70ace83a153..1f6508e249ae 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -464,19 +464,16 @@ static struct sock *vmci_transport_get_pending( struct vsock_sock *vlistener; struct vsock_sock *vpending; struct sock *pending; + struct sockaddr_vm src; + + vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port); vlistener = vsock_sk(listener); list_for_each_entry(vpending, &vlistener->pending_links, pending_links) { - struct sockaddr_vm src; - struct sockaddr_vm dst; - - vsock_addr_init(&src, pkt->dg.src.context, pkt->src_port); - vsock_addr_init(&dst, pkt->dg.dst.context, pkt->dst_port); - if (vsock_addr_equals_addr(&src, &vpending->remote_addr) && - vsock_addr_equals_addr(&dst, &vpending->local_addr)) { + pkt->dst_port == vpending->local_addr.svm_port) { pending = sk_vsock(vpending); sock_hold(pending); goto found; @@ -739,10 +736,15 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg) */ bh_lock_sock(sk); - if (!sock_owned_by_user(sk) && sk->sk_state == SS_CONNECTED) - vmci_trans(vsk)->notify_ops->handle_notify_pkt( - sk, pkt, true, &dst, &src, - &bh_process_pkt); + if (!sock_owned_by_user(sk)) { + /* The local context ID may be out of date, update it. */ + vsk->local_addr.svm_cid = dst.svm_cid; + + if (sk->sk_state == SS_CONNECTED) + vmci_trans(vsk)->notify_ops->handle_notify_pkt( + sk, pkt, true, &dst, &src, + &bh_process_pkt); + } bh_unlock_sock(sk); @@ -902,6 +904,9 @@ static void vmci_transport_recv_pkt_work(struct work_struct *work) lock_sock(sk); + /* The local context ID may be out of date. */ + vsock_sk(sk)->local_addr.svm_cid = pkt->dg.dst.context; + switch (sk->sk_state) { case SS_LISTEN: vmci_transport_recv_listen(sk, pkt); @@ -958,6 +963,10 @@ static int vmci_transport_recv_listen(struct sock *sk, pending = vmci_transport_get_pending(sk, pkt); if (pending) { lock_sock(pending); + + /* The local context ID may be out of date. */ + vsock_sk(pending)->local_addr.svm_cid = pkt->dg.dst.context; + switch (pending->sk_state) { case SS_CONNECTING: err = vmci_transport_recv_connecting_server(sk, diff --git a/net/vmw_vsock/vsock_addr.c b/net/vmw_vsock/vsock_addr.c index b7df1aea7c59..ec2611b4ea0e 100644 --- a/net/vmw_vsock/vsock_addr.c +++ b/net/vmw_vsock/vsock_addr.c @@ -64,16 +64,6 @@ bool vsock_addr_equals_addr(const struct sockaddr_vm *addr, } EXPORT_SYMBOL_GPL(vsock_addr_equals_addr); -bool vsock_addr_equals_addr_any(const struct sockaddr_vm *addr, - const struct sockaddr_vm *other) -{ - return (addr->svm_cid == VMADDR_CID_ANY || - other->svm_cid == VMADDR_CID_ANY || - addr->svm_cid == other->svm_cid) && - addr->svm_port == other->svm_port; -} -EXPORT_SYMBOL_GPL(vsock_addr_equals_addr_any); - int vsock_addr_cast(const struct sockaddr *addr, size_t len, struct sockaddr_vm **out_addr) { diff --git a/net/vmw_vsock/vsock_addr.h b/net/vmw_vsock/vsock_addr.h index cdfbcefdf843..9ccd5316eac0 100644 --- a/net/vmw_vsock/vsock_addr.h +++ b/net/vmw_vsock/vsock_addr.h @@ -24,8 +24,6 @@ bool vsock_addr_bound(const struct sockaddr_vm *addr); void vsock_addr_unbind(struct sockaddr_vm *addr); bool vsock_addr_equals_addr(const struct sockaddr_vm *addr, const struct sockaddr_vm *other); -bool vsock_addr_equals_addr_any(const struct sockaddr_vm *addr, - const struct sockaddr_vm *other); int vsock_addr_cast(const struct sockaddr *addr, size_t len, struct sockaddr_vm **out_addr); -- cgit v1.2.3-55-g7522 From a8ec3a662921220fc058ed6f7f3674697876d218 Mon Sep 17 00:00:00 2001 From: Ilija Hadzic Date: Tue, 2 Apr 2013 09:56:10 -0400 Subject: drm: correctly restore mappings if drm_open fails If first drm_open fails, the error-handling path will incorrectly restore inode's mapping to NULL. This can cause the crash later on. Fix by separately storing away mapping pointers that drm_open can touch and restore each from its own respective variable if the call fails. Fixes: https://bugzilla.novell.com/show_bug.cgi?id=807850 (thanks to Michal Hocko for investigating investigating and finding the root cause of the bug) Reference: http://lists.freedesktop.org/archives/dri-devel/2013-March/036564.html v2: Use one variable to store file and inode mapping since they are the same at the function entry. Fix spelling mistakes in commit message. v3: Add reference to the original bug report. Reported-by: Marco Munderloh Tested-by: Marco Munderloh Signed-off-by: Ilija Hadzic Cc: Michal Hocko Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fops.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 13fdcd10a605..429e07d0b0f1 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -123,6 +123,7 @@ int drm_open(struct inode *inode, struct file *filp) int retcode = 0; int need_setup = 0; struct address_space *old_mapping; + struct address_space *old_imapping; minor = idr_find(&drm_minors_idr, minor_id); if (!minor) @@ -137,6 +138,7 @@ int drm_open(struct inode *inode, struct file *filp) if (!dev->open_count++) need_setup = 1; mutex_lock(&dev->struct_mutex); + old_imapping = inode->i_mapping; old_mapping = dev->dev_mapping; if (old_mapping == NULL) dev->dev_mapping = &inode->i_data; @@ -159,8 +161,8 @@ int drm_open(struct inode *inode, struct file *filp) err_undo: mutex_lock(&dev->struct_mutex); - filp->f_mapping = old_mapping; - inode->i_mapping = old_mapping; + filp->f_mapping = old_imapping; + inode->i_mapping = old_imapping; iput(container_of(dev->dev_mapping, struct inode, i_data)); dev->dev_mapping = old_mapping; mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3-55-g7522 From 8b4b9f27e57584f3d90e0bb84cf800ad81cfe3a1 Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Fri, 15 Feb 2013 12:21:43 -0500 Subject: x86: remove the x32 syscall bitmask from syscall_get_nr() Commit fca460f95e928bae373daa8295877b6905bc62b8 simplified the x32 implementation by creating a syscall bitmask, equal to 0x40000000, that could be applied to x32 syscalls such that the masked syscall number would be the same as a x86_64 syscall. While that patch was a nice way to simplify the code, it went a bit too far by adding the mask to syscall_get_nr(); returning the masked syscall numbers can cause confusion with callers that expect syscall numbers matching the x32 ABI, e.g. unmasked syscall numbers. This patch fixes this by simply removing the mask from syscall_get_nr() while preserving the other changes from the original commit. While there are several syscall_get_nr() callers in the kernel, most simply check that the syscall number is greater than zero, in this case this patch will have no effect. Of those remaining callers, they appear to be few, seccomp and ftrace, and from my testing of seccomp without this patch the original commit definitely breaks things; the seccomp filter does not correctly filter the syscalls due to the difference in syscall numbers in the BPF filter and the value from syscall_get_nr(). Applying this patch restores the seccomp BPF filter functionality on x32. I've tested this patch with the seccomp BPF filters as well as ftrace and everything looks reasonable to me; needless to say general usage seemed fine as well. Signed-off-by: Paul Moore Link: http://lkml.kernel.org/r/20130215172143.12549.10292.stgit@localhost Cc: Cc: Will Drewry Cc: H. Peter Anvin Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/syscall.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/syscall.h b/arch/x86/include/asm/syscall.h index 1ace47b62592..2e188d68397c 100644 --- a/arch/x86/include/asm/syscall.h +++ b/arch/x86/include/asm/syscall.h @@ -29,13 +29,13 @@ extern const unsigned long sys_call_table[]; */ static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { - return regs->orig_ax & __SYSCALL_MASK; + return regs->orig_ax; } static inline void syscall_rollback(struct task_struct *task, struct pt_regs *regs) { - regs->ax = regs->orig_ax & __SYSCALL_MASK; + regs->ax = regs->orig_ax; } static inline long syscall_get_error(struct task_struct *task, -- cgit v1.2.3-55-g7522 From b8178f130e25c1bdac1c33e0996f1ff6e20ec08e Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Mon, 1 Apr 2013 15:47:39 -0600 Subject: Revert "PCI/ACPI: Request _OSC control before scanning PCI root bus" This reverts commit 8c33f51df406e1a1f7fa4e9b244845b7ebd61fa6. Conflicts: drivers/acpi/pci_root.c This commit broke some pre-1.1 PCIe devices by leaving them with ASPM enabled. Previously, we had disabled ASPM on these devices because many of them don't implement it correctly (per 149e1637). Requesting _OSC control early means that aspm_disabled may be set before we scan the PCI bus and configure link ASPM state. But the ASPM configuration currently skips the check for pre-PCIe 1.1 devices when aspm_disabled is set, like this: acpi_pci_root_add acpi_pci_osc_support if (flags != base_flags) pcie_no_aspm aspm_disabled = 1 pci_acpi_scan_root ... pcie_aspm_init_link_state pcie_aspm_sanity_check if (!aspm_disabled) /* check for pre-PCIe 1.1 device */ Therefore, setting aspm_disabled early means that we leave ASPM enabled on these pre-PCIe 1.1 devices, which is a regression for some devices. The best fix would be to clean up the ASPM init so we can evaluate _OSC before scanning the bug (that way boot-time and hot-add discovery will work the same), but that requires significant rework. For now, we'll just revert the _OSC change as the lowest-risk fix. Reference: https://bugzilla.kernel.org/show_bug.cgi?id=55211 Signed-off-by: Bjorn Helgaas Acked-by: Rafael J. Wysocki Acked-by: Yinghai Lu CC: stable@vger.kernel.org # v3.8+ --- drivers/acpi/pci_root.c | 76 ++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 0ac546d5e53f..c740364d4abe 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -415,7 +415,6 @@ static int acpi_pci_root_add(struct acpi_device *device, struct acpi_pci_root *root; struct acpi_pci_driver *driver; u32 flags, base_flags; - bool is_osc_granted = false; root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); if (!root) @@ -476,6 +475,30 @@ static int acpi_pci_root_add(struct acpi_device *device, flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT; acpi_pci_osc_support(root, flags); + /* + * TBD: Need PCI interface for enumeration/configuration of roots. + */ + + mutex_lock(&acpi_pci_root_lock); + list_add_tail(&root->node, &acpi_pci_roots); + mutex_unlock(&acpi_pci_root_lock); + + /* + * Scan the Root Bridge + * -------------------- + * Must do this prior to any attempt to bind the root device, as the + * PCI namespace does not get created until this call is made (and + * thus the root bridge's pci_dev does not exist). + */ + root->bus = pci_acpi_scan_root(root); + if (!root->bus) { + printk(KERN_ERR PREFIX + "Bus %04x:%02x not present in PCI namespace\n", + root->segment, (unsigned int)root->secondary.start); + result = -ENODEV; + goto out_del_root; + } + /* Indicate support for various _OSC capabilities. */ if (pci_ext_cfg_avail()) flags |= OSC_EXT_PCI_CONFIG_SUPPORT; @@ -494,6 +517,7 @@ static int acpi_pci_root_add(struct acpi_device *device, flags = base_flags; } } + if (!pcie_ports_disabled && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL @@ -514,54 +538,28 @@ static int acpi_pci_root_add(struct acpi_device *device, status = acpi_pci_osc_control_set(device->handle, &flags, OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); if (ACPI_SUCCESS(status)) { - is_osc_granted = true; dev_info(&device->dev, "ACPI _OSC control (0x%02x) granted\n", flags); + if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { + /* + * We have ASPM control, but the FADT indicates + * that it's unsupported. Clear it. + */ + pcie_clear_aspm(root->bus); + } } else { - is_osc_granted = false; dev_info(&device->dev, "ACPI _OSC request failed (%s), " "returned control mask: 0x%02x\n", acpi_format_exception(status), flags); + pr_info("ACPI _OSC control for PCIe not granted, " + "disabling ASPM\n"); + pcie_no_aspm(); } } else { dev_info(&device->dev, - "Unable to request _OSC control " - "(_OSC support mask: 0x%02x)\n", flags); - } - - /* - * TBD: Need PCI interface for enumeration/configuration of roots. - */ - - mutex_lock(&acpi_pci_root_lock); - list_add_tail(&root->node, &acpi_pci_roots); - mutex_unlock(&acpi_pci_root_lock); - - /* - * Scan the Root Bridge - * -------------------- - * Must do this prior to any attempt to bind the root device, as the - * PCI namespace does not get created until this call is made (and - * thus the root bridge's pci_dev does not exist). - */ - root->bus = pci_acpi_scan_root(root); - if (!root->bus) { - printk(KERN_ERR PREFIX - "Bus %04x:%02x not present in PCI namespace\n", - root->segment, (unsigned int)root->secondary.start); - result = -ENODEV; - goto out_del_root; - } - - /* ASPM setting */ - if (is_osc_granted) { - if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) - pcie_clear_aspm(root->bus); - } else { - pr_info("ACPI _OSC control for PCIe not granted, " - "disabling ASPM\n"); - pcie_no_aspm(); + "Unable to request _OSC control " + "(_OSC support mask: 0x%02x)\n", flags); } pci_acpi_add_bus_pm_notifier(device, root->bus); -- cgit v1.2.3-55-g7522 From 6e0eda3c389887168455b92b6f7b48f552227067 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 14 Mar 2013 18:49:37 +0400 Subject: PCI: Don't try to disable Bus Master on disconnected PCI devices This is a fix for commit 7897e60227 ("PCI: Disable Bus Master unconditionally in pci_device_shutdown()"). Vivek reported that with this commit, kexec failed because none of his SATA disks came up. A ->shutdown() callback might put the device in D3cold, which means config space is no longer available. [bhelgaas: changelog] Link: https://lkml.org/lkml/2013/3/12/529 Reported-and-Tested-by: Vivek Goyal Signed-off-by: Konstantin Khlebnikov Signed-off-by: Bjorn Helgaas Cc: Rafael J. Wysocki --- drivers/pci/pci-driver.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 1fa1e482a999..79277fb36c6b 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -390,9 +390,10 @@ static void pci_device_shutdown(struct device *dev) /* * Turn off Bus Master bit on the device to tell it to not - * continue to do DMA + * continue to do DMA. Don't touch devices in D3cold or unknown states. */ - pci_clear_master(pci_dev); + if (pci_dev->current_state <= PCI_D3hot) + pci_clear_master(pci_dev); } #ifdef CONFIG_PM -- cgit v1.2.3-55-g7522 From 906b1c394d0906a154fbdc904ca506bceb515756 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 30 Mar 2013 10:23:12 +0000 Subject: netfilter: ip6t_NPT: Fix translation for non-multiple of 32 prefix lengths The bitmask used for the prefix mangling was being calculated incorrectly, leading to the wrong part of the address being replaced when the prefix length wasn't a multiple of 32. Signed-off-by: Matthias Schiffer Signed-off-by: Pablo Neira Ayuso --- net/ipv6/netfilter/ip6t_NPT.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/netfilter/ip6t_NPT.c b/net/ipv6/netfilter/ip6t_NPT.c index 33608c610276..cb631143721c 100644 --- a/net/ipv6/netfilter/ip6t_NPT.c +++ b/net/ipv6/netfilter/ip6t_NPT.c @@ -57,7 +57,7 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, if (pfx_len - i >= 32) mask = 0; else - mask = htonl(~((1 << (pfx_len - i)) - 1)); + mask = htonl((1 << (i - pfx_len + 32)) - 1); idx = i / 32; addr->s6_addr32[idx] &= mask; -- cgit v1.2.3-55-g7522 From e66cd5372d09d58002b2779a3bcdc564d6348883 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Wed, 3 Apr 2013 13:17:20 +0200 Subject: ACPI / BGRT: Don't let users configure BGRT on non X86 systems Fengguang Wu's 0-Day kernel build testing backend found the following build error for an allmodconfig build on ia64: drivers/built-in.o: In function `show_yoffset': >> bgrt.c:(.text+0xe5a71): undefined reference to `bgrt_tab' >> bgrt.c:(.text+0xe5a91): undefined reference to `bgrt_tab' drivers/built-in.o: In function `show_xoffset': >> bgrt.c:(.text+0xe5b51): undefined reference to `bgrt_tab' >> bgrt.c:(.text+0xe5b71): undefined reference to `bgrt_tab' drivers/built-in.o: In function `show_type': >> bgrt.c:(.text+0xe5c31): undefined reference to `bgrt_tab' drivers/built-in.o:bgrt.c:(.text+0xe5c51): more undefined references to `bgrt_tab' follow drivers/built-in.o: In function `bgrt_init': bgrt.c:(.init.text+0x8931): undefined reference to `bgrt_image' bgrt.c:(.init.text+0x8932): undefined reference to `bgrt_image_size' bgrt.c:(.init.text+0x8950): undefined reference to `bgrt_image' bgrt.c:(.init.text+0x8960): undefined reference to `bgrt_image_size' The problem is that all these undefined names are provided by arch/x86/platform/efi/efi-bgrt.c - which is obviously not available to the ia64 build. It doesn't seem useful to provide the BGRT support for Itanium (many systems are headless and have no graphics at all). So just don't let users configure this driver on non-X86 machines. Reported-by: Fengguang Wu Acked-by: H. Peter Anvin Signed-off-by: Tony Luck Signed-off-by: Rafael J. Wysocki --- drivers/acpi/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 92ed9692c47e..4bf68c8d4797 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -396,7 +396,7 @@ config ACPI_CUSTOM_METHOD config ACPI_BGRT bool "Boottime Graphics Resource Table support" - depends on EFI + depends on EFI && X86 help This driver adds support for exposing the ACPI Boottime Graphics Resource Table, which allows the operating system to obtain -- cgit v1.2.3-55-g7522 From 690a863ff03d9a29ace2b752b8f802fba78a842f Mon Sep 17 00:00:00 2001 From: Torstein Hegge Date: Tue, 26 Mar 2013 22:10:05 +0100 Subject: ALSA: usb: Work around CM6631 sample rate change bug The C-Media CM6631 USB receiver doesn't respond to changes in sample rate while the interface is active. The same behavior is observed in other UAC2 hardware like the VIA VT1731. Reset the interface after setting the sampling frequency on sample rate changes, to ensure that the sample rate set by snd_usb_init_sample_rate() is used. Otherwise, the device will try to use the sample rate of the previous stream, causing distorted sound on sample rate changes. The reset is performed for all UAC2 devices, as it should not affect a standards compliant device, but it is only necessary for C-Media CM6631, VIA VT1731 and possibly others. Failure to read sample rate from the device is not handled as an error in set_sample_rate_v2(), as (permanent or intermittent) failure to read sample rate isn't essential for a successful sample rate set. Signed-off-by: Torstein Hegge Acked-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/usb/clock.c | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 5e634a2eb282..9e2703a25156 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c @@ -253,7 +253,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, { struct usb_device *dev = chip->dev; unsigned char data[4]; - int err, crate; + int err, cur_rate, prev_rate; int clock = snd_usb_clock_find_source(chip, fmt->clock); if (clock < 0) @@ -266,6 +266,19 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, return -ENXIO; } + err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, + UAC2_CS_CONTROL_SAM_FREQ << 8, + snd_usb_ctrl_intf(chip) | (clock << 8), + data, sizeof(data)); + if (err < 0) { + snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", + dev->devnum, iface, fmt->altsetting); + prev_rate = 0; + } else { + prev_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); + } + data[0] = rate; data[1] = rate >> 8; data[2] = rate >> 16; @@ -280,19 +293,31 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, return err; } - if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, - USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - UAC2_CS_CONTROL_SAM_FREQ << 8, - snd_usb_ctrl_intf(chip) | (clock << 8), - data, sizeof(data))) < 0) { + err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, + USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, + UAC2_CS_CONTROL_SAM_FREQ << 8, + snd_usb_ctrl_intf(chip) | (clock << 8), + data, sizeof(data)); + if (err < 0) { snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", dev->devnum, iface, fmt->altsetting); - return err; + cur_rate = 0; + } else { + cur_rate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); } - crate = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); - if (crate != rate) - snd_printd(KERN_WARNING "current rate %d is different from the runtime rate %d\n", crate, rate); + if (cur_rate != rate) { + snd_printd(KERN_WARNING + "current rate %d is different from the runtime rate %d\n", + cur_rate, rate); + } + + /* Some devices doesn't respond to sample rate changes while the + * interface is active. */ + if (rate != prev_rate) { + usb_set_interface(dev, iface, 0); + usb_set_interface(dev, iface, fmt->altsetting); + } return 0; } -- cgit v1.2.3-55-g7522 From 698613b63817f2f6ca79831cd1c37aae67025323 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 3 Apr 2013 16:33:26 +0100 Subject: ARM: iWMMXt: always enable iWMMXt support with PJ4 CPUs Jason Cooper reports these build errors: arch/arm/kernel/built-in.o: In function `iwmmxt_do': /.../arch/arm/kernel/pj4-cp0.c:36: undefined reference to `iwmmxt_task_release' /.../arch/arm/kernel/pj4-cp0.c:40: undefined reference to `iwmmxt_task_switch' make: *** [vmlinux] Error 1 This is caused because the PJ4 code explicitly references the iWMMXt code, but doesn't require it to be built. Fix this by ensuring that iWMMXt is always enabled with PJ4. Reported-by: Jason Cooper Signed-off-by: Russell King --- arch/arm/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 13b739469c51..12ea3b3d49a9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1183,9 +1183,9 @@ config ARM_NR_BANKS default 8 config IWMMXT - bool "Enable iWMMXt support" + bool "Enable iWMMXt support" if !CPU_PJ4 depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 - default y if PXA27x || PXA3xx || ARCH_MMP + default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 help Enable support for iWMMXt context switching at run time if running on a CPU that supports it. -- cgit v1.2.3-55-g7522 From 6e7aceeb7c70b9ebad79bcfe91fcf738826e8e6d Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 25 Mar 2013 17:02:48 +0100 Subject: ARM: 7682/1: cache-l2x0: fix masking of RTL revision numbering and set_debug init Commit b8db6b8 (ARM: 7547/4: cache-l2x0: add support for Aurora L2 cache ctrl) moved the masking of the part ID which caused the RTL version to be lost. Commit 6248d06 (ARM: 7545/1: cache-l2x0: make outer_cache_fns a field of l2x0_of_data) changed how .set_debug is initialized. Both commits break commit 74ddcdb (ARM: 7608/1: l2x0: Only set .set_debug on PL310 r3p0 and earlier) which uses the RTL version to conditionally set .set_debug function pointer. Commit b8db6b8 also caused the printed cache ID to be missing the version information. Fix this by reverting how the part number is masked so the RTL version info is maintained. The cache-id-part DT property does not set the RTL bits so masking them should have no effect. Also, re-arrange the order of the function pointer init so the .set_debug function can be overridden. Reported-by: Paolo Pisati Signed-off-by: Rob Herring Cc: Gregory CLEMENT Cc: Yehuda Yitschak Signed-off-by: Russell King --- arch/arm/mm/cache-l2x0.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index c2f37390308a..c465faca51b0 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c @@ -299,7 +299,7 @@ static void l2x0_unlock(u32 cache_id) int lockregs; int i; - switch (cache_id) { + switch (cache_id & L2X0_CACHE_ID_PART_MASK) { case L2X0_CACHE_ID_PART_L310: lockregs = 8; break; @@ -333,15 +333,14 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask) if (cache_id_part_number_from_dt) cache_id = cache_id_part_number_from_dt; else - cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID) - & L2X0_CACHE_ID_PART_MASK; + cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID); aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); aux &= aux_mask; aux |= aux_val; /* Determine the number of ways */ - switch (cache_id) { + switch (cache_id & L2X0_CACHE_ID_PART_MASK) { case L2X0_CACHE_ID_PART_L310: if (aux & (1 << 16)) ways = 16; @@ -725,7 +724,6 @@ static const struct l2x0_of_data pl310_data = { .flush_all = l2x0_flush_all, .inv_all = l2x0_inv_all, .disable = l2x0_disable, - .set_debug = pl310_set_debug, }, }; @@ -814,9 +812,8 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask) data->save(); of_init = true; - l2x0_init(l2x0_base, aux_val, aux_mask); - memcpy(&outer_cache, &data->outer_cache, sizeof(outer_cache)); + l2x0_init(l2x0_base, aux_val, aux_mask); return 0; } -- cgit v1.2.3-55-g7522 From 93dc68876b608da041fe40ed39424b0fcd5aa2fb Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Tue, 26 Mar 2013 23:35:04 +0100 Subject: ARM: 7684/1: errata: Workaround for Cortex-A15 erratum 798181 (TLBI/DSB operations) On Cortex-A15 (r0p0..r3p2) the TLBI/DSB are not adequately shooting down all use of the old entries. This patch implements the erratum workaround which consists of: 1. Dummy TLBIMVAIS and DSB on the CPU doing the TLBI operation. 2. Send IPI to the CPUs that are running the same mm (and ASID) as the one being invalidated (or all the online CPUs for global pages). 3. CPU receiving the IPI executes a DMB and CLREX (part of the exception return code already). Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/Kconfig | 10 ++++++ arch/arm/include/asm/highmem.h | 7 ++++ arch/arm/include/asm/mmu_context.h | 2 ++ arch/arm/include/asm/tlbflush.h | 15 +++++++++ arch/arm/kernel/smp_tlb.c | 66 ++++++++++++++++++++++++++++++++++++++ arch/arm/mm/context.c | 3 +- 6 files changed, 102 insertions(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 12ea3b3d49a9..1cacda426a0e 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1439,6 +1439,16 @@ config ARM_ERRATA_775420 to deadlock. This workaround puts DSB before executing ISB if an abort may occur on cache maintenance. +config ARM_ERRATA_798181 + bool "ARM errata: TLBI/DSB failure on Cortex-A15" + depends on CPU_V7 && SMP + help + On Cortex-A15 (r0p0..r3p2) the TLBI*IS/DSB operations are not + adequately shooting down all use of the old entries. This + option enables the Linux kernel workaround for this erratum + which sends an IPI to the CPUs that are running the same ASID + as the one being invalidated. + endmenu source "arch/arm/common/Kconfig" diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h index 8c5e828f484d..91b99abe7a95 100644 --- a/arch/arm/include/asm/highmem.h +++ b/arch/arm/include/asm/highmem.h @@ -41,6 +41,13 @@ extern void kunmap_high(struct page *page); #endif #endif +/* + * Needed to be able to broadcast the TLB invalidation for kmap. + */ +#ifdef CONFIG_ARM_ERRATA_798181 +#undef ARCH_NEEDS_KMAP_HIGH_GET +#endif + #ifdef ARCH_NEEDS_KMAP_HIGH_GET extern void *kmap_high_get(struct page *page); #else diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h index 863a6611323c..a7b85e0d0cc1 100644 --- a/arch/arm/include/asm/mmu_context.h +++ b/arch/arm/include/asm/mmu_context.h @@ -27,6 +27,8 @@ void __check_vmalloc_seq(struct mm_struct *mm); void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk); #define init_new_context(tsk,mm) ({ atomic64_set(&mm->context.id, 0); 0; }) +DECLARE_PER_CPU(atomic64_t, active_asids); + #else /* !CONFIG_CPU_HAS_ASID */ #ifdef CONFIG_MMU diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index 4db8c8820f0d..9e9c041358ca 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h @@ -450,6 +450,21 @@ static inline void local_flush_bp_all(void) isb(); } +#ifdef CONFIG_ARM_ERRATA_798181 +static inline void dummy_flush_tlb_a15_erratum(void) +{ + /* + * Dummy TLBIMVAIS. Using the unmapped address 0 and ASID 0. + */ + asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (0)); + dsb(); +} +#else +static inline void dummy_flush_tlb_a15_erratum(void) +{ +} +#endif + /* * flush_pmd_entry * diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c index bd0300531399..e82e1d248772 100644 --- a/arch/arm/kernel/smp_tlb.c +++ b/arch/arm/kernel/smp_tlb.c @@ -12,6 +12,7 @@ #include #include +#include /**********************************************************************/ @@ -69,12 +70,72 @@ static inline void ipi_flush_bp_all(void *ignored) local_flush_bp_all(); } +#ifdef CONFIG_ARM_ERRATA_798181 +static int erratum_a15_798181(void) +{ + unsigned int midr = read_cpuid_id(); + + /* Cortex-A15 r0p0..r3p2 affected */ + if ((midr & 0xff0ffff0) != 0x410fc0f0 || midr > 0x413fc0f2) + return 0; + return 1; +} +#else +static int erratum_a15_798181(void) +{ + return 0; +} +#endif + +static void ipi_flush_tlb_a15_erratum(void *arg) +{ + dmb(); +} + +static void broadcast_tlb_a15_erratum(void) +{ + if (!erratum_a15_798181()) + return; + + dummy_flush_tlb_a15_erratum(); + smp_call_function_many(cpu_online_mask, ipi_flush_tlb_a15_erratum, + NULL, 1); +} + +static void broadcast_tlb_mm_a15_erratum(struct mm_struct *mm) +{ + int cpu; + cpumask_t mask = { CPU_BITS_NONE }; + + if (!erratum_a15_798181()) + return; + + dummy_flush_tlb_a15_erratum(); + for_each_online_cpu(cpu) { + if (cpu == smp_processor_id()) + continue; + /* + * We only need to send an IPI if the other CPUs are running + * the same ASID as the one being invalidated. There is no + * need for locking around the active_asids check since the + * switch_mm() function has at least one dmb() (as required by + * this workaround) in case a context switch happens on + * another CPU after the condition below. + */ + if (atomic64_read(&mm->context.id) == + atomic64_read(&per_cpu(active_asids, cpu))) + cpumask_set_cpu(cpu, &mask); + } + smp_call_function_many(&mask, ipi_flush_tlb_a15_erratum, NULL, 1); +} + void flush_tlb_all(void) { if (tlb_ops_need_broadcast()) on_each_cpu(ipi_flush_tlb_all, NULL, 1); else local_flush_tlb_all(); + broadcast_tlb_a15_erratum(); } void flush_tlb_mm(struct mm_struct *mm) @@ -83,6 +144,7 @@ void flush_tlb_mm(struct mm_struct *mm) on_each_cpu_mask(mm_cpumask(mm), ipi_flush_tlb_mm, mm, 1); else local_flush_tlb_mm(mm); + broadcast_tlb_mm_a15_erratum(mm); } void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) @@ -95,6 +157,7 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) &ta, 1); } else local_flush_tlb_page(vma, uaddr); + broadcast_tlb_mm_a15_erratum(vma->vm_mm); } void flush_tlb_kernel_page(unsigned long kaddr) @@ -105,6 +168,7 @@ void flush_tlb_kernel_page(unsigned long kaddr) on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1); } else local_flush_tlb_kernel_page(kaddr); + broadcast_tlb_a15_erratum(); } void flush_tlb_range(struct vm_area_struct *vma, @@ -119,6 +183,7 @@ void flush_tlb_range(struct vm_area_struct *vma, &ta, 1); } else local_flush_tlb_range(vma, start, end); + broadcast_tlb_mm_a15_erratum(vma->vm_mm); } void flush_tlb_kernel_range(unsigned long start, unsigned long end) @@ -130,6 +195,7 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end) on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1); } else local_flush_tlb_kernel_range(start, end); + broadcast_tlb_a15_erratum(); } void flush_bp_all(void) diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index a5a4b2bc42ba..2ac37372ef52 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c @@ -48,7 +48,7 @@ static DEFINE_RAW_SPINLOCK(cpu_asid_lock); static atomic64_t asid_generation = ATOMIC64_INIT(ASID_FIRST_VERSION); static DECLARE_BITMAP(asid_map, NUM_USER_ASIDS); -static DEFINE_PER_CPU(atomic64_t, active_asids); +DEFINE_PER_CPU(atomic64_t, active_asids); static DEFINE_PER_CPU(u64, reserved_asids); static cpumask_t tlb_flush_pending; @@ -215,6 +215,7 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk) if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) { local_flush_bp_all(); local_flush_tlb_all(); + dummy_flush_tlb_a15_erratum(); } atomic64_set(&per_cpu(active_asids, cpu), asid); -- cgit v1.2.3-55-g7522 From 6f3d90e55660ba42301b5e9c7eed332cc9f70fd7 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 28 Mar 2013 11:17:55 +0100 Subject: ARM: 7685/1: delay: use private ticks_per_jiffy field for timer-based delay ops Commit 70264367a243 ("ARM: 7653/2: do not scale loops_per_jiffy when using a constant delay clock") fixed a problem with our timer-based delay loop, where loops_per_jiffy is scaled by cpufreq yet used directly by the timer delay ops. This patch fixes the problem in a more elegant way by keeping a private ticks_per_jiffy field in the delay ops, independent of loops_per_jiffy and therefore not subject to scaling. The loop-based delay continues to use loops_per_jiffy directly, as it should. Acked-by: Nicolas Pitre Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/include/asm/delay.h | 2 +- arch/arm/kernel/smp.c | 3 --- arch/arm/lib/delay.c | 8 +++++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h index 720799fd3a81..dff714d886d5 100644 --- a/arch/arm/include/asm/delay.h +++ b/arch/arm/include/asm/delay.h @@ -24,7 +24,7 @@ extern struct arm_delay_ops { void (*delay)(unsigned long); void (*const_udelay)(unsigned long); void (*udelay)(unsigned long); - bool const_clock; + unsigned long ticks_per_jiffy; } arm_delay_ops; #define __delay(n) arm_delay_ops.delay(n) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 79078edbb9bc..1f2ccccaf009 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -673,9 +673,6 @@ static int cpufreq_callback(struct notifier_block *nb, if (freq->flags & CPUFREQ_CONST_LOOPS) return NOTIFY_OK; - if (arm_delay_ops.const_clock) - return NOTIFY_OK; - if (!per_cpu(l_p_j_ref, cpu)) { per_cpu(l_p_j_ref, cpu) = per_cpu(cpu_data, cpu).loops_per_jiffy; diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c index 6b93f6a1a3c7..64dbfa57204a 100644 --- a/arch/arm/lib/delay.c +++ b/arch/arm/lib/delay.c @@ -58,7 +58,7 @@ static void __timer_delay(unsigned long cycles) static void __timer_const_udelay(unsigned long xloops) { unsigned long long loops = xloops; - loops *= loops_per_jiffy; + loops *= arm_delay_ops.ticks_per_jiffy; __timer_delay(loops >> UDELAY_SHIFT); } @@ -73,11 +73,13 @@ void __init register_current_timer_delay(const struct delay_timer *timer) pr_info("Switching to timer-based delay loop\n"); delay_timer = timer; lpj_fine = timer->freq / HZ; - loops_per_jiffy = lpj_fine; + + /* cpufreq may scale loops_per_jiffy, so keep a private copy */ + arm_delay_ops.ticks_per_jiffy = lpj_fine; arm_delay_ops.delay = __timer_delay; arm_delay_ops.const_udelay = __timer_const_udelay; arm_delay_ops.udelay = __timer_udelay; - arm_delay_ops.const_clock = true; + delay_calibrated = true; } else { pr_info("Ignoring duplicate/late registration of read_current_timer delay\n"); -- cgit v1.2.3-55-g7522 From b21e023ba4003fe4b5c32540e4aee5991c019e92 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 2 Apr 2013 22:11:46 +0100 Subject: ARM: 7689/1: add unwind annotations to ftrace asm Add unwind annotations to the ftrace assembly code so that the function tracer's stacktracing options (func_stack_trace, etc.) work when CONFIG_ARM_UNWIND is enabled. Signed-off-by: Rabin Vincent Signed-off-by: Russell King --- arch/arm/kernel/entry-common.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 3248cde504ed..fefd7f971437 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -276,7 +276,13 @@ ENDPROC(ftrace_graph_caller_old) */ .macro mcount_enter +/* + * This pad compensates for the push {lr} at the call site. Note that we are + * unable to unwind through a function which does not otherwise save its lr. + */ + UNWIND(.pad #4) stmdb sp!, {r0-r3, lr} + UNWIND(.save {r0-r3, lr}) .endm .macro mcount_get_lr reg @@ -289,6 +295,7 @@ ENDPROC(ftrace_graph_caller_old) .endm ENTRY(__gnu_mcount_nc) +UNWIND(.fnstart) #ifdef CONFIG_DYNAMIC_FTRACE mov ip, lr ldmia sp!, {lr} @@ -296,17 +303,22 @@ ENTRY(__gnu_mcount_nc) #else __mcount #endif +UNWIND(.fnend) ENDPROC(__gnu_mcount_nc) #ifdef CONFIG_DYNAMIC_FTRACE ENTRY(ftrace_caller) +UNWIND(.fnstart) __ftrace_caller +UNWIND(.fnend) ENDPROC(ftrace_caller) #endif #ifdef CONFIG_FUNCTION_GRAPH_TRACER ENTRY(ftrace_graph_caller) +UNWIND(.fnstart) __ftrace_graph_caller +UNWIND(.fnend) ENDPROC(ftrace_graph_caller) #endif -- cgit v1.2.3-55-g7522 From 4e1db26a0b42e2b6e27c05d68adcc01709c2eed2 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 3 Apr 2013 12:24:45 +0100 Subject: ARM: 7690/1: mm: fix CONFIG_LPAE typos CONFIG_LPAE doesn't exist: the correct option is CONFIG_ARM_LPAE, so fix up the two typos under arch/arm/. The fix to head.S is slightly scary, but this is just for setting up an early io-mapping for the serial port when running on a big-endian, LPAE system. Since these systems don't exist in the wild (at least, I have no access to one outside of kvmtool, which doesn't provide a serial port suitable for earlyprintk), then we can revisit the code later if it causes any problems. Signed-off-by: Paul Bolle Signed-off-by: Will Deacon Signed-off-by: Russell King --- arch/arm/kernel/head.S | 2 +- arch/arm/kernel/setup.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index e0eb9a1cae77..8bac553fe213 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -267,7 +267,7 @@ __create_page_tables: addne r6, r6, #1 << SECTION_SHIFT strne r6, [r3] -#if defined(CONFIG_LPAE) && defined(CONFIG_CPU_ENDIAN_BE8) +#if defined(CONFIG_ARM_LPAE) && defined(CONFIG_CPU_ENDIAN_BE8) sub r4, r4, #4 @ Fixup page table pointer @ for 64-bit descriptors #endif diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index f3ac13f69b7a..d343a6c3a6d1 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -544,7 +544,7 @@ int __init arm_add_memory(phys_addr_t start, phys_addr_t size) size -= start & ~PAGE_MASK; bank->start = PAGE_ALIGN(start); -#ifndef CONFIG_LPAE +#ifndef CONFIG_ARM_LPAE if (bank->start + size < bank->start) { printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " "32-bit physical address space\n", (long long)start); -- cgit v1.2.3-55-g7522 From 8cde7ad17e4f4ff8d12ff60dd09c0a291cb0b61c Mon Sep 17 00:00:00 2001 From: Zheng Liu Date: Wed, 3 Apr 2013 12:27:18 -0400 Subject: ext4: fix big-endian bugs which could cause fs corruptions When an extent was zeroed out, we forgot to do convert from cpu to le16. It could make us hit a BUG_ON when we try to write dirty pages out. So fix it. [ Also fix a bug found by Dmitry Monakhov where we were missing le32_to_cpu() calls in the new indirect punch hole code. There are a number of other big endian warnings found by static code analyzers, but we'll wait for the next merge window to fix them all up. These fixes are designed to be Obviously Correct by code inspection, and easy to demonstrate that it won't make any difference (and hence, won't introduce any bugs) on little endian architectures such as x86. --tytso ] Signed-off-by: Zheng Liu Signed-off-by: "Theodore Ts'o" Reported-by: CAI Qian Reported-by: Christian Kujau Cc: Dmitry Monakhov --- fs/ext4/extents.c | 11 +++++++---- fs/ext4/indirect.c | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 56efcaadf848..9c6d06dcef8b 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2999,20 +2999,23 @@ static int ext4_split_extent_at(handle_t *handle, if (split_flag & EXT4_EXT_DATA_VALID1) { err = ext4_ext_zeroout(inode, ex2); zero_ex.ee_block = ex2->ee_block; - zero_ex.ee_len = ext4_ext_get_actual_len(ex2); + zero_ex.ee_len = cpu_to_le16( + ext4_ext_get_actual_len(ex2)); ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(ex2)); } else { err = ext4_ext_zeroout(inode, ex); zero_ex.ee_block = ex->ee_block; - zero_ex.ee_len = ext4_ext_get_actual_len(ex); + zero_ex.ee_len = cpu_to_le16( + ext4_ext_get_actual_len(ex)); ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(ex)); } } else { err = ext4_ext_zeroout(inode, &orig_ex); zero_ex.ee_block = orig_ex.ee_block; - zero_ex.ee_len = ext4_ext_get_actual_len(&orig_ex); + zero_ex.ee_len = cpu_to_le16( + ext4_ext_get_actual_len(&orig_ex)); ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(&orig_ex)); } @@ -3272,7 +3275,7 @@ static int ext4_ext_convert_to_initialized(handle_t *handle, if (err) goto out; zero_ex.ee_block = ex->ee_block; - zero_ex.ee_len = ext4_ext_get_actual_len(ex); + zero_ex.ee_len = cpu_to_le16(ext4_ext_get_actual_len(ex)); ext4_ext_store_pblock(&zero_ex, ext4_ext_pblock(ex)); err = ext4_ext_get_access(handle, inode, path + depth); diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c index b505a145a593..a04183127ef0 100644 --- a/fs/ext4/indirect.c +++ b/fs/ext4/indirect.c @@ -1539,9 +1539,9 @@ static int free_hole_blocks(handle_t *handle, struct inode *inode, blk = *i_data; if (level > 0) { ext4_lblk_t first2; - bh = sb_bread(inode->i_sb, blk); + bh = sb_bread(inode->i_sb, le32_to_cpu(blk)); if (!bh) { - EXT4_ERROR_INODE_BLOCK(inode, blk, + EXT4_ERROR_INODE_BLOCK(inode, le32_to_cpu(blk), "Read failure"); return -EIO; } -- cgit v1.2.3-55-g7522 From 24ad0ef9c8b946ed2abe681e4e44f4a1e643d882 Mon Sep 17 00:00:00 2001 From: Rafael J. Wysocki Date: Thu, 28 Mar 2013 11:07:29 +0000 Subject: PCI/ACPI: Always resume devices on ACPI wakeup notifications It turns out that the _Lxx control methods provided by some BIOSes clear the PME Status bit of PCI devices they handle, which means that pci_acpi_wake_dev() cannot really use that bit to check whether or not the device has signalled wakeup. One symptom of the problem is, for example, that when an affected PCI USB controller is runtime-suspended, then plugging in a new USB device into one of the controller's ports will not wake up the controller, which should happen. For this reason, make pci_acpi_wake_dev() always attempt to resume the device it is called for regardless of the device's PME Status bit value (that bit still has to be cleared if set at this point, though). Reported-by: Sarah Sharp Signed-off-by: Rafael J. Wysocki Signed-off-by: Bjorn Helgaas Acked-by: Matthew Garrett CC: stable@vger.kernel.org # v3.7+--- drivers/pci/pci-acpi.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index dee5dddaa292..5147c210df52 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -53,14 +53,15 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) return; } - if (!pci_dev->pm_cap || !pci_dev->pme_support - || pci_check_pme_status(pci_dev)) { - if (pci_dev->pme_poll) - pci_dev->pme_poll = false; + /* Clear PME Status if set. */ + if (pci_dev->pme_support) + pci_check_pme_status(pci_dev); - pci_wakeup_event(pci_dev); - pm_runtime_resume(&pci_dev->dev); - } + if (pci_dev->pme_poll) + pci_dev->pme_poll = false; + + pci_wakeup_event(pci_dev); + pm_runtime_resume(&pci_dev->dev); if (pci_dev->subordinate) pci_pme_wakeup_bus(pci_dev->subordinate); -- cgit v1.2.3-55-g7522 From de7d5f729c72638f41d7c17487bccb1c570ff144 Mon Sep 17 00:00:00 2001 From: Rafael J. Wysocki Date: Sat, 30 Mar 2013 23:38:02 +0100 Subject: PCI/PM: Disable runtime PM of PCIe ports The runtime PM of PCIe ports turns out to be quite fragile, as in some cases things work while in some other cases they don't and we don't seem to have a good way to determine whether or not they are going to work in advance. For this reason, avoid enabling runtime PM for PCIe ports by keeping their runtime PM reference counters always above 0 for the time being. When a PCIe port is suspended, it can no longer report events like hotplug, so hotplug below the port may not work, as in the bug report below. [bhelgaas: changelog, stable] Reference: https://bugzilla.kernel.org/show_bug.cgi?id=53811 Signed-off-by: Rafael J. Wysocki Signed-off-by: Bjorn Helgaas CC: stable@vger.kernel.org # v3.6+--- drivers/pci/pcie/portdrv_pci.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 08c243ab034e..ed4d09498337 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -184,14 +184,6 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { #define PCIE_PORTDRV_PM_OPS NULL #endif /* !PM */ -/* - * PCIe port runtime suspend is broken for some chipsets, so use a - * black list to disable runtime PM for these chipsets. - */ -static const struct pci_device_id port_runtime_pm_black_list[] = { - { /* end: all zeroes */ } -}; - /* * pcie_portdrv_probe - Probe PCI-Express port devices * @dev: PCI-Express port device being probed @@ -225,16 +217,11 @@ static int pcie_portdrv_probe(struct pci_dev *dev, * it by default. */ dev->d3cold_allowed = false; - if (!pci_match_id(port_runtime_pm_black_list, dev)) - pm_runtime_put_noidle(&dev->dev); - return 0; } static void pcie_portdrv_remove(struct pci_dev *dev) { - if (!pci_match_id(port_runtime_pm_black_list, dev)) - pm_runtime_get_noresume(&dev->dev); pcie_port_device_remove(dev); pci_disable_device(dev); } -- cgit v1.2.3-55-g7522 From 1d87caa69c04008e09f5ff47b5e6acb6116febc7 Mon Sep 17 00:00:00 2001 From: Rainer Koenig Date: Thu, 4 Apr 2013 08:40:38 +0200 Subject: ALSA: hda - Enabling Realtek ALC 671 codec * Added the device ID to the modalias list and assinged ALC662 patches for it * Added 4 port support for the device ID 0671 in alc662_parse_auto_config Signed-off-by: Rainer Koenig Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 563c24df4d6f..f15c36bde540 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3440,7 +3440,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec) const hda_nid_t *ssids; if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || - codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) + codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 || + codec->vendor_id == 0x10ec0671) ssids = alc663_ssids; else ssids = alc662_ssids; @@ -3894,6 +3895,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, + { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 }, { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, -- cgit v1.2.3-55-g7522 From f1a9a149abc86903e81dd1b2e720f3f89874384b Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 2 Apr 2013 11:11:52 +0200 Subject: HID: magicmouse: fix race between input_register() and probe() Since kernel 3.7, it appears that the input registration occured before the end of magicmouse_setup_input(). This is shown by receiving a lot of "EV_SYN SYN_REPORT 1" instead of normal "EV_SYN SYN_REPORT 0". This value means that the output buffer is full, and the user space is loosing events. Using .input_configured guarantees that the race is not occuring, and that the call of "input_set_events_per_packet(input, 60)" is taken into account by input_register(). Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=908604 Cc: stable@vger.kernel.org Reported-and-Tested-By: Clarke Wixon Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index f7f113ba083e..a8ce44296cfd 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -462,6 +462,21 @@ static int magicmouse_input_mapping(struct hid_device *hdev, return 0; } +static void magicmouse_input_configured(struct hid_device *hdev, + struct hid_input *hi) + +{ + struct magicmouse_sc *msc = hid_get_drvdata(hdev); + + int ret = magicmouse_setup_input(msc->input, hdev); + if (ret) { + hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); + /* clean msc->input to notify probe() of the failure */ + msc->input = NULL; + } +} + + static int magicmouse_probe(struct hid_device *hdev, const struct hid_device_id *id) { @@ -493,15 +508,10 @@ static int magicmouse_probe(struct hid_device *hdev, goto err_free; } - /* We do this after hid-input is done parsing reports so that - * hid-input uses the most natural button and axis IDs. - */ - if (msc->input) { - ret = magicmouse_setup_input(msc->input, hdev); - if (ret) { - hid_err(hdev, "magicmouse setup input failed (%d)\n", ret); - goto err_stop_hw; - } + if (!msc->input) { + hid_err(hdev, "magicmouse input not registered\n"); + ret = -ENOMEM; + goto err_stop_hw; } if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) @@ -568,6 +578,7 @@ static struct hid_driver magicmouse_driver = { .remove = magicmouse_remove, .raw_event = magicmouse_raw_event, .input_mapping = magicmouse_input_mapping, + .input_configured = magicmouse_input_configured, }; module_hid_driver(magicmouse_driver); -- cgit v1.2.3-55-g7522 From 57c7310b8eb96b0fe3b0aaa8dc194adbae03bef3 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Tue, 5 Mar 2013 16:01:47 -0500 Subject: GFS2: use kmalloc for lvb bitmap The temp lvb bitmap was on the stack, which could be an alignment problem for __set_bit_le. Use kmalloc for it instead. Signed-off-by: David Teigland Signed-off-by: Steven Whitehouse --- fs/gfs2/incore.h | 1 + fs/gfs2/lock_dlm.c | 31 ++++++++++++++++++------------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 156e42ec84ea..5c29216e9cc1 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h @@ -588,6 +588,7 @@ struct lm_lockstruct { struct dlm_lksb ls_control_lksb; /* control_lock */ char ls_control_lvb[GDLM_LVB_SIZE]; /* control_lock lvb */ struct completion ls_sync_wait; /* {control,mounted}_{lock,unlock} */ + char *ls_lvb_bits; spinlock_t ls_recover_spin; /* protects following fields */ unsigned long ls_recover_flags; /* DFL_ */ diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index 9802de0f85e6..b15bb45911ca 100644 --- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c @@ -580,7 +580,6 @@ static void gfs2_control_func(struct work_struct *work) { struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_control_work.work); struct lm_lockstruct *ls = &sdp->sd_lockstruct; - char lvb_bits[GDLM_LVB_SIZE]; uint32_t block_gen, start_gen, lvb_gen, flags; int recover_set = 0; int write_lvb = 0; @@ -634,7 +633,7 @@ static void gfs2_control_func(struct work_struct *work) return; } - control_lvb_read(ls, &lvb_gen, lvb_bits); + control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits); spin_lock(&ls->ls_recover_spin); if (block_gen != ls->ls_recover_block || @@ -664,10 +663,10 @@ static void gfs2_control_func(struct work_struct *work) ls->ls_recover_result[i] = 0; - if (!test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) + if (!test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET)) continue; - __clear_bit_le(i, lvb_bits + JID_BITMAP_OFFSET); + __clear_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET); write_lvb = 1; } } @@ -691,7 +690,7 @@ static void gfs2_control_func(struct work_struct *work) continue; if (ls->ls_recover_submit[i] < start_gen) { ls->ls_recover_submit[i] = 0; - __set_bit_le(i, lvb_bits + JID_BITMAP_OFFSET); + __set_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET); } } /* even if there are no bits to set, we need to write the @@ -705,7 +704,7 @@ static void gfs2_control_func(struct work_struct *work) spin_unlock(&ls->ls_recover_spin); if (write_lvb) { - control_lvb_write(ls, start_gen, lvb_bits); + control_lvb_write(ls, start_gen, ls->ls_lvb_bits); flags = DLM_LKF_CONVERT | DLM_LKF_VALBLK; } else { flags = DLM_LKF_CONVERT; @@ -725,7 +724,7 @@ static void gfs2_control_func(struct work_struct *work) */ for (i = 0; i < recover_size; i++) { - if (test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) { + if (test_bit_le(i, ls->ls_lvb_bits + JID_BITMAP_OFFSET)) { fs_info(sdp, "recover generation %u jid %d\n", start_gen, i); gfs2_recover_set(sdp, i); @@ -758,7 +757,6 @@ static void gfs2_control_func(struct work_struct *work) static int control_mount(struct gfs2_sbd *sdp) { struct lm_lockstruct *ls = &sdp->sd_lockstruct; - char lvb_bits[GDLM_LVB_SIZE]; uint32_t start_gen, block_gen, mount_gen, lvb_gen; int mounted_mode; int retries = 0; @@ -857,7 +855,7 @@ locks_done: * lvb_gen will be non-zero. */ - control_lvb_read(ls, &lvb_gen, lvb_bits); + control_lvb_read(ls, &lvb_gen, ls->ls_lvb_bits); if (lvb_gen == 0xFFFFFFFF) { /* special value to force mount attempts to fail */ @@ -887,7 +885,7 @@ locks_done: * and all lvb bits to be clear (no pending journal recoveries.) */ - if (!all_jid_bits_clear(lvb_bits)) { + if (!all_jid_bits_clear(ls->ls_lvb_bits)) { /* journals need recovery, wait until all are clear */ fs_info(sdp, "control_mount wait for journal recovery\n"); goto restart; @@ -949,7 +947,6 @@ static int dlm_recovery_wait(void *word) static int control_first_done(struct gfs2_sbd *sdp) { struct lm_lockstruct *ls = &sdp->sd_lockstruct; - char lvb_bits[GDLM_LVB_SIZE]; uint32_t start_gen, block_gen; int error; @@ -991,8 +988,8 @@ restart: memset(ls->ls_recover_result, 0, ls->ls_recover_size*sizeof(uint32_t)); spin_unlock(&ls->ls_recover_spin); - memset(lvb_bits, 0, sizeof(lvb_bits)); - control_lvb_write(ls, start_gen, lvb_bits); + memset(ls->ls_lvb_bits, 0, GDLM_LVB_SIZE); + control_lvb_write(ls, start_gen, ls->ls_lvb_bits); error = mounted_lock(sdp, DLM_LOCK_PR, DLM_LKF_CONVERT); if (error) @@ -1022,6 +1019,12 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots, uint32_t old_size, new_size; int i, max_jid; + if (!ls->ls_lvb_bits) { + ls->ls_lvb_bits = kzalloc(GDLM_LVB_SIZE, GFP_NOFS); + if (!ls->ls_lvb_bits) + return -ENOMEM; + } + max_jid = 0; for (i = 0; i < num_slots; i++) { if (max_jid < slots[i].slot - 1) @@ -1057,6 +1060,7 @@ static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots, static void free_recover_size(struct lm_lockstruct *ls) { + kfree(ls->ls_lvb_bits); kfree(ls->ls_recover_submit); kfree(ls->ls_recover_result); ls->ls_recover_submit = NULL; @@ -1205,6 +1209,7 @@ static int gdlm_mount(struct gfs2_sbd *sdp, const char *table) ls->ls_recover_size = 0; ls->ls_recover_submit = NULL; ls->ls_recover_result = NULL; + ls->ls_lvb_bits = NULL; error = set_recover_size(sdp, NULL, 0); if (error) -- cgit v1.2.3-55-g7522 From 4146c3d469dc400eefa253fb37aa1e74fb5e41f8 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 7 Mar 2013 23:42:52 +0900 Subject: GFS2: use memchr_inv Use memchr_inv to verify that the specified memory range is cleared. Signed-off-by: Akinobu Mita Cc: Steven Whitehouse Cc: cluster-devel@redhat.com Cc: Christine Caulfield Cc: David Teigland --- fs/gfs2/lock_dlm.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c index b15bb45911ca..c8423d6de6c3 100644 --- a/fs/gfs2/lock_dlm.c +++ b/fs/gfs2/lock_dlm.c @@ -483,12 +483,8 @@ static void control_lvb_write(struct lm_lockstruct *ls, uint32_t lvb_gen, static int all_jid_bits_clear(char *lvb) { - int i; - for (i = JID_BITMAP_OFFSET; i < GDLM_LVB_SIZE; i++) { - if (lvb[i]) - return 0; - } - return 1; + return !memchr_inv(lvb + JID_BITMAP_OFFSET, 0, + GDLM_LVB_SIZE - JID_BITMAP_OFFSET); } static void sync_wait_cb(void *arg) -- cgit v1.2.3-55-g7522 From 441362d06be349430d06e37286adce4b90e6ce96 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 11 Mar 2013 23:01:37 +0800 Subject: GFS2: return error if malloc failed in gfs2_rs_alloc() The error code in gfs2_rs_alloc() is set to ENOMEM when error but never be used, instead, gfs2_rs_alloc() always return 0. Fix to return 'error'. Signed-off-by: Wei Yongjun Signed-off-by: Steven Whitehouse --- fs/gfs2/rgrp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index d1f51fd73f86..70d1cd0b5f3b 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -576,7 +576,7 @@ int gfs2_rs_alloc(struct gfs2_inode *ip) RB_CLEAR_NODE(&ip->i_res->rs_node); out: up_write(&ip->i_rw_mutex); - return 0; + return error; } static void dump_rs(struct seq_file *seq, const struct gfs2_blkreserv *rs) -- cgit v1.2.3-55-g7522 From c2952d202f710d326ac36a8ea6bd216b20615ec8 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Thu, 14 Mar 2013 15:49:59 +0000 Subject: GFS2: Fix unlock of fcntl locks during withdrawn state When withdraw occurs, we need to continue to allow unlocks of fcntl locks to occur, however these will only be local, since the node has withdrawn from the cluster. This prevents triggering a VFS level bug trap due to locks remaining when a file is closed. Signed-off-by: Steven Whitehouse --- fs/gfs2/file.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 019f45e45097..d79c2dadc536 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -923,8 +923,11 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl) cmd = F_SETLK; fl->fl_type = F_UNLCK; } - if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { + if (fl->fl_type == F_UNLCK) + posix_lock_file_wait(file, fl); return -EIO; + } if (IS_GETLK(cmd)) return dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl); else if (fl->fl_type == F_UNLCK) -- cgit v1.2.3-55-g7522 From aeb3a97222832e5457c4b72d72235098ce4bfe8d Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Thu, 4 Apr 2013 11:47:13 +0200 Subject: ALSA: hda - fix typo in proc output Rename "Digitial In" to "Digital In". This function is only used for proc output, so should not cause any problems to change. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index ecdf30eb5879..4aba7646dd9c 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -173,7 +173,7 @@ const char *snd_hda_get_jack_type(u32 cfg) "Line Out", "Speaker", "HP Out", "CD", "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand", "Line In", "Aux", "Mic", "Telephony", - "SPDIF In", "Digitial In", "Reserved", "Other" + "SPDIF In", "Digital In", "Reserved", "Other" }; return jack_types[(cfg & AC_DEFCFG_DEVICE) -- cgit v1.2.3-55-g7522 From 8fc24426f15d967d585af7062b7be3c46bbce571 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 4 Apr 2013 15:35:24 +0200 Subject: Revert "ALSA: hda - Allow power_save_controller option override DCAPS" This reverts commit 6ab317419c62850a71e2adfd1573e5ee87d8774f. The commit [6ab317419c: ALSA: hda - Allow power_save_controller option override DCAPS] changed the behavior of power_save_controller so that it can override the driver capability. This assumed that this option is rarely changed dynamically unlike power_save option. Too naive. It turned out that the user-space power-management tool tries to set power_save_controller option to 1 together with power_save option without knowing what's actually doing. This enabled forcibly the runtime PM of the controller, which is known to be broken om many chips thus disabled as default. So, the only sane fix is to revert this commit again. It was intended to ease debugging/testing for runtime PM enablement, but obviously we need another way for it. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=56171 Reported-and-tested-by: Nikita Tsukanov Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 5 ++--- sound/pci/hda/hda_intel.c | 6 ++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 4499bd948860..95731a08f257 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -890,9 +890,8 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) power_save - Automatic power-saving timeout (in second, 0 = disable) - power_save_controller - Support runtime D3 of HD-audio controller - (-1 = on for supported chip (default), false = off, - true = force to on even for unsupported hardware) + power_save_controller - Reset HD-audio controller in power-saving mode + (default = on) align_buffer_size - Force rounding of buffer/period sizes to multiples of 128 bytes. This is more efficient in terms of memory access but isn't required by the HDA spec and prevents diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 418bfc0eb0a3..bcd40ee488e3 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -134,8 +134,8 @@ MODULE_PARM_DESC(power_save, "Automatic power-saving timeout " * this may give more power-saving, but will take longer time to * wake up. */ -static int power_save_controller = -1; -module_param(power_save_controller, bint, 0644); +static bool power_save_controller = 1; +module_param(power_save_controller, bool, 0644); MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); #endif /* CONFIG_PM */ @@ -2931,8 +2931,6 @@ static int azx_runtime_idle(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip = card->private_data; - if (power_save_controller > 0) - return 0; if (!power_save_controller || !(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) return -EBUSY; -- cgit v1.2.3-55-g7522 From b6a9b7f6b1f21735a7456d534dc0e68e61359d2c Mon Sep 17 00:00:00 2001 From: Jan Stancek Date: Thu, 4 Apr 2013 11:35:10 -0700 Subject: mm: prevent mmap_cache race in find_vma() find_vma() can be called by multiple threads with read lock held on mm->mmap_sem and any of them can update mm->mmap_cache. Prevent compiler from re-fetching mm->mmap_cache, because other readers could update it in the meantime: thread 1 thread 2 | find_vma() | find_vma() struct vm_area_struct *vma = NULL; | vma = mm->mmap_cache; | if (!(vma && vma->vm_end > addr | && vma->vm_start <= addr)) { | | mm->mmap_cache = vma; return vma; | ^^ compiler may optimize this | local variable out and re-read | mm->mmap_cache | This issue can be reproduced with gcc-4.8.0-1 on s390x by running mallocstress testcase from LTP, which triggers: kernel BUG at mm/rmap.c:1088! Call Trace: ([<000003d100c57000>] 0x3d100c57000) [<000000000023a1c0>] do_wp_page+0x2fc/0xa88 [<000000000023baae>] handle_pte_fault+0x41a/0xac8 [<000000000023d832>] handle_mm_fault+0x17a/0x268 [<000000000060507a>] do_protection_exception+0x1e2/0x394 [<0000000000603a04>] pgm_check_handler+0x138/0x13c [<000003fffcf1f07a>] 0x3fffcf1f07a Last Breaking-Event-Address: [<000000000024755e>] page_add_new_anon_rmap+0xc2/0x168 Thanks to Jakub Jelinek for his insight on gcc and helping to track this down. Signed-off-by: Jan Stancek Acked-by: David Rientjes Signed-off-by: Hugh Dickins Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds --- mm/mmap.c | 2 +- mm/nommu.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/mmap.c b/mm/mmap.c index 6466699b16cb..0db0de1c2fbe 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1940,7 +1940,7 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr) /* Check the cache first. */ /* (Cache hit rate is typically around 35%.) */ - vma = mm->mmap_cache; + vma = ACCESS_ONCE(mm->mmap_cache); if (!(vma && vma->vm_end > addr && vma->vm_start <= addr)) { struct rb_node *rb_node; diff --git a/mm/nommu.c b/mm/nommu.c index e19328087534..2f3ea749c318 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -821,7 +821,7 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr) struct vm_area_struct *vma; /* check the cache first */ - vma = mm->mmap_cache; + vma = ACCESS_ONCE(mm->mmap_cache); if (vma && vma->vm_start <= addr && vma->vm_end > addr) return vma; -- cgit v1.2.3-55-g7522 From e2409d83434d77874b461b78af6a19cd6e6a1280 Mon Sep 17 00:00:00 2001 From: hayeswang Date: Sun, 31 Mar 2013 17:02:04 +0000 Subject: r8169: fix auto speed down issue It would cause no link after suspending or shutdowning when the nic changes the speed to 10M and connects to a link partner which forces the speed to 100M. Check the link partner ability to determine which speed to set. Signed-off-by: Hayes Wang Acked-by: Francois Romieu Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 28fb50a1e9c3..4ecbe64a758d 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3818,6 +3818,30 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp) } } +static void rtl_speed_down(struct rtl8169_private *tp) +{ + u32 adv; + int lpa; + + rtl_writephy(tp, 0x1f, 0x0000); + lpa = rtl_readphy(tp, MII_LPA); + + if (lpa & (LPA_10HALF | LPA_10FULL)) + adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; + else if (lpa & (LPA_100HALF | LPA_100FULL)) + adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; + else + adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | + (tp->mii.supports_gmii ? + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full : 0); + + rtl8169_set_speed(tp->dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL, + adv); +} + static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -3848,9 +3872,7 @@ static bool rtl_wol_pll_power_down(struct rtl8169_private *tp) if (!(__rtl8169_get_wol(tp) & WAKE_ANY)) return false; - rtl_writephy(tp, 0x1f, 0x0000); - rtl_writephy(tp, MII_BMCR, 0x0000); - + rtl_speed_down(tp); rtl_wol_suspend_quirk(tp); return true; -- cgit v1.2.3-55-g7522 From 4543fbefe6e06a9e40d9f2b28d688393a299f079 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Tue, 2 Apr 2013 17:10:07 -0400 Subject: net: count hw_addr syncs so that unsync works properly. A few drivers use dev_uc_sync/unsync to synchronize the address lists from master down to slave/lower devices. In some cases (bond/team) a single address list is synched down to multiple devices. At the time of unsync, we have a leak in these lower devices, because "synced" is treated as a boolean and the address will not be unsynced for anything after the first device/call. Treat "synced" as a count (same as refcount) and allow all unsync calls to work. Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- include/linux/netdevice.h | 2 +- net/core/dev_addr_lists.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 8bfa95600e48..6151e903eef0 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -210,9 +210,9 @@ struct netdev_hw_addr { #define NETDEV_HW_ADDR_T_SLAVE 3 #define NETDEV_HW_ADDR_T_UNICAST 4 #define NETDEV_HW_ADDR_T_MULTICAST 5 - bool synced; bool global_use; int refcount; + int synced; struct rcu_head rcu_head; }; diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index bd2eb9d3e369..abdc9e6ef33e 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -37,7 +37,7 @@ static int __hw_addr_create_ex(struct netdev_hw_addr_list *list, ha->type = addr_type; ha->refcount = 1; ha->global_use = global; - ha->synced = false; + ha->synced = 0; list_add_tail_rcu(&ha->list, &list->list); list->count++; @@ -165,7 +165,7 @@ int __hw_addr_sync(struct netdev_hw_addr_list *to_list, addr_len, ha->type); if (err) break; - ha->synced = true; + ha->synced++; ha->refcount++; } else if (ha->refcount == 1) { __hw_addr_del(to_list, ha->addr, addr_len, ha->type); @@ -186,7 +186,7 @@ void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, if (ha->synced) { __hw_addr_del(to_list, ha->addr, addr_len, ha->type); - ha->synced = false; + ha->synced--; __hw_addr_del(from_list, ha->addr, addr_len, ha->type); } -- cgit v1.2.3-55-g7522 From 31d1670e73f4911fe401273a8f576edc9c2b5fea Mon Sep 17 00:00:00 2001 From: Hannes Frederic Sowa Date: Tue, 2 Apr 2013 14:36:46 +0000 Subject: atl1e: limit gso segment size to prevent generation of wrong ip length fields The limit of 0x3c00 is taken from the windows driver. Suggested-by: Huang, Xiong Cc: Huang, Xiong Cc: Eric Dumazet Signed-off-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- drivers/net/ethernet/atheros/atl1e/atl1e.h | 2 +- drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e.h b/drivers/net/ethernet/atheros/atl1e/atl1e.h index edfdf6b950e7..b5fd934585e9 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e.h +++ b/drivers/net/ethernet/atheros/atl1e/atl1e.h @@ -186,7 +186,7 @@ struct atl1e_tpd_desc { /* how about 0x2000 */ #define MAX_TX_BUF_LEN 0x2000 #define MAX_TX_BUF_SHIFT 13 -/*#define MAX_TX_BUF_LEN 0x3000 */ +#define MAX_TSO_SEG_SIZE 0x3c00 /* rrs word 1 bit 0:31 */ #define RRS_RX_CSUM_MASK 0xFFFF diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index f73d5609439a..ac25f05ff68f 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -2329,6 +2329,7 @@ static int atl1e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) INIT_WORK(&adapter->reset_task, atl1e_reset_task); INIT_WORK(&adapter->link_chg_task, atl1e_link_chg_task); + netif_set_gso_max_size(netdev, MAX_TSO_SEG_SIZE); err = register_netdev(netdev); if (err) { netdev_err(netdev, "register netdevice failed\n"); -- cgit v1.2.3-55-g7522 From 4de79c737b200492195ebc54a887075327e1ec1d Mon Sep 17 00:00:00 2001 From: Veaceslav Falico Date: Wed, 3 Apr 2013 05:46:33 +0000 Subject: bonding: remove sysfs before removing devices We have a race condition if we try to rmmod bonding and simultaneously add a bond master through sysfs. In bonding_exit() we first remove the devices (through rtnl_link_unregister() ) and only after that we remove the sysfs. If we manage to add a device through sysfs after that the devices were removed - we'll end up with that device/sysfs structure and with the module unloaded. Fix this by first removing the sysfs and only after that calling rtnl_link_unregister(). Signed-off-by: Veaceslav Falico Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index a51241b2e621..171b10f167a5 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4902,8 +4902,8 @@ static void __exit bonding_exit(void) bond_destroy_debugfs(); - rtnl_link_unregister(&bond_link_ops); unregister_pernet_subsys(&bond_net_ops); + rtnl_link_unregister(&bond_link_ops); #ifdef CONFIG_NET_POLL_CONTROLLER /* -- cgit v1.2.3-55-g7522 From 25da0e3e9d3fb2b522bc2a598076735850310eb1 Mon Sep 17 00:00:00 2001 From: Eric W. Biederman Date: Wed, 3 Apr 2013 16:13:35 +0000 Subject: Revert "af_unix: dont send SCM_CREDENTIAL when dest socket is NULL" This reverts commit 14134f6584212d585b310ce95428014b653dfaf6. The problem that the above patch was meant to address is that af_unix messages are not being coallesced because we are sending unnecesarry credentials. Not sending credentials in maybe_add_creds totally breaks unconnected unix domain sockets that wish to send credentails to other sockets. In practice this break some versions of udev because they receive a message and the sending uid is bogus so they drop the message. Reported-by: Sven Joachim Signed-off-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/unix/af_unix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 971282b6f6a3..f153a8d6e339 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1412,8 +1412,8 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, if (UNIXCB(skb).cred) return; if (test_bit(SOCK_PASSCRED, &sock->flags) || - (other->sk_socket && - test_bit(SOCK_PASSCRED, &other->sk_socket->flags))) { + !other->sk_socket || + test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { UNIXCB(skb).pid = get_pid(task_tgid(current)); UNIXCB(skb).cred = get_current_cred(); } -- cgit v1.2.3-55-g7522 From 0e82e7f6dfeec1013339612f74abc2cdd29d43d2 Mon Sep 17 00:00:00 2001 From: Eric W. Biederman Date: Wed, 3 Apr 2013 16:14:47 +0000 Subject: af_unix: If we don't care about credentials coallesce all messages It was reported that the following LSB test case failed https://lsbbugs.linuxfoundation.org/attachment.cgi?id=2144 because we were not coallescing unix stream messages when the application was expecting us to. The problem was that the first send was before the socket was accepted and thus sock->sk_socket was NULL in maybe_add_creds, and the second send after the socket was accepted had a non-NULL value for sk->socket and thus we could tell the credentials were not needed so we did not bother. The unnecessary credentials on the first message cause unix_stream_recvmsg to start verifying that all messages had the same credentials before coallescing and then the coallescing failed because the second message had no credentials. Ignoring credentials when we don't care in unix_stream_recvmsg fixes a long standing pessimization which would fail to coallesce messages when reading from a unix stream socket if the senders were different even if we did not care about their credentials. I have tested this and verified that the in the LSB test case mentioned above that the messages do coallesce now, while the were failing to coallesce without this change. Reported-by: Karel Srot Reported-by: Ding Tianhong Signed-off-by: "Eric W. Biederman" Signed-off-by: David S. Miller --- net/unix/af_unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index f153a8d6e339..2db702d82e7d 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1993,7 +1993,7 @@ again: if ((UNIXCB(skb).pid != siocb->scm->pid) || (UNIXCB(skb).cred != siocb->scm->cred)) break; - } else { + } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { /* Copy credentials */ scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); check_creds = 1; -- cgit v1.2.3-55-g7522 From f01fc1a82c2ee68726b400fadb156bd623b5f2f1 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Wed, 3 Apr 2013 16:50:54 +0000 Subject: ixgbe: fix registration order of driver and DCA nofitication ixgbe_notify_dca cannot be called before driver registration because it expects driver's klist_devices to be allocated and initialized. While on it make sure debugfs files are removed when registration fails. Cc: stable Signed-off-by: Jakub Kicinski Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index db5611ae407e..79f4a26ea6cc 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -7922,12 +7922,19 @@ static int __init ixgbe_init_module(void) ixgbe_dbg_init(); #endif /* CONFIG_DEBUG_FS */ + ret = pci_register_driver(&ixgbe_driver); + if (ret) { +#ifdef CONFIG_DEBUG_FS + ixgbe_dbg_exit(); +#endif /* CONFIG_DEBUG_FS */ + return ret; + } + #ifdef CONFIG_IXGBE_DCA dca_register_notify(&dca_notifier); #endif - ret = pci_register_driver(&ixgbe_driver); - return ret; + return 0; } module_init(ixgbe_init_module); -- cgit v1.2.3-55-g7522 From 34e2ed34a035de07277cca817fe8264324398141 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 4 Apr 2013 08:33:00 +0000 Subject: net: ipv4: notify when address lifetime changes if userspace changes lifetime of address, send netlink notification and call notifier. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/ipv4/devinet.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index f678507bc829..96083b7a436b 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -802,8 +802,10 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg if (nlh->nlmsg_flags & NLM_F_EXCL || !(nlh->nlmsg_flags & NLM_F_REPLACE)) return -EEXIST; - - set_ifa_lifetime(ifa_existing, valid_lft, prefered_lft); + ifa = ifa_existing; + set_ifa_lifetime(ifa, valid_lft, prefered_lft); + rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid); + blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); } return 0; } -- cgit v1.2.3-55-g7522 From 868211db6df96ddae411fcd800502725beef8387 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 4 Apr 2013 22:32:10 +0200 Subject: ALSA: hda/generic - fix uninitialized variable changed is not initialized in path_power_down_sync, but it is expected to be false in case no change happened in the loop. So set it to false. Signed-off-by: Jiri Slaby Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 43c2ea539561..2dbe767be16b 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -740,7 +740,7 @@ EXPORT_SYMBOL_HDA(snd_hda_activate_path); static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path) { struct hda_gen_spec *spec = codec->spec; - bool changed; + bool changed = false; int i; if (!spec->power_down_unused || path->active) -- cgit v1.2.3-55-g7522 From ad8c396936e328f5344e1881afde9e28d5f2045f Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 2 Apr 2013 22:59:29 +0000 Subject: MIPS: Unbreak function tracer for 64-bit kernel. Commit 58b69401c797 [MIPS: Function tracer: Fix broken function tracing] completely broke the function tracer for 64-bit kernels. The symptom is a system hang very early in the boot process. The fix: Remove/fix $sp adjustments for 64-bit case. Signed-off-by: David Daney Cc: linux-mips@linux-mips.org Cc: Al Cooper Cc: viric@viric.name Cc: stable@vger.kernel.org # 3.8.x Signed-off-by: Ralf Baechle --- arch/mips/kernel/mcount.S | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index 165867673357..33d067148e61 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S @@ -46,10 +46,9 @@ PTR_L a5, PT_R9(sp) PTR_L a6, PT_R10(sp) PTR_L a7, PT_R11(sp) -#else - PTR_ADDIU sp, PT_SIZE #endif -.endm + PTR_ADDIU sp, PT_SIZE + .endm .macro RETURN_BACK jr ra @@ -68,7 +67,11 @@ NESTED(ftrace_caller, PT_SIZE, ra) .globl _mcount _mcount: b ftrace_stub - addiu sp,sp,8 +#ifdef CONFIG_32BIT + addiu sp,sp,8 +#else + nop +#endif /* When tracing is activated, it calls ftrace_caller+8 (aka here) */ lw t1, function_trace_stop -- cgit v1.2.3-55-g7522 From 143f0f659986f921731ab340d9415be479762c1a Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 4 Apr 2013 12:47:01 +0000 Subject: MIPS: Alchemy: Fix typo "CONFIG_DEBUG_PCI" Commit 7517de348663b08a808aff44b5300e817157a568 ("MIPS: Alchemy: Redo PCI as platform driver") added a reference to CONFIG_DEBUG_PCI. Change it to CONFIG_PCI_DEBUG, as that is a valid Kconfig macro. Also add a newline to a debugging printk that this fix enables. Signed-off-by: Paul Bolle Cc: Sergei Shtylyov Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Ralf Baechle --- arch/mips/pci/pci-alchemy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c index 38a80c83fd67..d1faece21b6a 100644 --- a/arch/mips/pci/pci-alchemy.c +++ b/arch/mips/pci/pci-alchemy.c @@ -19,7 +19,7 @@ #include #include -#ifdef CONFIG_DEBUG_PCI +#ifdef CONFIG_PCI_DEBUG #define DBG(x...) printk(KERN_DEBUG x) #else #define DBG(x...) do {} while (0) @@ -162,7 +162,7 @@ static int config_access(unsigned char access_type, struct pci_bus *bus, if (status & (1 << 29)) { *data = 0xffffffff; error = -1; - DBG("alchemy-pci: master abort on cfg access %d bus %d dev %d", + DBG("alchemy-pci: master abort on cfg access %d bus %d dev %d\n", access_type, bus->number, device); } else if ((status >> 28) & 0xf) { DBG("alchemy-pci: PCI ERR detected: dev %d, status %lx\n", -- cgit v1.2.3-55-g7522 From aaa9fad32fa80878e6935c5668098c9b55b31458 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Mon, 25 Mar 2013 09:39:54 +0000 Subject: MIPS: Kconfig: Rename SNIPROM too CONFIG_SNIPROM was renamed to CONFIG_FW_SNIPROM in v3.8. Let's rename SNIPROM itself too. Signed-off-by: Paul Bolle Cc: linux-mips@linux-mips.org; Cc: linux-kernel@vger.kernel.org Cc: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- arch/mips/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index cd2e21ff562a..b2df47604759 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -657,7 +657,7 @@ config SNI_RM bool "SNI RM200/300/400" select FW_ARC if CPU_LITTLE_ENDIAN select FW_ARC32 if CPU_LITTLE_ENDIAN - select SNIPROM if CPU_BIG_ENDIAN + select FW_SNIPROM if CPU_BIG_ENDIAN select ARCH_MAY_HAVE_PC_FDC select BOOT_ELF32 select CEVT_R4K @@ -1144,7 +1144,7 @@ config DEFAULT_SGI_PARTITION config FW_ARC32 bool -config SNIPROM +config FW_SNIPROM bool config BOOT_ELF32 -- cgit v1.2.3-55-g7522 From ed1197f9317c960a199f491779e056c572506dd3 Mon Sep 17 00:00:00 2001 From: EunBong Song Date: Sun, 24 Mar 2013 22:18:35 +0000 Subject: MIPS: Fix build error cavium-octeon without CONFIG_SMP Singed-off-by: EunBong Song Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Ralf Baechle --- arch/mips/cavium-octeon/setup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index c594a3d4f743..b0baa299f899 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c @@ -174,7 +174,10 @@ static int octeon_kexec_prepare(struct kimage *image) static void octeon_generic_shutdown(void) { - int cpu, i; + int i; +#ifdef CONFIG_SMP + int cpu; +#endif struct cvmx_bootmem_desc *bootmem_desc; void *named_block_array_ptr; -- cgit v1.2.3-55-g7522 From adb3789264c4e8567113a0e764ad30ce6e8737f3 Mon Sep 17 00:00:00 2001 From: Deng-Cheng Zhu Date: Mon, 1 Apr 2013 18:14:28 +0000 Subject: MIPS: Fix ISA level which causes secondary cache init bypassing and more The commit a96102be70 introduced set_isa() where compatible ISA info is also set aside from the one gets passed in. It means, for example, 1004K will have MIPS_CPU_ISA_M32R2/M32R1/II/I flags. This leads to things like the following inappropriate: if (c->isa_level == MIPS_CPU_ISA_M32R1 || c->isa_level == MIPS_CPU_ISA_M32R2 || c->isa_level == MIPS_CPU_ISA_M64R1 || c->isa_level == MIPS_CPU_ISA_M64R2) This patch fixes it. Signed-off-by: Deng-Cheng Zhu Cc: Steven J. Hill Cc: linux-mips@linux-mips.org Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-probe.c | 6 ++---- arch/mips/kernel/traps.c | 2 +- arch/mips/mm/c-r4k.c | 6 ++---- arch/mips/mm/sc-mips.c | 6 ++---- 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 6bfccc227a95..ed80c3844345 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -1226,10 +1226,8 @@ __cpuinit void cpu_probe(void) if (c->options & MIPS_CPU_FPU) { c->fpu_id = cpu_get_fpu_id(); - if (c->isa_level == MIPS_CPU_ISA_M32R1 || - c->isa_level == MIPS_CPU_ISA_M32R2 || - c->isa_level == MIPS_CPU_ISA_M64R1 || - c->isa_level == MIPS_CPU_ISA_M64R2) { + if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | + MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { if (c->fpu_id & MIPS_FPIR_3D) c->ases |= MIPS_ASE_MIPS3D; } diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index a200b5bdbb87..c3abb88170fc 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -1571,7 +1571,7 @@ void __cpuinit per_cpu_trap_init(bool is_boot_cpu) #ifdef CONFIG_64BIT status_set |= ST0_FR|ST0_KX|ST0_SX|ST0_UX; #endif - if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) + if (current_cpu_data.isa_level & MIPS_CPU_ISA_IV) status_set |= ST0_XX; if (cpu_has_dsp) status_set |= ST0_MX; diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index ecca559b8d7b..2078915eacb9 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1247,10 +1247,8 @@ static void __cpuinit setup_scache(void) return; default: - if (c->isa_level == MIPS_CPU_ISA_M32R1 || - c->isa_level == MIPS_CPU_ISA_M32R2 || - c->isa_level == MIPS_CPU_ISA_M64R1 || - c->isa_level == MIPS_CPU_ISA_M64R2) { + if (c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | + MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2)) { #ifdef CONFIG_MIPS_CPU_SCACHE if (mips_sc_init ()) { scache_size = c->scache.ways * c->scache.sets * c->scache.linesz; diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c index 93d937b4b1ba..df96da7e939b 100644 --- a/arch/mips/mm/sc-mips.c +++ b/arch/mips/mm/sc-mips.c @@ -98,10 +98,8 @@ static inline int __init mips_sc_probe(void) c->scache.flags |= MIPS_CACHE_NOT_PRESENT; /* Ignore anything but MIPSxx processors */ - if (c->isa_level != MIPS_CPU_ISA_M32R1 && - c->isa_level != MIPS_CPU_ISA_M32R2 && - c->isa_level != MIPS_CPU_ISA_M64R1 && - c->isa_level != MIPS_CPU_ISA_M64R2) + if (!(c->isa_level & (MIPS_CPU_ISA_M32R1 | MIPS_CPU_ISA_M32R2 | + MIPS_CPU_ISA_M64R1 | MIPS_CPU_ISA_M64R2))) return 0; /* Does this MIPS32/MIPS64 CPU have a config2 register? */ -- cgit v1.2.3-55-g7522 From 80fa8181aabeb10389c8810f97e2737eb084ce8f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 25 Mar 2013 13:43:14 +0100 Subject: MIPS: Delete definition of SA_RESTORER. SA_RESTORER used to be defined as 0x04000000 but only the O32 ABI ever supported its use and no libc was using it, so the entire sa-restorer functionality was removed with lmo commit 39bffc12c3580ab [Zap sa_restorer.] for 2.5.48 retaining only the SA_RESTORER definition as a reminder to avoid accidental reuse of the mask bit. Upstream cdef9602fbf1871a43f0f1b5cea10dd0f275167d [signal: always clear sa_restorer on execve] adds code that assumes sa_sigaction has an sa_restorer field, if SA_RESTORER is defined which would break MIPS. So remove the SA_RESTORER definition before the v3.8.4 merge. Signed-off-by: Ralf Baechle (cherry picked from commit 17da8d63add23830892ac4dc2cbb3b5d4ffb79a8) --- arch/mips/include/uapi/asm/signal.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/mips/include/uapi/asm/signal.h b/arch/mips/include/uapi/asm/signal.h index d6b18b4d0f3a..addb9f556b71 100644 --- a/arch/mips/include/uapi/asm/signal.h +++ b/arch/mips/include/uapi/asm/signal.h @@ -72,6 +72,12 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */ * * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single * Unix names RESETHAND and NODEFER respectively. + * + * SA_RESTORER used to be defined as 0x04000000 but only the O32 ABI ever + * supported its use and no libc was using it, so the entire sa-restorer + * functionality was removed with lmo commit 39bffc12c3580ab for 2.5.48 + * retaining only the SA_RESTORER definition as a reminder to avoid + * accidental reuse of the mask bit. */ #define SA_ONSTACK 0x08000000 #define SA_RESETHAND 0x80000000 @@ -84,8 +90,6 @@ typedef unsigned long old_sigset_t; /* at least 32 bits */ #define SA_NOMASK SA_NODEFER #define SA_ONESHOT SA_RESETHAND -#define SA_RESTORER 0x04000000 /* Only for o32 */ - #define MINSIGSTKSZ 2048 #define SIGSTKSZ 8192 -- cgit v1.2.3-55-g7522 From b844fe691897221ad0d5e0279c8ea9e3e4a46982 Mon Sep 17 00:00:00 2001 From: Darrick J. Wong Date: Fri, 5 Apr 2013 15:36:32 +0100 Subject: dm cache: fix writes to cache device in writethrough mode The dm-cache writethrough strategy introduced by commit e2e74d617eadc15 ("dm cache: fix race in writethrough implementation") issues a bio to the origin device, remaps and then issues the bio to the cache device. This more conservative in-series approach was selected to favor correctness over performance (of the previous parallel writethrough). However, this in-series implementation that reuses the same bio to write both the origin and cache device didn't take into account that the block layer's req_bio_endio() modifies a completing bio's bi_sector and bi_size. So the new writethrough strategy needs to preserve these bio fields, and restore them before submission to the cache device, otherwise nothing gets written to the cache (because bi_size is 0). This patch adds a struct dm_bio_details field to struct per_bio_data, and uses dm_bio_record() and dm_bio_restore() to ensure the bio is restored before reissuing to the cache device. Adding such a large structure to the per_bio_data is not ideal but we can improve this later, for now correctness is the important thing. This problem initially went unnoticed because the dm-cache test-suite uses a linear DM device for the dm-cache device's origin device. Writethrough worked as expected because DM submits a *clone* of the original bio, so the original bio which was reused for the cache was never touched. Signed-off-by: Darrick J. Wong Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon --- drivers/md/dm-cache-target.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 66120bd46d15..1ab122a75764 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -6,6 +6,7 @@ #include "dm.h" #include "dm-bio-prison.h" +#include "dm-bio-record.h" #include "dm-cache-metadata.h" #include @@ -205,6 +206,7 @@ struct per_bio_data { struct cache *cache; dm_cblock_t cblock; bio_end_io_t *saved_bi_end_io; + struct dm_bio_details bio_details; }; struct dm_cache_migration { @@ -643,6 +645,7 @@ static void writethrough_endio(struct bio *bio, int err) return; } + dm_bio_restore(&pb->bio_details, bio); remap_to_cache(pb->cache, bio, pb->cblock); /* @@ -667,6 +670,7 @@ static void remap_to_origin_then_cache(struct cache *cache, struct bio *bio, pb->cache = cache; pb->cblock = cblock; pb->saved_bi_end_io = bio->bi_end_io; + dm_bio_record(&pb->bio_details, bio); bio->bi_end_io = writethrough_endio; remap_to_origin_clear_discard(pb->cache, bio, oblock); -- cgit v1.2.3-55-g7522 From 19b0092e265fe9ab129902373c3127c0e0be3376 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Fri, 5 Apr 2013 15:36:34 +0100 Subject: dm cache: reduce bio front_pad size in writeback mode A recent patch to fix the dm cache target's writethrough mode extended the bio's front_pad to include a 1056-byte struct dm_bio_details. Writeback mode doesn't need this, so this patch reduces the per_bio_data_size to 16 bytes in this case instead of 1096. The dm_bio_details structure was added in "dm cache: fix writes to cache device in writethrough mode" which fixed commit e2e74d617e ("dm cache: fix race in writethrough implementation"). In writeback mode we avoid allocating the writethrough-specific members of the per_bio_data structure (the dm_bio_details structure included). Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon --- drivers/md/dm-cache-target.c | 47 ++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 1ab122a75764..10744091e6ca 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -202,7 +202,11 @@ struct per_bio_data { unsigned req_nr:2; struct dm_deferred_entry *all_io_entry; - /* writethrough fields */ + /* + * writethrough fields. These MUST remain at the end of this + * structure and the 'cache' member must be the first as it + * is used to determine the offsetof the writethrough fields. + */ struct cache *cache; dm_cblock_t cblock; bio_end_io_t *saved_bi_end_io; @@ -515,16 +519,28 @@ static void save_stats(struct cache *cache) /*---------------------------------------------------------------- * Per bio data *--------------------------------------------------------------*/ -static struct per_bio_data *get_per_bio_data(struct bio *bio) + +/* + * If using writeback, leave out struct per_bio_data's writethrough fields. + */ +#define PB_DATA_SIZE_WB (offsetof(struct per_bio_data, cache)) +#define PB_DATA_SIZE_WT (sizeof(struct per_bio_data)) + +static size_t get_per_bio_data_size(struct cache *cache) +{ + return cache->features.write_through ? PB_DATA_SIZE_WT : PB_DATA_SIZE_WB; +} + +static struct per_bio_data *get_per_bio_data(struct bio *bio, size_t data_size) { - struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); + struct per_bio_data *pb = dm_per_bio_data(bio, data_size); BUG_ON(!pb); return pb; } -static struct per_bio_data *init_per_bio_data(struct bio *bio) +static struct per_bio_data *init_per_bio_data(struct bio *bio, size_t data_size) { - struct per_bio_data *pb = get_per_bio_data(bio); + struct per_bio_data *pb = get_per_bio_data(bio, data_size); pb->tick = false; pb->req_nr = dm_bio_get_target_bio_nr(bio); @@ -558,7 +574,8 @@ static void remap_to_cache(struct cache *cache, struct bio *bio, static void check_if_tick_bio_needed(struct cache *cache, struct bio *bio) { unsigned long flags; - struct per_bio_data *pb = get_per_bio_data(bio); + size_t pb_data_size = get_per_bio_data_size(cache); + struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); spin_lock_irqsave(&cache->lock, flags); if (cache->need_tick_bio && @@ -637,7 +654,7 @@ static void defer_writethrough_bio(struct cache *cache, struct bio *bio) static void writethrough_endio(struct bio *bio, int err) { - struct per_bio_data *pb = get_per_bio_data(bio); + struct per_bio_data *pb = get_per_bio_data(bio, PB_DATA_SIZE_WT); bio->bi_end_io = pb->saved_bi_end_io; if (err) { @@ -665,7 +682,7 @@ static void writethrough_endio(struct bio *bio, int err) static void remap_to_origin_then_cache(struct cache *cache, struct bio *bio, dm_oblock_t oblock, dm_cblock_t cblock) { - struct per_bio_data *pb = get_per_bio_data(bio); + struct per_bio_data *pb = get_per_bio_data(bio, PB_DATA_SIZE_WT); pb->cache = cache; pb->cblock = cblock; @@ -1039,7 +1056,8 @@ static void defer_bio(struct cache *cache, struct bio *bio) static void process_flush_bio(struct cache *cache, struct bio *bio) { - struct per_bio_data *pb = get_per_bio_data(bio); + size_t pb_data_size = get_per_bio_data_size(cache); + struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); BUG_ON(bio->bi_size); if (!pb->req_nr) @@ -1111,7 +1129,8 @@ static void process_bio(struct cache *cache, struct prealloc *structs, dm_oblock_t block = get_bio_block(cache, bio); struct dm_bio_prison_cell *cell_prealloc, *old_ocell, *new_ocell; struct policy_result lookup_result; - struct per_bio_data *pb = get_per_bio_data(bio); + size_t pb_data_size = get_per_bio_data_size(cache); + struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); bool discarded_block = is_discarded_oblock(cache, block); bool can_migrate = discarded_block || spare_migration_bandwidth(cache); @@ -1885,7 +1904,6 @@ static int cache_create(struct cache_args *ca, struct cache **result) cache->ti = ca->ti; ti->private = cache; - ti->per_bio_data_size = sizeof(struct per_bio_data); ti->num_flush_bios = 2; ti->flush_supported = true; @@ -1894,6 +1912,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) ti->discard_zeroes_data_unsupported = true; memcpy(&cache->features, &ca->features, sizeof(cache->features)); + ti->per_bio_data_size = get_per_bio_data_size(cache); cache->callbacks.congested_fn = cache_is_congested; dm_table_add_target_callbacks(ti->table, &cache->callbacks); @@ -2096,6 +2115,7 @@ static int cache_map(struct dm_target *ti, struct bio *bio) int r; dm_oblock_t block = get_bio_block(cache, bio); + size_t pb_data_size = get_per_bio_data_size(cache); bool can_migrate = false; bool discarded_block; struct dm_bio_prison_cell *cell; @@ -2112,7 +2132,7 @@ static int cache_map(struct dm_target *ti, struct bio *bio) return DM_MAPIO_REMAPPED; } - pb = init_per_bio_data(bio); + pb = init_per_bio_data(bio, pb_data_size); if (bio->bi_rw & (REQ_FLUSH | REQ_FUA | REQ_DISCARD)) { defer_bio(cache, bio); @@ -2197,7 +2217,8 @@ static int cache_end_io(struct dm_target *ti, struct bio *bio, int error) { struct cache *cache = ti->private; unsigned long flags; - struct per_bio_data *pb = get_per_bio_data(bio); + size_t pb_data_size = get_per_bio_data_size(cache); + struct per_bio_data *pb = get_per_bio_data(bio, pb_data_size); if (pb->tick) { policy_tick(cache->policy); -- cgit v1.2.3-55-g7522 From e24b0bfa2f0446ffaad2661040be23668133aef8 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 5 Apr 2013 18:16:34 +0200 Subject: Revert "drivers/rtc/rtc-at91rm9200.c: use a variable for storing IMR" This reverts commit 0ef1594c017521ea89278e80fe3f80dafb17abde. This patch introduced a few races which cannot be easily fixed with a small follow-up patch. Furthermore, the SoC with the broken hardware register, which this patch intended to add support for, can only be used with device trees, which this driver currently does not support. [ Here is the discussion that led to this "revert" patch: https://lkml.org/lkml/2013/4/3/176 ] Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Nicolas Ferre Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-at91rm9200.c | 50 +++++++++++++++++--------------------------- drivers/rtc/rtc-at91rm9200.h | 1 + 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/drivers/rtc/rtc-at91rm9200.c b/drivers/rtc/rtc-at91rm9200.c index 0a9f27e094ea..434ebc3a99dc 100644 --- a/drivers/rtc/rtc-at91rm9200.c +++ b/drivers/rtc/rtc-at91rm9200.c @@ -44,7 +44,6 @@ static DECLARE_COMPLETION(at91_rtc_updated); static unsigned int at91_alarm_year = AT91_RTC_EPOCH; static void __iomem *at91_rtc_regs; static int irq; -static u32 at91_rtc_imr; /* * Decode time/date into rtc_time structure @@ -109,11 +108,9 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) cr = at91_rtc_read(AT91_RTC_CR); at91_rtc_write(AT91_RTC_CR, cr | AT91_RTC_UPDCAL | AT91_RTC_UPDTIM); - at91_rtc_imr |= AT91_RTC_ACKUPD; at91_rtc_write(AT91_RTC_IER, AT91_RTC_ACKUPD); wait_for_completion(&at91_rtc_updated); /* wait for ACKUPD interrupt */ at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD); - at91_rtc_imr &= ~AT91_RTC_ACKUPD; at91_rtc_write(AT91_RTC_TIMR, bin2bcd(tm->tm_sec) << 0 @@ -145,7 +142,7 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); tm->tm_year = at91_alarm_year - 1900; - alrm->enabled = (at91_rtc_imr & AT91_RTC_ALARM) + alrm->enabled = (at91_rtc_read(AT91_RTC_IMR) & AT91_RTC_ALARM) ? 1 : 0; dev_dbg(dev, "%s(): %4d-%02d-%02d %02d:%02d:%02d\n", __func__, @@ -171,7 +168,6 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) tm.tm_sec = alrm->time.tm_sec; at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM); - at91_rtc_imr &= ~AT91_RTC_ALARM; at91_rtc_write(AT91_RTC_TIMALR, bin2bcd(tm.tm_sec) << 0 | bin2bcd(tm.tm_min) << 8 @@ -184,7 +180,6 @@ static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) if (alrm->enabled) { at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); - at91_rtc_imr |= AT91_RTC_ALARM; at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); } @@ -201,12 +196,9 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) if (enabled) { at91_rtc_write(AT91_RTC_SCCR, AT91_RTC_ALARM); - at91_rtc_imr |= AT91_RTC_ALARM; at91_rtc_write(AT91_RTC_IER, AT91_RTC_ALARM); - } else { + } else at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ALARM); - at91_rtc_imr &= ~AT91_RTC_ALARM; - } return 0; } @@ -215,10 +207,12 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) */ static int at91_rtc_proc(struct device *dev, struct seq_file *seq) { + unsigned long imr = at91_rtc_read(AT91_RTC_IMR); + seq_printf(seq, "update_IRQ\t: %s\n", - (at91_rtc_imr & AT91_RTC_ACKUPD) ? "yes" : "no"); + (imr & AT91_RTC_ACKUPD) ? "yes" : "no"); seq_printf(seq, "periodic_IRQ\t: %s\n", - (at91_rtc_imr & AT91_RTC_SECEV) ? "yes" : "no"); + (imr & AT91_RTC_SECEV) ? "yes" : "no"); return 0; } @@ -233,7 +227,7 @@ static irqreturn_t at91_rtc_interrupt(int irq, void *dev_id) unsigned int rtsr; unsigned long events = 0; - rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_imr; + rtsr = at91_rtc_read(AT91_RTC_SR) & at91_rtc_read(AT91_RTC_IMR); if (rtsr) { /* this interrupt is shared! Is it ours? */ if (rtsr & AT91_RTC_ALARM) events |= (RTC_AF | RTC_IRQF); @@ -297,7 +291,6 @@ static int __init at91_rtc_probe(struct platform_device *pdev) at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | AT91_RTC_SECEV | AT91_RTC_TIMEV | AT91_RTC_CALEV); - at91_rtc_imr = 0; ret = request_irq(irq, at91_rtc_interrupt, IRQF_SHARED, @@ -336,7 +329,6 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) at91_rtc_write(AT91_RTC_IDR, AT91_RTC_ACKUPD | AT91_RTC_ALARM | AT91_RTC_SECEV | AT91_RTC_TIMEV | AT91_RTC_CALEV); - at91_rtc_imr = 0; free_irq(irq, pdev); rtc_device_unregister(rtc); @@ -349,35 +341,31 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) /* AT91RM9200 RTC Power management control */ -static u32 at91_rtc_bkpimr; - +static u32 at91_rtc_imr; static int at91_rtc_suspend(struct device *dev) { /* this IRQ is shared with DBGU and other hardware which isn't * necessarily doing PM like we are... */ - at91_rtc_bkpimr = at91_rtc_imr & (AT91_RTC_ALARM|AT91_RTC_SECEV); - if (at91_rtc_bkpimr) { - if (device_may_wakeup(dev)) { + at91_rtc_imr = at91_rtc_read(AT91_RTC_IMR) + & (AT91_RTC_ALARM|AT91_RTC_SECEV); + if (at91_rtc_imr) { + if (device_may_wakeup(dev)) enable_irq_wake(irq); - } else { - at91_rtc_write(AT91_RTC_IDR, at91_rtc_bkpimr); - at91_rtc_imr &= ~at91_rtc_bkpimr; - } -} + else + at91_rtc_write(AT91_RTC_IDR, at91_rtc_imr); + } return 0; } static int at91_rtc_resume(struct device *dev) { - if (at91_rtc_bkpimr) { - if (device_may_wakeup(dev)) { + if (at91_rtc_imr) { + if (device_may_wakeup(dev)) disable_irq_wake(irq); - } else { - at91_rtc_imr |= at91_rtc_bkpimr; - at91_rtc_write(AT91_RTC_IER, at91_rtc_bkpimr); - } + else + at91_rtc_write(AT91_RTC_IER, at91_rtc_imr); } return 0; } diff --git a/drivers/rtc/rtc-at91rm9200.h b/drivers/rtc/rtc-at91rm9200.h index 5f940b6844cb..da1945e5f714 100644 --- a/drivers/rtc/rtc-at91rm9200.h +++ b/drivers/rtc/rtc-at91rm9200.h @@ -64,6 +64,7 @@ #define AT91_RTC_SCCR 0x1c /* Status Clear Command Register */ #define AT91_RTC_IER 0x20 /* Interrupt Enable Register */ #define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */ +#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */ #define AT91_RTC_VER 0x2c /* Valid Entry Register */ #define AT91_RTC_NVTIM (1 << 0) /* Non valid Time */ -- cgit v1.2.3-55-g7522 From b2c87cae0edb1a99f7dd2751d5beb2cb97926514 Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Fri, 22 Mar 2013 10:07:24 -0400 Subject: GFS2: Issue discards in 512b sectors This patch changes GFS2's discard issuing code so that it calls function sb_issue_discard rather than blkdev_issue_discard. The code was calling blkdev_issue_discard and specifying the correct sector offset and sector size, but blkdev_issue_discard expects these values to be in terms of 512 byte sectors, even if the native sector size for the device is different. Calling sb_issue_discard with the BLOCK size instead ensures the correct block-to-512b-sector translation. I verified that "minlen" is specified in blocks, so comparing it to a number of blocks is correct. Signed-off-by: Bob Peterson Signed-off-by: Steven Whitehouse --- fs/gfs2/rgrp.c | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 70d1cd0b5f3b..5a51265a4341 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1181,12 +1181,9 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed) { struct super_block *sb = sdp->sd_vfs; - struct block_device *bdev = sb->s_bdev; - const unsigned int sects_per_blk = sdp->sd_sb.sb_bsize / - bdev_logical_block_size(sb->s_bdev); u64 blk; sector_t start = 0; - sector_t nr_sects = 0; + sector_t nr_blks = 0; int rv; unsigned int x; u32 trimmed = 0; @@ -1206,35 +1203,34 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset, if (diff == 0) continue; blk = offset + ((bi->bi_start + x) * GFS2_NBBY); - blk *= sects_per_blk; /* convert to sectors */ while(diff) { if (diff & 1) { - if (nr_sects == 0) + if (nr_blks == 0) goto start_new_extent; - if ((start + nr_sects) != blk) { - if (nr_sects >= minlen) { - rv = blkdev_issue_discard(bdev, - start, nr_sects, + if ((start + nr_blks) != blk) { + if (nr_blks >= minlen) { + rv = sb_issue_discard(sb, + start, nr_blks, GFP_NOFS, 0); if (rv) goto fail; - trimmed += nr_sects; + trimmed += nr_blks; } - nr_sects = 0; + nr_blks = 0; start_new_extent: start = blk; } - nr_sects += sects_per_blk; + nr_blks++; } diff >>= 2; - blk += sects_per_blk; + blk++; } } - if (nr_sects >= minlen) { - rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, 0); + if (nr_blks >= minlen) { + rv = sb_issue_discard(sb, start, nr_blks, GFP_NOFS, 0); if (rv) goto fail; - trimmed += nr_sects; + trimmed += nr_blks; } if (ptrimmed) *ptrimmed = trimmed; -- cgit v1.2.3-55-g7522 From ff802e31b5e60a9a39f70479947a27cea5da701c Mon Sep 17 00:00:00 2001 From: Mike Marciniszyn Date: Fri, 5 Apr 2013 14:30:13 -0400 Subject: firmware,IB/qib: revert firmware file move Commit e2eed58b4fbf ("IB/qib: change QLogic to Intel") moved a firmware file potentially breaking the ABI. This patch reverts that aspect of the fix as well as reverting the firmware name as used in qib. Reported-by: David Woodhouse Signed-off-by: Mike Marciniszyn Signed-off-by: Linus Torvalds --- drivers/infiniband/hw/qib/qib_sd7220.c | 2 +- firmware/Makefile | 2 +- firmware/intel/sd7220.fw.ihex | 513 --------------------------------- firmware/qlogic/sd7220.fw.ihex | 513 +++++++++++++++++++++++++++++++++ 4 files changed, 515 insertions(+), 515 deletions(-) delete mode 100644 firmware/intel/sd7220.fw.ihex create mode 100644 firmware/qlogic/sd7220.fw.ihex diff --git a/drivers/infiniband/hw/qib/qib_sd7220.c b/drivers/infiniband/hw/qib/qib_sd7220.c index 08a6c6d39e56..911205d3d5a0 100644 --- a/drivers/infiniband/hw/qib/qib_sd7220.c +++ b/drivers/infiniband/hw/qib/qib_sd7220.c @@ -44,7 +44,7 @@ #include "qib.h" #include "qib_7220.h" -#define SD7220_FW_NAME "intel/sd7220.fw" +#define SD7220_FW_NAME "qlogic/sd7220.fw" MODULE_FIRMWARE(SD7220_FW_NAME); /* diff --git a/firmware/Makefile b/firmware/Makefile index 5d8ee1319b5c..cbb09ce9730a 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -82,7 +82,7 @@ fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \ fw-shipped-$(CONFIG_SCSI_QLOGIC_1280) += qlogic/1040.bin qlogic/1280.bin \ qlogic/12160.bin fw-shipped-$(CONFIG_SCSI_QLOGICPTI) += qlogic/isp1000.bin -fw-shipped-$(CONFIG_INFINIBAND_QIB) += intel/sd7220.fw +fw-shipped-$(CONFIG_INFINIBAND_QIB) += qlogic/sd7220.fw fw-shipped-$(CONFIG_SND_KORG1212) += korg/k1212.dsp fw-shipped-$(CONFIG_SND_MAESTRO3) += ess/maestro3_assp_kernel.fw \ ess/maestro3_assp_minisrc.fw diff --git a/firmware/intel/sd7220.fw.ihex b/firmware/intel/sd7220.fw.ihex deleted file mode 100644 index a33636319112..000000000000 --- a/firmware/intel/sd7220.fw.ihex +++ /dev/null @@ -1,513 +0,0 @@ -:10000000020A29020A87E5E630E6047F0180027FC2 -:1000100000E5E230E4047E0180027E00EE5F6008CD -:1000200053F9F7E4F5FE80087F0A121731120EA289 -:1000300075FC08E4F5FDE5E720E70343F908220035 -:1000400001201100042000755101E4F552F553F52B -:1000500052F57E7F04020438C2360552E552D3942D -:100060000C4005755201D23690070C7407F0A3744A -:10007000FFF0E4F50CA3F0900714F0A3F0750B204B -:10008000F509E4F508E508D39430400302040412AE -:100090000006150BE50870047F0180027F00E5096A -:1000A00070047E0180027E00EE5F6005121871D23E -:1000B0003553E1F7E5084509FFE50B25E025E02488 -:1000C00083F582E43407F583EFF085E220E552D32F -:1000D0009401400D1219F3E054A064407003020330 -:1000E000FB53F9F8909470E4F0E0F510AF09121E9C -:1000F000B3AF08EF4408F582758380E0F529EF443B -:1001000007121A3CF5225440D39400401EE52954AE -:10011000F070211219F3E04480F0E52254306508B4 -:1001200070091219F3E054BFF080091219F37440FA -:10013000F00203FB121A127583AE74FFF0AF087E53 -:1001400000EF4407F582E0FDE50B25E025E0248182 -:10015000F582E43407F583EDF090070EE004F0EF4C -:100160004407F582758398E0F528121A23400C1293 -:1001700019F3E04401121A320203F6AF087E00744C -:1001800080CDEFCD8D82F583E030E00A1219F3E0E7 -:100190004420F00203FB1219F3E054DFF0EE44AE0A -:1001A000121A4330E4030203FB749E121A0520E086 -:1001B000030203FB8F828E83E020E0030203FB1225 -:1001C00019F3E04410F0E5E320E708E508121A3AD5 -:1001D0004404F0AF087E00EF121A3A20E2341219FC -:1001E000F3E04408F0E5E430E6047D0180027D00A0 -:1001F000E57EC3940450047C0180027C00EC4D60D9 -:1002000005C2350203FBEE44D2121A434440F00209 -:1002100003FB1219F3E054F7F0121A127583D2E0BF -:1002200054BFF0900714E004F0E57E7003757E0182 -:10023000AF087E00121A2340121219F3E044011293 -:1002400019F2E05402121A320203FB1219F3E044CD -:10025000021219F2E054FEF0C235EE448A8F82F5A4 -:1002600083E0F517548F4440F07490FCE508440790 -:10027000FDF5828C83E0543F900702F0E054C08D7E -:10028000828C83F07492121A05900703121A197463 -:1002900082121A05900704121A1974B4121A0590E2 -:1002A0000705121A197494FEE5084406121A0AF595 -:1002B0001030E004D2378002C237E510547F8F82BD -:1002C0008E83F0304430121A035480D394004004DB -:1002D000D2398002C2398F828E83E04480F0121AB4 -:1002E000035440D394004004D23A8002C23A8F8231 -:1002F0008E83E04440F07492FEE5084406121A0A28 -:1003000030E704D2388002C2388F828E83E0547F77 -:10031000F0121E46E4F50A20030280033043031264 -:1003200019952002028003304203120C8F303006F0 -:10033000121995120C8F120D471219F3E054FBF0AD -:10034000E50AC39401404643E1081219F3E044046E -:10035000F0E5E420E72A121A127583D2E05408D39C -:10036000940040047F0180027F00E50AC3940140AD -:10037000047E0180027E00EF5E6005121DD78017AB -:10038000121A127583D2E04408F00203FB121A120B -:100390007583D2E054F7F0121E467F0812173174AD -:1003A0008EFE121A128E83E0F51054FEF0E5104412 -:1003B00001FFE508FDED4407F582EFF0E51054FE7E -:1003C000FFED4407F582EF121A11758386E04410A1 -:1003D000121A11E04410F01219F3E054FD4401FF29 -:1003E0001219F3EF121A3230320CE5084408F58284 -:1003F0007583827405F0AF0B1218D774102508F5B9 -:10040000080200850509E509D3940750030200821C -:10041000E57ED3940040047F0180027F00E57EC327 -:1004200094FA50047E0180027E00EE5F6002057E39 -:1004300030350B43E1017F0912173102005853E1B7 -:10044000FE0200588E6A8F6B8C6C8D6D756E017517 -:100450006F01757001E4F573F574F57590072FF071 -:10046000F53CF53EF546F547F53DF53FF56FE56F93 -:10047000700FE56B456A12072A758380743AF08025 -:100480000912072A758380741AF0E4F56EC3743F6D -:10049000956EFF120865758382EFF0121A4D1208EF -:1004A000C6E533F01208FA1208B140E1E56F700BAF -:1004B00012072A7583807436F0800912072A758323 -:1004C000807416F0756E0112072A7583B4E56EF01C -:1004D000121A4D743F256EF582E43400F583E5333E -:1004E000F074BF256EF582E434001208B140D8E400 -:1004F000F570F546F547F56E1208FAF583E0FE1241 -:1005000008C6E07C002400FFEC3EFEAD3BD3EF9D2F -:10051000EE9C50047B0180027B00E57070047A0140 -:1005200080027A00EB5A6006856E46757001D3EF43 -:100530009DEE9C50047F0180027F00E570B40104B1 -:100540007E0180027E00EF5E6003856E47056EE5EA -:100550006E647F70A3E5466005E547B47E0385467B -:1005600047E56F7008854676854777800EC3747FB0 -:100570009546F578C3747F9547F579E56F7037E553 -:10058000466547700C757301757401F53CF53D8047 -:1005900035E4F54EC3E5479546F53CC313F57125A3 -:1005A00046F572C3943F4005E4F53D8040C3743F77 -:1005B0009572F53D8037E5466547700F7573017597 -:1005C0007501F53EF53F754E018022E4F54EC3E519 -:1005D000479546F53EC313F5712546F572D3943F12 -:1005E0005005E4F53F8006E57224C1F53F056FE54F -:1005F0006FC39402500302046EE56D456C70028077 -:1006000004E574457590072FF07F01E53E6004E531 -:100610003C7014E4F53CF53DF53EF53F1208D27010 -:1006200004F00206A4807AE53CC3953E4007E53C11 -:10063000953EFF8006C3E53E953CFFE576D3957970 -:10064000400585767A800385797AE577C395785079 -:100650000585777B800385787BE57BD3957A403071 -:10066000E57B957AF53CF53EC3E57B957A900719D5 -:10067000F0E53CC313F571257AF572C3943F40054C -:10068000E4F53D801FC3743F9572F53DF53F80143E -:10069000E4F53CF53E900719F01208D27003F080A3 -:1006A000037401F01208657583D0E0540FFEAD3C71 -:1006B00070027E07BE0F027E80EEFBEFD39B74803C -:1006C000F898401FE4F53CF53E1208D27003F08024 -:1006D000127401F0E508FBEB4407F5827583D2E064 -:1006E0004410F0E508FBEB4409F58275839EEDF0BC -:1006F000EB4407F5827583CAEDF01208657583CC6B -:10070000EFF022E5084407F5827583BCE054F0F071 -:10071000E5084407F5827583BEE054F0F0E508442F -:1007200007F5827583C0E054F0F0E5084407F582D0 -:1007300022F0900728E0FEA3E0F5828E8322854216 -:100740004285414185404074C02FF58274023EF5D8 -:1007500083E542F074E02FF58274023EF58322E5D2 -:100760004229FDE433FCE53CC39DEC6480F87480D1 -:100770009822F583E0900722541FFDE0FAA3E0F5EC -:10078000828A83EDF022900722E0FCA3E0F5828CC0 -:100790008322900724FFED4407CFF0A3EFF02285DA -:1007A0003838853939853A3A74C02FF58274023E5B -:1007B000F58322900726FFED4407CFF0A3EFF02248 -:1007C000F074A02FF58274023EF5832274C02511C7 -:1007D000F582E43401F5832274002511F582E434B6 -:1007E00002F5832274602511F582E43403F5832237 -:1007F00074802511F582E43403F5832274E0251119 -:10080000F582E43403F5832274402511F582E43443 -:1008100006F5832274802FF58274023EF58322AFA1 -:10082000087E00EF4407F58222F583E5824407F550 -:1008300082E540F02274402511F582E43402F5830C -:100840002274C02511F582E43403F5832274002557 -:1008500011F582E43406F5832274202511F582E433 -:100860003406F58322E508FDED4407F58222E541D3 -:10087000F0E56564014564227E00FB7A00FD7C00A2 -:100880002274202511F582E434022274A02511F58A -:1008900082E4340322853E42853F418F4022853CDD -:1008A00042853D418F402275453F900720E4F0A3EB -:1008B00022F583E532F0056EE56EC3944022F0E543 -:1008C000084406F582227400256EF582E43400F5B2 -:1008D0008322E56D456C90072F22E4F9E53CD39522 -:1008E0003E2274802EF582E43402F583E02274A067 -:1008F0002EF582E43402F583E0227480256EF582C1 -:10090000E43400222542FDE433FC22854242854145 -:100910004185404022ED4C60030209E5EF4E7037FF -:10092000900726120789E0FD1207CCEDF09007280A -:10093000120789E0FD1207D8EDF0120786E0541F78 -:10094000FD120881F583EDF0900724120789E05429 -:100950001FFD120835EDF0EF64044E703790072646 -:10096000120789E0FD1207E4EDF0900728120789CD -:10097000E0FD1207F0EDF0120786E0541FFD1208AB -:100980008BF583EDF0900724120789E0541FFD12C8 -:100990000841EDF0EF64014E70047D0180027D009E -:1009A000EF64024E70047F0180027F00EF4D60789B -:1009B000900726120735E0FF1207FCEF120731E01F -:1009C000FF120808EFF0900722120735E0541FFFCE -:1009D00012084DEFF0900724120735E0541FFF1264 -:1009E0000859EFF0221207CCE4F01207D8E4F01215 -:1009F0000881F583E4F01208357414F01207E4E47A -:100A0000F01207F0E4F012088BF583E4F0120841CD -:100A10007414F01207FCE4F0120808E4F012084D18 -:100A2000E4F01208597414F02253F9F775FC10E43D -:100A3000F5FD75FE30F5FFE5E720E70343F908E52E -:100A4000E620E70B78FFE4F6D8FD53E6FE80097850 -:100A500008E4F6D8FD53E6FE758180E4F5A8D2A837 -:100A6000C2A9D2AFE5E220E50520E602800343E11A -:100A700002E5E220E00E9000007F007E08E4F0A393 -:100A8000DFFCDEFA020ADB43FA01C0E0C0F0C083FB -:100A9000C082C0D0121CE7D0D0D082D083D0F0D09A -:100AA000E053FAFE32021B55E493A3F8E493A3F655 -:100AB00008DFF98029E493A3F85407240CC8C33352 -:100AC000C4540F4420C8834004F456800146F6DF26 -:100AD000E4800B010204081020408090003FE47E77 -:100AE000019360C1A3FF543F30E509541FFEE49316 -:100AF000A360010ECF54C025E060AD40B880FE8CED -:100B0000648D658A668B67E4F569EF4E7003021D9C -:100B100055E4F568E5674566703212072A758390DB -:100B2000E41207297583C2E41207297583C4E4120D -:100B30000870702912072A758392E41207297583B9 -:100B4000C6E41207297583C8E4F0801190072612C5 -:100B50000735E41208707005120732E4F0121D55D3 -:100B6000121EBFE5674566703312072A758390E54C -:100B7000411207297583C2E5411207297583C41202 -:100B8000086E702912072A758392E54012072975AD -:100B900083C6E5401207297583C8800E9007261288 -:100BA000073512086E7006120732E540F0AF697E15 -:100BB00000AD67AC6612044412072A7583CAE0D3FD -:100BC0009400500C0568E568C394055003020B14AB -:100BD000228C608D611208DA7420400D2FF582742A -:100BE000033EF583E53EF0800B2FF58274033EF55E -:100BF00083E53CF0E53CD3953E403CE561456070C3 -:100C000010E9120904E53E120768403B120895807E -:100C100018E53EC39538401D853E38E53E600585A4 -:100C20003F3980038539398F3A120814E53E12079F -:100C3000C0E53FF0228043E5614560701912075F0F -:100C4000400512089E802712090B120814E5421273 -:100C500007C0E541F022E53CC39538401D853C388E -:100C6000E53C6005853D3980038539398F3A1208A6 -:100C700014E53C1207C0E53DF02285383885393946 -:100C8000853A3A120814E5381207C0E539F0227F98 -:100C900006121731121D23120E04120E33E0440AFD -:100CA000F0748EFE120E04120E0BEFF0E52830E504 -:100CB00003D38001C3400575142080037514081206 -:100CC0000E0475838AE514F0B4FF05751280800662 -:100CD000E514C313F512E4F516F57F121936121355 -:100CE000A3E50AC3940150090516E516C394144000 -:100CF000EAE5E420E728120E047583D2E05408D315 -:100D0000940040047F0180027F00E50AC394014003 -:100D1000047E0180027E00EF5E6003121DD7E57F36 -:100D2000C394114014120E047583D2E04480F0E5A0 -:100D3000E420E70F121DD7800A120E047583D2E05B -:100D4000547FF0121D2322748A850882F583E517EB -:100D5000F0120E3AE4F0900702E0120E177583903D -:100D6000EFF07492FEE5084407FFF5828E83E054AD -:100D7000C0FD900703E0543F4D8F828E83F09007B3 -:100D800004E0120E17758382EFF0900705E0FFED87 -:100D90004407F5827583B4EF120E03758380E05427 -:100DA000BFF030370A120E91758394E04480F03022 -:100DB000380A120E91758392E04480F0E52830E401 -:100DC0001A20390A120E04758388E0547FF0203A05 -:100DD0000A120E04758388E054BFF0748CFE120E64 -:100DE000048E83E0540F120E03758386E054BFF027 -:100DF000E5084406120DFD75838AE4F022F582753C -:100E00008382E4F0E5084407F582228E83E0F51042 -:100E100054FEF0E5104401FFE508FDED4407F582BE -:100E200022E515C45407FFE508FDED4408F5827579 -:100E3000838222758380E04440F0E5084408F5820F -:100E400075838A22E51625E025E024AFF582E43497 -:100E50001AF583E493F50D2243E11043E18053E159 -:100E6000FD85E11022E51625E025E024B2F582E4B7 -:100E7000341AF583E49322855582855483E515F071 -:100E800022E5E25420D3940022E5E25440D39400BA -:100E900022E5084406F58222FDE508FBEB4407F550 -:100EA000822253F9F775FE3022EF4E70261207CCDE -:100EB000E0FD90072612077B1207D8E0FD90072877 -:100EC00012077B120881120772120835E09007247E -:100ED000120778EF64044E70291207E4E0FD9007D2 -:100EE0002612077B1207F0E0FD90072812077B12FD -:100EF000088B120772120841E0541FFD900724125C -:100F0000077BEF64014E70047D0180027D00EF6479 -:100F1000024E70047F0180027F00EF4D60351207A2 -:100F2000FCE0FF900726120789EFF0120808E0FFA7 -:100F3000900728120789EFF012084DE0541FFF12A6 -:100F40000786EFF0120859E0541FFF90072412079C -:100F500089EFF022E4F553120E8140047F018002F4 -:100F60007F00120E8940047E0180027E00EE4F70E9 -:100F700003020FF685E11043E10253E10F85E11012 -:100F8000E4F551E5E3543FF552120E89401DAD5290 -:100F9000AF51121118EF600885E11043E140800B5A -:100FA00053E1BF120E5812000680FBE5E3543FF5F3 -:100FB00051E5E4543FF552120E81401DAD52AF5140 -:100FC000121118EF600885E11043E120800B53E116 -:100FD000DF120E5812000680FB120E8140047F01C2 -:100FE00080027F00120E8940047E0180027E00EEA6 -:100FF0004F6003120E5B22120E21EFF012109122AD -:1010000002110002104002109000000000000000D9 -:1010100001200120E4F5571216BD121644E4121007 -:10102000561214B7900726120735E4120731E4F080 -:101030001210561214B7900726120735E541120711 -:1010400031E540F0AF577E00AD567C00120444AF4E -:10105000567E000211EEFF900720A3E0FDE4F55656 -:10106000F540FEFCAB56FA1211517F0F7D18E4F5E6 -:1010700056F540FEFCAB56FA121541AF567E0012F3 -:101080001AFFE4FFF5567D1FF540FEFCAB56FA2231 -:1010900022E4F555E508FD74A0F556ED4407F55733 -:1010A000E52830E503D38001C340057F28EF8004A5 -:1010B0007F14EFC313F554E4F9120E1875838EE014 -:1010C000F510CEEFCEEED394004026E51054FE127C -:1010D0000E9875838EEDF0E5104401FDEB4407F5A5 -:1010E00082EDF0855782855683E030E301091E804A -:1010F000D4C234E9C395544002D2342202000622FD -:10110000303011901000E493F510901010E493F536 -:101110001012109012115022E4FCC3ED9FFAEFF56B -:101120008375820079FFE493CC6CCCA3D9F8DAF60E -:10113000E5E230E4028CE5ED24FFFFEF7582FFF578 -:1011400083E4936C70037F01227F00222211000050 -:10115000228E588F598C5A8D5B8A5C8B5D755E012F -:10116000E4F55FF560F56212072A7583D0E0FFC4ED -:10117000540FF561121EA585595ED3E55E955BE5BA -:101180005A12076B504B1207037583BCE0455E1281 -:1011900007297583BEE0455E1207297583C0E045C7 -:1011A0005EF0AF5FE560120878120AFFAF627E0062 -:1011B000AD5DAC5C120444E561AF5E7E00B4030536 -:1011C000121E218007AD5DAC5C121317055E021183 -:1011D0007A1207037583BCE045401207297583BE68 -:1011E000E045401207297583C0E04540F0228E5843 -:1011F0008F59755A017901755B01E4FB12072A7555 -:1012000083AEE0541AFF120865E0C4135407FEEFE2 -:10121000700CEE6535700790072FE0B4010DAF3507 -:101220007E00120EA9CFEBCF021E60E55964024585 -:101230005870047F0180027F00E559455870047E94 -:101240000180027E00EE4F602385414985404BE5D9 -:10125000594558702CAF5AFECDE9CDFCAB59AA5870 -:10126000120AFFAF5B7E00121E608015AF5B7E002E -:10127000121E60900726120735E549120731E54B2B -:10128000F0E4FDAF35FEFC120915228C648D651269 -:1012900008DA403CE56545647010120904C3E53E78 -:1012A000120769403B1208958018E53EC395384007 -:1012B0001D853E38E53E6005853F39800385393917 -:1012C0008F3A1207A8E53E120753E53FF022803B14 -:1012D000E5654564701112075F400512089E801F86 -:1012E00012073EE541F022E53CC39538401D853CA0 -:1012F00038E53C6005853D3980038539398F3A12E0 -:1013000007A8E53C120753E53DF02212079FE53898 -:10131000120753E539F0228C638D641208DA403CE1 -:10132000E56445637010120904C3E53E1207694085 -:101330003B1208958018E53EC39538401D853E3820 -:10134000E53E6005853F3980038539398F3A1207BC -:10135000A8E53E120753E53FF022803BE564456374 -:10136000701112075F400512089E801F12073EE5AC -:1013700041F022E53CC39538401D853C38E53C6092 -:1013800005853D3980038539398F3A1207A8E53C38 -:10139000120753E53DF02212079FE538120753E587 -:1013A00039F022E50DFEE5088E544405F555751516 -:1013B0000FF582120E7A1217A320310575150380DE -:1013C0000375150BE50AC39401503812142020311F -:1013D0000605150515800415151515E50AC39401B4 -:1013E0005021121420203104051580021515E50A3C -:1013F000C39401500E120E771217A3203105051564 -:10140000120E77E515B408047F0180027F00E51510 -:10141000B407047E0180027E00EE4F6002057F2249 -:10142000855582855483E515F01217A32212072AE9 -:101430007583AE74FF120729E0541AF534E0C41323 -:101440005407F53524FE602424FE603C24047063B8 -:1014500075312DE508FD74B612079274BC90072211 -:1014600012079574901207B37492803C75313AE577 -:1014700008FD74BA12079274C09007221207B6745E -:10148000C41207B374C88020753135E508FD74B8FF -:1014900012079274BEFFED4407900722CFF0A3EF2E -:1014A000F074C21207B374C6FFED4407A3CFF0A3D4 -:1014B000EFF022753401228E588F598C5A8D5B8A39 -:1014C0005C8B5D755E01E4F55F121EA585595ED3E8 -:1014D000E55E955BE55A12076B5057E55D455C701C -:1014E0003012072A758392E55E1207297583C6E5D7 -:1014F0005E1207297583C8E55E120729758390E59A -:101500005E1207297583C2E55E1207297583C480C0 -:1015100003120732E55EF0AF5F7E00AD5DAC5C129A -:101520000444AF5E7E00AD5DAC5C120BD1055E0283 -:1015300014CFAB5DAA5CAD5BAC5AAF59AE58021B81 -:10154000FB8C5C8D5D8A5E8B5F756001E4F561F5F7 -:1015500062F563121EA58F60D3E560955DE55C12B0 -:10156000076B5061E55F455E702712072A7583B6E9 -:10157000E5601207297583B8E5601207297583BAFB -:10158000E560F0AF617E00E56212087A120AFF8022 -:1015900019900724120735E56012072975838EE438 -:1015A0001207297401120729E4F0AF637E00AD5FD2 -:1015B000AC5E120444AF607E00AD5FAC5E12128B75 -:1015C00005600215582290114DE49390072EF012F9 -:1015D000081F7583AEE0541AF5347067EF4407F5C1 -:1015E000827583CEE0FF1313135407F536540FD3DF -:1015F0009400400612142D121BA9E536540F24FE48 -:10160000600C14600C146019240370378010021EE3 -:1016100091121E9112072A7583CEE054EFF0021D3D -:10162000AE121014E4F555121D850555E555C39409 -:101630000540F412072A7583CEE054C7120729E04B -:101640004408F022E4F558F559AF08EF4407F58255 -:101650007583D0E0FDC4540FF55AEF4407F5827549 -:1016600083807401F0120821758382E545F0EF4410 -:1016700007F58275838A74FFF0121A4D12072A75D6 -:1016800083BCE054EF1207297583BEE054EF1207C4 -:10169000297583C0E054EF1207297583BCE044101C -:1016A0001207297583BEE044101207297583C0E034 -:1016B0004410F0AF58E559120878020AFFE4F558D3 -:1016C0007D01F559AF35FEFC12091512072A758305 -:1016D000B674101207297583B87410120729758320 -:1016E000BA74101207297583BC7410120729758308 -:1016F000BE74101207297583C074101207297583F0 -:1017000090E41207297583C2E41207297583C4E4A3 -:10171000120729758392E41207297583C6E412071C -:10172000297583C8E4F0AF58FEE55912087A020A19 -:10173000FFE5E230E46CE5E754C064407064E5091D -:10174000C45430FEE50825E025E054C04EFEEF54B9 -:101750003F4EFDE52BAE2A7802C333CE33CED8F907 -:10176000F5828E83EDF0E52BAE2A7802C333CE33BB -:10177000CED8F9FFF5828E83A3E5FEF08F828E83AB -:10178000A3A3E5FDF08F828E83A3A3A3E5FCF0C3A2 -:10179000E52B94FAE52A94005008052BE52B7002FE -:1017A000052A22E4FFE4F558F556F5577482FC1239 -:1017B0000E048C83E0F510547FF0E5104480120E87 -:1017C00098EDF07E0A120E047583A0E020E026DE7C -:1017D000F40557E55770020556E5142401FDE4337E -:1017E000FCD3E5579DE5569C40D9E50A942050026C -:1017F000050A43E108C231120E047583A6E05512B2 -:1018000065127003D23122C23122900726E0FAA37A -:10181000E0F5828A83E0F541E539C395414026E54C -:10182000399541C39FEE12076B40047C0180027C16 -:1018300000E541643F60047B0180027B00EC5B605B -:101840002905418028C3E5419539C39FEE12076BF6 -:1018500040047F0180027F00E54160047E01800238 -:101860007E00EF5E600415418003853941853A4072 -:1018700022E5E230E460E5E130E25BE50970047FF7 -:101880000180027F00E50870047E0180027E00EE88 -:101890005F604353F9F8E5E230E43BE5E130E22EE6 -:1018A00043FA0253FAFBE4F510909470E510F0E56A -:1018B000E130E2E7909470E06510600343FA0405BC -:1018C00010909470E510F070E612000680E153FA73 -:1018D000FD53FAFB80C0228F54120006E5E130E090 -:1018E000047F0180027F00E57ED3940540047E01E1 -:1018F00080027E00EE4F603D855411E5E220E1322A -:1019000074CE121A0530E7047D0180027D008F82BB -:101910008E83E030E6047F0180027F00EF5D70156A -:101920001215C674CE121A0530E607E04480F04363 -:10193000F98012187122120E44E51625E025E024E4 -:10194000B0F582E4341AF583E493F50FE51625E04B -:1019500025E024B1F582E4341AF583E493F50E1200 -:101960000E65F510E50F54F0120E1775838CEFF02D -:10197000E50F30E00C120E04758386E04440F080E1 -:101980000A120E04758386E054BFF0120E9175831F -:1019900082E50EF0227F05121731120E04120E336B -:1019A0007402F0748EFE120E04120E0BEFF0751519 -:1019B00070120FF72034057515108003751550123D -:1019C0000FF72034047410800274F02515F51512F9 -:1019D0000E21EFF0121091203417E5156430600CE1 -:1019E00074102515F515B48003E4F515120E21EFDA -:1019F000F022F0E50B25E025E02482F582E43407AF -:101A0000F583227488FEE5084407FFF5828E83E0A3 -:101A100022F0E5084407F58222F0E054C08F828E60 -:101A200083F022EF4407F582758386E05410D39447 -:101A30000022F0900715E004F0224406F582758339 -:101A40009EE022FEEF4407F5828E83E022E49007B9 -:101A50002AF0A3F012072A758382E0547F12072927 -:101A6000E04480F01210FC12081F7583A0E020E013 -:101A70001A90072BE004F0700690072AE004F0901B -:101A8000072AE0B410E1A3E0B400DCEE44A6FCEFCA -:101A90004407F5828C83E0F532EE44A8FEEF44075C -:101AA000F5828E83E0F5332201201100042000909E -:101AB00000200F9200210F9400220F9600230F9810 -:101AC00000240F9A00250F9C00260F9E00270FA0D0 -:101AD000012001A2012101A4012201A6012301A8E4 -:101AE000012401AA012501AC012601AE012701B0A4 -:101AF000012801B400280FB640280FB8612801CB97 -:101B0000EFCBCAEECA7F01E4FDEB4A7024E508F58D -:101B10008274B6120829E508F58274B8120829E51E -:101B200008F58274BA1208297E007C00120AFF8030 -:101B300012900726120735E541F090072412073569 -:101B4000E540F012072A75838EE41207297401120A -:101B50000729E4F022E4F526F52753E1FEF52A757E -:101B60002B01F5087F0112173130301C901AA9E4BF -:101B700093F510901FF9E493F510900041E493F56C -:101B800010901ECAE493F5107F02121731120F5401 -:101B90007F03121731120006E5E230E70912100048 -:101BA00030300312110002004712081F7583D0E085 -:101BB000C4540FFD7543017544FF1208AA7404F064 -:101BC000753B01ED14600C14600B14600F2403705E -:101BD0000B800980001208A704F080061208A77481 -:101BE00004F0EE4482FEEF4407F5828E83E5451251 -:101BF00008BE758382E531F002114C8E608F611250 -:101C00001EA5E4FFCEEDCEEED39561E56012076B25 -:101C1000403974202EF582E43403F583E07003FF2D -:101C200080261208E2FDC39F401ECFEDCFEB4A7025 -:101C30000B8D421208EEF5418E40800C1208E2F541 -:101C4000381208EEF5398E3A1E80BC22755801E52F -:101C500035700C1207CCE0F54A1207D8E0F54CE5D8 -:101C600035B4040C1207E4E0F54A1207F0E0F54C35 -:101C7000E535B401047F0180027F00E535B402043C -:101C80007E0180027E00EE4F600C1207FCE0F54AF8 -:101C9000120808E0F54C85414985404B22755B01EF -:101CA000900724120735E0541FFFD3940250048F8D -:101CB000588005EF24FEF558EFC394184005755978 -:101CC000188004EF04F55985435AAF587E00AD598A -:101CD0007C00AB5B7A00121541AF5A7E0012180AE5 -:101CE000AF5B7E00021AFFE5E230E70E121003C27E -:101CF000303030031210FF203328E5E730E70512BB -:101D00000EA2800DE5FEC394205006120EA243F9E8 -:101D100008E5F230E70353F97FE5F15470D39400FE -:101D200050D822120E04758380E4F0E508440712AF -:101D30000DFD758384120E02758386120E02758363 -:101D40008CE054F3120E0375838E120E0275839489 -:101D5000E054FBF02212072A75838EE412072974DF -:101D600001120729E41208BE75838CE04420120892 -:101D7000BEE054DFF07484850882F583E0547FF080 -:101D8000E04480F022755601E4FDF557AF35FEFCC6 -:101D9000120915121C9D121E7A121C4CAF577E00A0 -:101DA000AD567C00120444AF567E000211EE75560B -:101DB00001E4FDF557AF35FEFC120915121C9D120A -:101DC0001E7A121C4CAF577E00AD567C00120444A4 -:101DD000AF567E000211EEE4F516120E44FEE50841 -:101DE0004405FF120E658F828E83F00516E516C33B -:101DF000941440E6E508120E2BE4F022E4F558F5C1 -:101E000059F55AFFFEAD58FC1209157F047E00AD4E -:101E1000587C001209157F027E00AD587C00020933 -:101E200015E53C253EFCE5422400FBE433FAECC317 -:101E30009BEA12076B400B8C42E53D253FF5418F35 -:101E4000402212090B227484F5188508198519821D -:101E5000851883E0547FF0E04480F0E04480F02275 -:101E6000EF4E700B12072A7583D2E054DFF0221276 -:101E7000072A7583D2E04420F02275580190072686 -:101E8000120735E0543FF541120732E0543FF54068 -:101E900022755602E4F557121DFCAF577E00AD5671 -:101EA0007C00020444E4F542F541F540F538F5398B -:101EB000F53A22EF5407FFE5F954F84FF5F9227F80 -:101EC00001E4FE0F0EBEFFFB2201200001042000F2 -:101ED0000000000000000000000000000000000002 -:101EE00000000000000000000000000000000000F2 -:101EF00000000000000000000000000000000000E2 -:101F000000000000000000000000000000000000D1 -:101F100000000000000000000000000000000000C1 -:101F200000000000000000000000000000000000B1 -:101F300000000000000000000000000000000000A1 -:101F40000000000000000000000000000000000091 -:101F50000000000000000000000000000000000081 -:101F60000000000000000000000000000000000071 -:101F70000000000000000000000000000000000061 -:101F80000000000000000000000000000000000051 -:101F90000000000000000000000000000000000041 -:101FA0000000000000000000000000000000000031 -:101FB0000000000000000000000000000000000021 -:101FC0000000000000000000000000000000000011 -:101FD0000000000000000000000000000000000001 -:101FE00000000000000000000000000000000000F1 -:101FF000000000000000000001201100042000810A -:00000001FF diff --git a/firmware/qlogic/sd7220.fw.ihex b/firmware/qlogic/sd7220.fw.ihex new file mode 100644 index 000000000000..a33636319112 --- /dev/null +++ b/firmware/qlogic/sd7220.fw.ihex @@ -0,0 +1,513 @@ +:10000000020A29020A87E5E630E6047F0180027FC2 +:1000100000E5E230E4047E0180027E00EE5F6008CD +:1000200053F9F7E4F5FE80087F0A121731120EA289 +:1000300075FC08E4F5FDE5E720E70343F908220035 +:1000400001201100042000755101E4F552F553F52B +:1000500052F57E7F04020438C2360552E552D3942D +:100060000C4005755201D23690070C7407F0A3744A +:10007000FFF0E4F50CA3F0900714F0A3F0750B204B +:10008000F509E4F508E508D39430400302040412AE +:100090000006150BE50870047F0180027F00E5096A +:1000A00070047E0180027E00EE5F6005121871D23E +:1000B0003553E1F7E5084509FFE50B25E025E02488 +:1000C00083F582E43407F583EFF085E220E552D32F +:1000D0009401400D1219F3E054A064407003020330 +:1000E000FB53F9F8909470E4F0E0F510AF09121E9C +:1000F000B3AF08EF4408F582758380E0F529EF443B +:1001000007121A3CF5225440D39400401EE52954AE +:10011000F070211219F3E04480F0E52254306508B4 +:1001200070091219F3E054BFF080091219F37440FA +:10013000F00203FB121A127583AE74FFF0AF087E53 +:1001400000EF4407F582E0FDE50B25E025E0248182 +:10015000F582E43407F583EDF090070EE004F0EF4C +:100160004407F582758398E0F528121A23400C1293 +:1001700019F3E04401121A320203F6AF087E00744C +:1001800080CDEFCD8D82F583E030E00A1219F3E0E7 +:100190004420F00203FB1219F3E054DFF0EE44AE0A +:1001A000121A4330E4030203FB749E121A0520E086 +:1001B000030203FB8F828E83E020E0030203FB1225 +:1001C00019F3E04410F0E5E320E708E508121A3AD5 +:1001D0004404F0AF087E00EF121A3A20E2341219FC +:1001E000F3E04408F0E5E430E6047D0180027D00A0 +:1001F000E57EC3940450047C0180027C00EC4D60D9 +:1002000005C2350203FBEE44D2121A434440F00209 +:1002100003FB1219F3E054F7F0121A127583D2E0BF +:1002200054BFF0900714E004F0E57E7003757E0182 +:10023000AF087E00121A2340121219F3E044011293 +:1002400019F2E05402121A320203FB1219F3E044CD +:10025000021219F2E054FEF0C235EE448A8F82F5A4 +:1002600083E0F517548F4440F07490FCE508440790 +:10027000FDF5828C83E0543F900702F0E054C08D7E +:10028000828C83F07492121A05900703121A197463 +:1002900082121A05900704121A1974B4121A0590E2 +:1002A0000705121A197494FEE5084406121A0AF595 +:1002B0001030E004D2378002C237E510547F8F82BD +:1002C0008E83F0304430121A035480D394004004DB +:1002D000D2398002C2398F828E83E04480F0121AB4 +:1002E000035440D394004004D23A8002C23A8F8231 +:1002F0008E83E04440F07492FEE5084406121A0A28 +:1003000030E704D2388002C2388F828E83E0547F77 +:10031000F0121E46E4F50A20030280033043031264 +:1003200019952002028003304203120C8F303006F0 +:10033000121995120C8F120D471219F3E054FBF0AD +:10034000E50AC39401404643E1081219F3E044046E +:10035000F0E5E420E72A121A127583D2E05408D39C +:10036000940040047F0180027F00E50AC3940140AD +:10037000047E0180027E00EF5E6005121DD78017AB +:10038000121A127583D2E04408F00203FB121A120B +:100390007583D2E054F7F0121E467F0812173174AD +:1003A0008EFE121A128E83E0F51054FEF0E5104412 +:1003B00001FFE508FDED4407F582EFF0E51054FE7E +:1003C000FFED4407F582EF121A11758386E04410A1 +:1003D000121A11E04410F01219F3E054FD4401FF29 +:1003E0001219F3EF121A3230320CE5084408F58284 +:1003F0007583827405F0AF0B1218D774102508F5B9 +:10040000080200850509E509D3940750030200821C +:10041000E57ED3940040047F0180027F00E57EC327 +:1004200094FA50047E0180027E00EE5F6002057E39 +:1004300030350B43E1017F0912173102005853E1B7 +:10044000FE0200588E6A8F6B8C6C8D6D756E017517 +:100450006F01757001E4F573F574F57590072FF071 +:10046000F53CF53EF546F547F53DF53FF56FE56F93 +:10047000700FE56B456A12072A758380743AF08025 +:100480000912072A758380741AF0E4F56EC3743F6D +:10049000956EFF120865758382EFF0121A4D1208EF +:1004A000C6E533F01208FA1208B140E1E56F700BAF +:1004B00012072A7583807436F0800912072A758323 +:1004C000807416F0756E0112072A7583B4E56EF01C +:1004D000121A4D743F256EF582E43400F583E5333E +:1004E000F074BF256EF582E434001208B140D8E400 +:1004F000F570F546F547F56E1208FAF583E0FE1241 +:1005000008C6E07C002400FFEC3EFEAD3BD3EF9D2F +:10051000EE9C50047B0180027B00E57070047A0140 +:1005200080027A00EB5A6006856E46757001D3EF43 +:100530009DEE9C50047F0180027F00E570B40104B1 +:100540007E0180027E00EF5E6003856E47056EE5EA +:100550006E647F70A3E5466005E547B47E0385467B +:1005600047E56F7008854676854777800EC3747FB0 +:100570009546F578C3747F9547F579E56F7037E553 +:10058000466547700C757301757401F53CF53D8047 +:1005900035E4F54EC3E5479546F53CC313F57125A3 +:1005A00046F572C3943F4005E4F53D8040C3743F77 +:1005B0009572F53D8037E5466547700F7573017597 +:1005C0007501F53EF53F754E018022E4F54EC3E519 +:1005D000479546F53EC313F5712546F572D3943F12 +:1005E0005005E4F53F8006E57224C1F53F056FE54F +:1005F0006FC39402500302046EE56D456C70028077 +:1006000004E574457590072FF07F01E53E6004E531 +:100610003C7014E4F53CF53DF53EF53F1208D27010 +:1006200004F00206A4807AE53CC3953E4007E53C11 +:10063000953EFF8006C3E53E953CFFE576D3957970 +:10064000400585767A800385797AE577C395785079 +:100650000585777B800385787BE57BD3957A403071 +:10066000E57B957AF53CF53EC3E57B957A900719D5 +:10067000F0E53CC313F571257AF572C3943F40054C +:10068000E4F53D801FC3743F9572F53DF53F80143E +:10069000E4F53CF53E900719F01208D27003F080A3 +:1006A000037401F01208657583D0E0540FFEAD3C71 +:1006B00070027E07BE0F027E80EEFBEFD39B74803C +:1006C000F898401FE4F53CF53E1208D27003F08024 +:1006D000127401F0E508FBEB4407F5827583D2E064 +:1006E0004410F0E508FBEB4409F58275839EEDF0BC +:1006F000EB4407F5827583CAEDF01208657583CC6B +:10070000EFF022E5084407F5827583BCE054F0F071 +:10071000E5084407F5827583BEE054F0F0E508442F +:1007200007F5827583C0E054F0F0E5084407F582D0 +:1007300022F0900728E0FEA3E0F5828E8322854216 +:100740004285414185404074C02FF58274023EF5D8 +:1007500083E542F074E02FF58274023EF58322E5D2 +:100760004229FDE433FCE53CC39DEC6480F87480D1 +:100770009822F583E0900722541FFDE0FAA3E0F5EC +:10078000828A83EDF022900722E0FCA3E0F5828CC0 +:100790008322900724FFED4407CFF0A3EFF02285DA +:1007A0003838853939853A3A74C02FF58274023E5B +:1007B000F58322900726FFED4407CFF0A3EFF02248 +:1007C000F074A02FF58274023EF5832274C02511C7 +:1007D000F582E43401F5832274002511F582E434B6 +:1007E00002F5832274602511F582E43403F5832237 +:1007F00074802511F582E43403F5832274E0251119 +:10080000F582E43403F5832274402511F582E43443 +:1008100006F5832274802FF58274023EF58322AFA1 +:10082000087E00EF4407F58222F583E5824407F550 +:1008300082E540F02274402511F582E43402F5830C +:100840002274C02511F582E43403F5832274002557 +:1008500011F582E43406F5832274202511F582E433 +:100860003406F58322E508FDED4407F58222E541D3 +:10087000F0E56564014564227E00FB7A00FD7C00A2 +:100880002274202511F582E434022274A02511F58A +:1008900082E4340322853E42853F418F4022853CDD +:1008A00042853D418F402275453F900720E4F0A3EB +:1008B00022F583E532F0056EE56EC3944022F0E543 +:1008C000084406F582227400256EF582E43400F5B2 +:1008D0008322E56D456C90072F22E4F9E53CD39522 +:1008E0003E2274802EF582E43402F583E02274A067 +:1008F0002EF582E43402F583E0227480256EF582C1 +:10090000E43400222542FDE433FC22854242854145 +:100910004185404022ED4C60030209E5EF4E7037FF +:10092000900726120789E0FD1207CCEDF09007280A +:10093000120789E0FD1207D8EDF0120786E0541F78 +:10094000FD120881F583EDF0900724120789E05429 +:100950001FFD120835EDF0EF64044E703790072646 +:10096000120789E0FD1207E4EDF0900728120789CD +:10097000E0FD1207F0EDF0120786E0541FFD1208AB +:100980008BF583EDF0900724120789E0541FFD12C8 +:100990000841EDF0EF64014E70047D0180027D009E +:1009A000EF64024E70047F0180027F00EF4D60789B +:1009B000900726120735E0FF1207FCEF120731E01F +:1009C000FF120808EFF0900722120735E0541FFFCE +:1009D00012084DEFF0900724120735E0541FFF1264 +:1009E0000859EFF0221207CCE4F01207D8E4F01215 +:1009F0000881F583E4F01208357414F01207E4E47A +:100A0000F01207F0E4F012088BF583E4F0120841CD +:100A10007414F01207FCE4F0120808E4F012084D18 +:100A2000E4F01208597414F02253F9F775FC10E43D +:100A3000F5FD75FE30F5FFE5E720E70343F908E52E +:100A4000E620E70B78FFE4F6D8FD53E6FE80097850 +:100A500008E4F6D8FD53E6FE758180E4F5A8D2A837 +:100A6000C2A9D2AFE5E220E50520E602800343E11A +:100A700002E5E220E00E9000007F007E08E4F0A393 +:100A8000DFFCDEFA020ADB43FA01C0E0C0F0C083FB +:100A9000C082C0D0121CE7D0D0D082D083D0F0D09A +:100AA000E053FAFE32021B55E493A3F8E493A3F655 +:100AB00008DFF98029E493A3F85407240CC8C33352 +:100AC000C4540F4420C8834004F456800146F6DF26 +:100AD000E4800B010204081020408090003FE47E77 +:100AE000019360C1A3FF543F30E509541FFEE49316 +:100AF000A360010ECF54C025E060AD40B880FE8CED +:100B0000648D658A668B67E4F569EF4E7003021D9C +:100B100055E4F568E5674566703212072A758390DB +:100B2000E41207297583C2E41207297583C4E4120D +:100B30000870702912072A758392E41207297583B9 +:100B4000C6E41207297583C8E4F0801190072612C5 +:100B50000735E41208707005120732E4F0121D55D3 +:100B6000121EBFE5674566703312072A758390E54C +:100B7000411207297583C2E5411207297583C41202 +:100B8000086E702912072A758392E54012072975AD +:100B900083C6E5401207297583C8800E9007261288 +:100BA000073512086E7006120732E540F0AF697E15 +:100BB00000AD67AC6612044412072A7583CAE0D3FD +:100BC0009400500C0568E568C394055003020B14AB +:100BD000228C608D611208DA7420400D2FF582742A +:100BE000033EF583E53EF0800B2FF58274033EF55E +:100BF00083E53CF0E53CD3953E403CE561456070C3 +:100C000010E9120904E53E120768403B120895807E +:100C100018E53EC39538401D853E38E53E600585A4 +:100C20003F3980038539398F3A120814E53E12079F +:100C3000C0E53FF0228043E5614560701912075F0F +:100C4000400512089E802712090B120814E5421273 +:100C500007C0E541F022E53CC39538401D853C388E +:100C6000E53C6005853D3980038539398F3A1208A6 +:100C700014E53C1207C0E53DF02285383885393946 +:100C8000853A3A120814E5381207C0E539F0227F98 +:100C900006121731121D23120E04120E33E0440AFD +:100CA000F0748EFE120E04120E0BEFF0E52830E504 +:100CB00003D38001C3400575142080037514081206 +:100CC0000E0475838AE514F0B4FF05751280800662 +:100CD000E514C313F512E4F516F57F121936121355 +:100CE000A3E50AC3940150090516E516C394144000 +:100CF000EAE5E420E728120E047583D2E05408D315 +:100D0000940040047F0180027F00E50AC394014003 +:100D1000047E0180027E00EF5E6003121DD7E57F36 +:100D2000C394114014120E047583D2E04480F0E5A0 +:100D3000E420E70F121DD7800A120E047583D2E05B +:100D4000547FF0121D2322748A850882F583E517EB +:100D5000F0120E3AE4F0900702E0120E177583903D +:100D6000EFF07492FEE5084407FFF5828E83E054AD +:100D7000C0FD900703E0543F4D8F828E83F09007B3 +:100D800004E0120E17758382EFF0900705E0FFED87 +:100D90004407F5827583B4EF120E03758380E05427 +:100DA000BFF030370A120E91758394E04480F03022 +:100DB000380A120E91758392E04480F0E52830E401 +:100DC0001A20390A120E04758388E0547FF0203A05 +:100DD0000A120E04758388E054BFF0748CFE120E64 +:100DE000048E83E0540F120E03758386E054BFF027 +:100DF000E5084406120DFD75838AE4F022F582753C +:100E00008382E4F0E5084407F582228E83E0F51042 +:100E100054FEF0E5104401FFE508FDED4407F582BE +:100E200022E515C45407FFE508FDED4408F5827579 +:100E3000838222758380E04440F0E5084408F5820F +:100E400075838A22E51625E025E024AFF582E43497 +:100E50001AF583E493F50D2243E11043E18053E159 +:100E6000FD85E11022E51625E025E024B2F582E4B7 +:100E7000341AF583E49322855582855483E515F071 +:100E800022E5E25420D3940022E5E25440D39400BA +:100E900022E5084406F58222FDE508FBEB4407F550 +:100EA000822253F9F775FE3022EF4E70261207CCDE +:100EB000E0FD90072612077B1207D8E0FD90072877 +:100EC00012077B120881120772120835E09007247E +:100ED000120778EF64044E70291207E4E0FD9007D2 +:100EE0002612077B1207F0E0FD90072812077B12FD +:100EF000088B120772120841E0541FFD900724125C +:100F0000077BEF64014E70047D0180027D00EF6479 +:100F1000024E70047F0180027F00EF4D60351207A2 +:100F2000FCE0FF900726120789EFF0120808E0FFA7 +:100F3000900728120789EFF012084DE0541FFF12A6 +:100F40000786EFF0120859E0541FFF90072412079C +:100F500089EFF022E4F553120E8140047F018002F4 +:100F60007F00120E8940047E0180027E00EE4F70E9 +:100F700003020FF685E11043E10253E10F85E11012 +:100F8000E4F551E5E3543FF552120E89401DAD5290 +:100F9000AF51121118EF600885E11043E140800B5A +:100FA00053E1BF120E5812000680FBE5E3543FF5F3 +:100FB00051E5E4543FF552120E81401DAD52AF5140 +:100FC000121118EF600885E11043E120800B53E116 +:100FD000DF120E5812000680FB120E8140047F01C2 +:100FE00080027F00120E8940047E0180027E00EEA6 +:100FF0004F6003120E5B22120E21EFF012109122AD +:1010000002110002104002109000000000000000D9 +:1010100001200120E4F5571216BD121644E4121007 +:10102000561214B7900726120735E4120731E4F080 +:101030001210561214B7900726120735E541120711 +:1010400031E540F0AF577E00AD567C00120444AF4E +:10105000567E000211EEFF900720A3E0FDE4F55656 +:10106000F540FEFCAB56FA1211517F0F7D18E4F5E6 +:1010700056F540FEFCAB56FA121541AF567E0012F3 +:101080001AFFE4FFF5567D1FF540FEFCAB56FA2231 +:1010900022E4F555E508FD74A0F556ED4407F55733 +:1010A000E52830E503D38001C340057F28EF8004A5 +:1010B0007F14EFC313F554E4F9120E1875838EE014 +:1010C000F510CEEFCEEED394004026E51054FE127C +:1010D0000E9875838EEDF0E5104401FDEB4407F5A5 +:1010E00082EDF0855782855683E030E301091E804A +:1010F000D4C234E9C395544002D2342202000622FD +:10110000303011901000E493F510901010E493F536 +:101110001012109012115022E4FCC3ED9FFAEFF56B +:101120008375820079FFE493CC6CCCA3D9F8DAF60E +:10113000E5E230E4028CE5ED24FFFFEF7582FFF578 +:1011400083E4936C70037F01227F00222211000050 +:10115000228E588F598C5A8D5B8A5C8B5D755E012F +:10116000E4F55FF560F56212072A7583D0E0FFC4ED +:10117000540FF561121EA585595ED3E55E955BE5BA +:101180005A12076B504B1207037583BCE0455E1281 +:1011900007297583BEE0455E1207297583C0E045C7 +:1011A0005EF0AF5FE560120878120AFFAF627E0062 +:1011B000AD5DAC5C120444E561AF5E7E00B4030536 +:1011C000121E218007AD5DAC5C121317055E021183 +:1011D0007A1207037583BCE045401207297583BE68 +:1011E000E045401207297583C0E04540F0228E5843 +:1011F0008F59755A017901755B01E4FB12072A7555 +:1012000083AEE0541AFF120865E0C4135407FEEFE2 +:10121000700CEE6535700790072FE0B4010DAF3507 +:101220007E00120EA9CFEBCF021E60E55964024585 +:101230005870047F0180027F00E559455870047E94 +:101240000180027E00EE4F602385414985404BE5D9 +:10125000594558702CAF5AFECDE9CDFCAB59AA5870 +:10126000120AFFAF5B7E00121E608015AF5B7E002E +:10127000121E60900726120735E549120731E54B2B +:10128000F0E4FDAF35FEFC120915228C648D651269 +:1012900008DA403CE56545647010120904C3E53E78 +:1012A000120769403B1208958018E53EC395384007 +:1012B0001D853E38E53E6005853F39800385393917 +:1012C0008F3A1207A8E53E120753E53FF022803B14 +:1012D000E5654564701112075F400512089E801F86 +:1012E00012073EE541F022E53CC39538401D853CA0 +:1012F00038E53C6005853D3980038539398F3A12E0 +:1013000007A8E53C120753E53DF02212079FE53898 +:10131000120753E539F0228C638D641208DA403CE1 +:10132000E56445637010120904C3E53E1207694085 +:101330003B1208958018E53EC39538401D853E3820 +:10134000E53E6005853F3980038539398F3A1207BC +:10135000A8E53E120753E53FF022803BE564456374 +:10136000701112075F400512089E801F12073EE5AC +:1013700041F022E53CC39538401D853C38E53C6092 +:1013800005853D3980038539398F3A1207A8E53C38 +:10139000120753E53DF02212079FE538120753E587 +:1013A00039F022E50DFEE5088E544405F555751516 +:1013B0000FF582120E7A1217A320310575150380DE +:1013C0000375150BE50AC39401503812142020311F +:1013D0000605150515800415151515E50AC39401B4 +:1013E0005021121420203104051580021515E50A3C +:1013F000C39401500E120E771217A3203105051564 +:10140000120E77E515B408047F0180027F00E51510 +:10141000B407047E0180027E00EE4F6002057F2249 +:10142000855582855483E515F01217A32212072AE9 +:101430007583AE74FF120729E0541AF534E0C41323 +:101440005407F53524FE602424FE603C24047063B8 +:1014500075312DE508FD74B612079274BC90072211 +:1014600012079574901207B37492803C75313AE577 +:1014700008FD74BA12079274C09007221207B6745E +:10148000C41207B374C88020753135E508FD74B8FF +:1014900012079274BEFFED4407900722CFF0A3EF2E +:1014A000F074C21207B374C6FFED4407A3CFF0A3D4 +:1014B000EFF022753401228E588F598C5A8D5B8A39 +:1014C0005C8B5D755E01E4F55F121EA585595ED3E8 +:1014D000E55E955BE55A12076B5057E55D455C701C +:1014E0003012072A758392E55E1207297583C6E5D7 +:1014F0005E1207297583C8E55E120729758390E59A +:101500005E1207297583C2E55E1207297583C480C0 +:1015100003120732E55EF0AF5F7E00AD5DAC5C129A +:101520000444AF5E7E00AD5DAC5C120BD1055E0283 +:1015300014CFAB5DAA5CAD5BAC5AAF59AE58021B81 +:10154000FB8C5C8D5D8A5E8B5F756001E4F561F5F7 +:1015500062F563121EA58F60D3E560955DE55C12B0 +:10156000076B5061E55F455E702712072A7583B6E9 +:10157000E5601207297583B8E5601207297583BAFB +:10158000E560F0AF617E00E56212087A120AFF8022 +:1015900019900724120735E56012072975838EE438 +:1015A0001207297401120729E4F0AF637E00AD5FD2 +:1015B000AC5E120444AF607E00AD5FAC5E12128B75 +:1015C00005600215582290114DE49390072EF012F9 +:1015D000081F7583AEE0541AF5347067EF4407F5C1 +:1015E000827583CEE0FF1313135407F536540FD3DF +:1015F0009400400612142D121BA9E536540F24FE48 +:10160000600C14600C146019240370378010021EE3 +:1016100091121E9112072A7583CEE054EFF0021D3D +:10162000AE121014E4F555121D850555E555C39409 +:101630000540F412072A7583CEE054C7120729E04B +:101640004408F022E4F558F559AF08EF4407F58255 +:101650007583D0E0FDC4540FF55AEF4407F5827549 +:1016600083807401F0120821758382E545F0EF4410 +:1016700007F58275838A74FFF0121A4D12072A75D6 +:1016800083BCE054EF1207297583BEE054EF1207C4 +:10169000297583C0E054EF1207297583BCE044101C +:1016A0001207297583BEE044101207297583C0E034 +:1016B0004410F0AF58E559120878020AFFE4F558D3 +:1016C0007D01F559AF35FEFC12091512072A758305 +:1016D000B674101207297583B87410120729758320 +:1016E000BA74101207297583BC7410120729758308 +:1016F000BE74101207297583C074101207297583F0 +:1017000090E41207297583C2E41207297583C4E4A3 +:10171000120729758392E41207297583C6E412071C +:10172000297583C8E4F0AF58FEE55912087A020A19 +:10173000FFE5E230E46CE5E754C064407064E5091D +:10174000C45430FEE50825E025E054C04EFEEF54B9 +:101750003F4EFDE52BAE2A7802C333CE33CED8F907 +:10176000F5828E83EDF0E52BAE2A7802C333CE33BB +:10177000CED8F9FFF5828E83A3E5FEF08F828E83AB +:10178000A3A3E5FDF08F828E83A3A3A3E5FCF0C3A2 +:10179000E52B94FAE52A94005008052BE52B7002FE +:1017A000052A22E4FFE4F558F556F5577482FC1239 +:1017B0000E048C83E0F510547FF0E5104480120E87 +:1017C00098EDF07E0A120E047583A0E020E026DE7C +:1017D000F40557E55770020556E5142401FDE4337E +:1017E000FCD3E5579DE5569C40D9E50A942050026C +:1017F000050A43E108C231120E047583A6E05512B2 +:1018000065127003D23122C23122900726E0FAA37A +:10181000E0F5828A83E0F541E539C395414026E54C +:10182000399541C39FEE12076B40047C0180027C16 +:1018300000E541643F60047B0180027B00EC5B605B +:101840002905418028C3E5419539C39FEE12076BF6 +:1018500040047F0180027F00E54160047E01800238 +:101860007E00EF5E600415418003853941853A4072 +:1018700022E5E230E460E5E130E25BE50970047FF7 +:101880000180027F00E50870047E0180027E00EE88 +:101890005F604353F9F8E5E230E43BE5E130E22EE6 +:1018A00043FA0253FAFBE4F510909470E510F0E56A +:1018B000E130E2E7909470E06510600343FA0405BC +:1018C00010909470E510F070E612000680E153FA73 +:1018D000FD53FAFB80C0228F54120006E5E130E090 +:1018E000047F0180027F00E57ED3940540047E01E1 +:1018F00080027E00EE4F603D855411E5E220E1322A +:1019000074CE121A0530E7047D0180027D008F82BB +:101910008E83E030E6047F0180027F00EF5D70156A +:101920001215C674CE121A0530E607E04480F04363 +:10193000F98012187122120E44E51625E025E024E4 +:10194000B0F582E4341AF583E493F50FE51625E04B +:1019500025E024B1F582E4341AF583E493F50E1200 +:101960000E65F510E50F54F0120E1775838CEFF02D +:10197000E50F30E00C120E04758386E04440F080E1 +:101980000A120E04758386E054BFF0120E9175831F +:1019900082E50EF0227F05121731120E04120E336B +:1019A0007402F0748EFE120E04120E0BEFF0751519 +:1019B00070120FF72034057515108003751550123D +:1019C0000FF72034047410800274F02515F51512F9 +:1019D0000E21EFF0121091203417E5156430600CE1 +:1019E00074102515F515B48003E4F515120E21EFDA +:1019F000F022F0E50B25E025E02482F582E43407AF +:101A0000F583227488FEE5084407FFF5828E83E0A3 +:101A100022F0E5084407F58222F0E054C08F828E60 +:101A200083F022EF4407F582758386E05410D39447 +:101A30000022F0900715E004F0224406F582758339 +:101A40009EE022FEEF4407F5828E83E022E49007B9 +:101A50002AF0A3F012072A758382E0547F12072927 +:101A6000E04480F01210FC12081F7583A0E020E013 +:101A70001A90072BE004F0700690072AE004F0901B +:101A8000072AE0B410E1A3E0B400DCEE44A6FCEFCA +:101A90004407F5828C83E0F532EE44A8FEEF44075C +:101AA000F5828E83E0F5332201201100042000909E +:101AB00000200F9200210F9400220F9600230F9810 +:101AC00000240F9A00250F9C00260F9E00270FA0D0 +:101AD000012001A2012101A4012201A6012301A8E4 +:101AE000012401AA012501AC012601AE012701B0A4 +:101AF000012801B400280FB640280FB8612801CB97 +:101B0000EFCBCAEECA7F01E4FDEB4A7024E508F58D +:101B10008274B6120829E508F58274B8120829E51E +:101B200008F58274BA1208297E007C00120AFF8030 +:101B300012900726120735E541F090072412073569 +:101B4000E540F012072A75838EE41207297401120A +:101B50000729E4F022E4F526F52753E1FEF52A757E +:101B60002B01F5087F0112173130301C901AA9E4BF +:101B700093F510901FF9E493F510900041E493F56C +:101B800010901ECAE493F5107F02121731120F5401 +:101B90007F03121731120006E5E230E70912100048 +:101BA00030300312110002004712081F7583D0E085 +:101BB000C4540FFD7543017544FF1208AA7404F064 +:101BC000753B01ED14600C14600B14600F2403705E +:101BD0000B800980001208A704F080061208A77481 +:101BE00004F0EE4482FEEF4407F5828E83E5451251 +:101BF00008BE758382E531F002114C8E608F611250 +:101C00001EA5E4FFCEEDCEEED39561E56012076B25 +:101C1000403974202EF582E43403F583E07003FF2D +:101C200080261208E2FDC39F401ECFEDCFEB4A7025 +:101C30000B8D421208EEF5418E40800C1208E2F541 +:101C4000381208EEF5398E3A1E80BC22755801E52F +:101C500035700C1207CCE0F54A1207D8E0F54CE5D8 +:101C600035B4040C1207E4E0F54A1207F0E0F54C35 +:101C7000E535B401047F0180027F00E535B402043C +:101C80007E0180027E00EE4F600C1207FCE0F54AF8 +:101C9000120808E0F54C85414985404B22755B01EF +:101CA000900724120735E0541FFFD3940250048F8D +:101CB000588005EF24FEF558EFC394184005755978 +:101CC000188004EF04F55985435AAF587E00AD598A +:101CD0007C00AB5B7A00121541AF5A7E0012180AE5 +:101CE000AF5B7E00021AFFE5E230E70E121003C27E +:101CF000303030031210FF203328E5E730E70512BB +:101D00000EA2800DE5FEC394205006120EA243F9E8 +:101D100008E5F230E70353F97FE5F15470D39400FE +:101D200050D822120E04758380E4F0E508440712AF +:101D30000DFD758384120E02758386120E02758363 +:101D40008CE054F3120E0375838E120E0275839489 +:101D5000E054FBF02212072A75838EE412072974DF +:101D600001120729E41208BE75838CE04420120892 +:101D7000BEE054DFF07484850882F583E0547FF080 +:101D8000E04480F022755601E4FDF557AF35FEFCC6 +:101D9000120915121C9D121E7A121C4CAF577E00A0 +:101DA000AD567C00120444AF567E000211EE75560B +:101DB00001E4FDF557AF35FEFC120915121C9D120A +:101DC0001E7A121C4CAF577E00AD567C00120444A4 +:101DD000AF567E000211EEE4F516120E44FEE50841 +:101DE0004405FF120E658F828E83F00516E516C33B +:101DF000941440E6E508120E2BE4F022E4F558F5C1 +:101E000059F55AFFFEAD58FC1209157F047E00AD4E +:101E1000587C001209157F027E00AD587C00020933 +:101E200015E53C253EFCE5422400FBE433FAECC317 +:101E30009BEA12076B400B8C42E53D253FF5418F35 +:101E4000402212090B227484F5188508198519821D +:101E5000851883E0547FF0E04480F0E04480F02275 +:101E6000EF4E700B12072A7583D2E054DFF0221276 +:101E7000072A7583D2E04420F02275580190072686 +:101E8000120735E0543FF541120732E0543FF54068 +:101E900022755602E4F557121DFCAF577E00AD5671 +:101EA0007C00020444E4F542F541F540F538F5398B +:101EB000F53A22EF5407FFE5F954F84FF5F9227F80 +:101EC00001E4FE0F0EBEFFFB2201200001042000F2 +:101ED0000000000000000000000000000000000002 +:101EE00000000000000000000000000000000000F2 +:101EF00000000000000000000000000000000000E2 +:101F000000000000000000000000000000000000D1 +:101F100000000000000000000000000000000000C1 +:101F200000000000000000000000000000000000B1 +:101F300000000000000000000000000000000000A1 +:101F40000000000000000000000000000000000091 +:101F50000000000000000000000000000000000081 +:101F60000000000000000000000000000000000071 +:101F70000000000000000000000000000000000061 +:101F80000000000000000000000000000000000051 +:101F90000000000000000000000000000000000041 +:101FA0000000000000000000000000000000000031 +:101FB0000000000000000000000000000000000021 +:101FC0000000000000000000000000000000000011 +:101FD0000000000000000000000000000000000001 +:101FE00000000000000000000000000000000000F1 +:101FF000000000000000000001201100042000810A +:00000001FF -- cgit v1.2.3-55-g7522 From 124dff01afbdbff251f0385beca84ba1b9adda68 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 5 Apr 2013 20:42:05 +0200 Subject: netfilter: don't reset nf_trace in nf_reset() Commit 130549fe ("netfilter: reset nf_trace in nf_reset") added code to reset nf_trace in nf_reset(). This is wrong and unnecessary. nf_reset() is used in the following cases: - when passing packets up the the socket layer, at which point we want to release all netfilter references that might keep modules pinned while the packet is queued. nf_trace doesn't matter anymore at this point. - when encapsulating or decapsulating IPsec packets. We want to continue tracing these packets after IPsec processing. - when passing packets through virtual network devices. Only devices on that encapsulate in IPv4/v6 matter since otherwise nf_trace is not used anymore. Its not entirely clear whether those packets should be traced after that, however we've always done that. - when passing packets through virtual network devices that make the packet cross network namespace boundaries. This is the only cases where we clearly want to reset nf_trace and is also what the original patch intended to fix. Add a new function nf_reset_trace() and use it in dev_forward_skb() to fix this properly. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/skbuff.h | 4 ++++ net/core/dev.c | 1 + 2 files changed, 5 insertions(+) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 72b396751de7..b8292d8cc9fa 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -2641,6 +2641,10 @@ static inline void nf_reset(struct sk_buff *skb) nf_bridge_put(skb->nf_bridge); skb->nf_bridge = NULL; #endif +} + +static inline void nf_reset_trace(struct sk_buff *skb) +{ #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) skb->nf_trace = 0; #endif diff --git a/net/core/dev.c b/net/core/dev.c index 13e6447f0398..e7d68ed8aafe 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1639,6 +1639,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) skb->mark = 0; secpath_reset(skb); nf_reset(skb); + nf_reset_trace(skb); return netif_rx(skb); } EXPORT_SYMBOL_GPL(dev_forward_skb); -- cgit v1.2.3-55-g7522 From 918708245e92941df16a634dc201b407d12bcd91 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 3 Apr 2013 15:47:33 +0100 Subject: x86: Fix rebuild with EFI_STUB enabled eboot.o and efi_stub_$(BITS).o didn't get added to "targets", and hence their .cmd files don't get included by the build machinery, leading to the files always getting rebuilt. Rather than adding the two files individually, take the opportunity and add $(VMLINUX_OBJS) to "targets" instead, thus allowing the assignment at the top of the file to be shrunk quite a bit. At the same time, remove a pointless flags override line - the variable assigned to was misspelled anyway, and the options added are meaningless for assembly sources. [ hpa: the patch is not minimal, but I am taking it for -urgent anyway since the excess impact of the patch seems to be small enough. ] Signed-off-by: Jan Beulich Link: http://lkml.kernel.org/r/515C5D2502000078000CA6AD@nat28.tlf.novell.com Cc: Matthew Garrett Cc: Matt Fleming Signed-off-by: H. Peter Anvin --- arch/x86/boot/compressed/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 8a84501acb1b..5ef205c5f37b 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -4,7 +4,7 @@ # create a compressed vmlinux image from the original vmlinux # -targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo head_$(BITS).o misc.o string.o cmdline.o early_serial_console.o piggy.o +targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma vmlinux.bin.xz vmlinux.bin.lzo KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 KBUILD_CFLAGS += -fno-strict-aliasing -fPIC @@ -29,7 +29,6 @@ VMLINUX_OBJS = $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \ $(obj)/piggy.o $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone -$(obj)/efi_stub_$(BITS).o: KBUILD_CLFAGS += -fshort-wchar -mno-red-zone ifeq ($(CONFIG_EFI_STUB), y) VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o @@ -43,7 +42,7 @@ OBJCOPYFLAGS_vmlinux.bin := -R .comment -S $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) -targets += vmlinux.bin.all vmlinux.relocs +targets += $(patsubst $(obj)/%,%,$(VMLINUX_OBJS)) vmlinux.bin.all vmlinux.relocs CMD_RELOCS = arch/x86/tools/relocs quiet_cmd_relocs = RELOCS $@ -- cgit v1.2.3-55-g7522 From 8f964525a121f2ff2df948dac908dcc65be21b5b Mon Sep 17 00:00:00 2001 From: Andrew Honig Date: Fri, 29 Mar 2013 09:35:21 -0700 Subject: KVM: Allow cross page reads and writes from cached translations. This patch adds support for kvm_gfn_to_hva_cache_init functions for reads and writes that will cross a page. If the range falls within the same memslot, then this will be a fast operation. If the range is split between two memslots, then the slower kvm_read_guest and kvm_write_guest are used. Tested: Test against kvm_clock unit tests. Signed-off-by: Andrew Honig Signed-off-by: Gleb Natapov --- arch/x86/kvm/lapic.c | 2 +- arch/x86/kvm/x86.c | 13 ++++++------- include/linux/kvm_host.h | 2 +- include/linux/kvm_types.h | 1 + virt/kvm/kvm_main.c | 47 +++++++++++++++++++++++++++++++++++++---------- 5 files changed, 46 insertions(+), 19 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 02b51dd4e4ad..f77df1c5de6e 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1857,7 +1857,7 @@ int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data) if (!pv_eoi_enabled(vcpu)) return 0; return kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.pv_eoi.data, - addr); + addr, sizeof(u8)); } void kvm_lapic_init(void) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f19ac0aca60d..e1721324c271 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1823,7 +1823,8 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) return 0; } - if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa)) + if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa, + sizeof(u32))) return 1; vcpu->arch.apf.send_user_only = !(data & KVM_ASYNC_PF_SEND_ALWAYS); @@ -1952,12 +1953,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) gpa_offset = data & ~(PAGE_MASK | 1); - /* Check that the address is 32-byte aligned. */ - if (gpa_offset & (sizeof(struct pvclock_vcpu_time_info) - 1)) - break; - if (kvm_gfn_to_hva_cache_init(vcpu->kvm, - &vcpu->arch.pv_time, data & ~1ULL)) + &vcpu->arch.pv_time, data & ~1ULL, + sizeof(struct pvclock_vcpu_time_info))) vcpu->arch.pv_time_enabled = false; else vcpu->arch.pv_time_enabled = true; @@ -1977,7 +1975,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) return 1; if (kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.st.stime, - data & KVM_STEAL_VALID_BITS)) + data & KVM_STEAL_VALID_BITS, + sizeof(struct kvm_steal_time))) return 1; vcpu->arch.st.msr_val = data; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index cad77fe09d77..c13958251927 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -518,7 +518,7 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data, int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, void *data, unsigned long len); int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, - gpa_t gpa); + gpa_t gpa, unsigned long len); int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len); int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len); struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn); diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h index fa7cc7244cbd..b0bcce0ddc95 100644 --- a/include/linux/kvm_types.h +++ b/include/linux/kvm_types.h @@ -71,6 +71,7 @@ struct gfn_to_hva_cache { u64 generation; gpa_t gpa; unsigned long hva; + unsigned long len; struct kvm_memory_slot *memslot; }; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index adc68feb5c5a..f18013f09e68 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1541,21 +1541,38 @@ int kvm_write_guest(struct kvm *kvm, gpa_t gpa, const void *data, } int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, - gpa_t gpa) + gpa_t gpa, unsigned long len) { struct kvm_memslots *slots = kvm_memslots(kvm); int offset = offset_in_page(gpa); - gfn_t gfn = gpa >> PAGE_SHIFT; + gfn_t start_gfn = gpa >> PAGE_SHIFT; + gfn_t end_gfn = (gpa + len - 1) >> PAGE_SHIFT; + gfn_t nr_pages_needed = end_gfn - start_gfn + 1; + gfn_t nr_pages_avail; ghc->gpa = gpa; ghc->generation = slots->generation; - ghc->memslot = gfn_to_memslot(kvm, gfn); - ghc->hva = gfn_to_hva_many(ghc->memslot, gfn, NULL); - if (!kvm_is_error_hva(ghc->hva)) + ghc->len = len; + ghc->memslot = gfn_to_memslot(kvm, start_gfn); + ghc->hva = gfn_to_hva_many(ghc->memslot, start_gfn, &nr_pages_avail); + if (!kvm_is_error_hva(ghc->hva) && nr_pages_avail >= nr_pages_needed) { ghc->hva += offset; - else - return -EFAULT; - + } else { + /* + * If the requested region crosses two memslots, we still + * verify that the entire region is valid here. + */ + while (start_gfn <= end_gfn) { + ghc->memslot = gfn_to_memslot(kvm, start_gfn); + ghc->hva = gfn_to_hva_many(ghc->memslot, start_gfn, + &nr_pages_avail); + if (kvm_is_error_hva(ghc->hva)) + return -EFAULT; + start_gfn += nr_pages_avail; + } + /* Use the slow path for cross page reads and writes. */ + ghc->memslot = NULL; + } return 0; } EXPORT_SYMBOL_GPL(kvm_gfn_to_hva_cache_init); @@ -1566,8 +1583,13 @@ int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, struct kvm_memslots *slots = kvm_memslots(kvm); int r; + BUG_ON(len > ghc->len); + if (slots->generation != ghc->generation) - kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa); + kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len); + + if (unlikely(!ghc->memslot)) + return kvm_write_guest(kvm, ghc->gpa, data, len); if (kvm_is_error_hva(ghc->hva)) return -EFAULT; @@ -1587,8 +1609,13 @@ int kvm_read_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, struct kvm_memslots *slots = kvm_memslots(kvm); int r; + BUG_ON(len > ghc->len); + if (slots->generation != ghc->generation) - kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa); + kvm_gfn_to_hva_cache_init(kvm, ghc, ghc->gpa, ghc->len); + + if (unlikely(!ghc->memslot)) + return kvm_read_guest(kvm, ghc->gpa, data, len); if (kvm_is_error_hva(ghc->hva)) return -EFAULT; -- cgit v1.2.3-55-g7522 From aa8b4be3ac049c8b1df2a87e4d1d902ccfc1f7a9 Mon Sep 17 00:00:00 2001 From: Jay Estabrook Date: Sun, 7 Apr 2013 21:36:09 +1200 Subject: alpha: Add irongate_io to PCI bus resources Fixes a NULL pointer dereference at boot on UP1500. Cc: stable@vger.kernel.org Reviewed-and-Tested-by: Matt Turner Signed-off-by: Jay Estabrook Signed-off-by: Matt Turner Signed-off-by: Michael Cree Signed-off-by: Linus Torvalds --- arch/alpha/kernel/sys_nautilus.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c index 4d4c046f708d..1383f8601a93 100644 --- a/arch/alpha/kernel/sys_nautilus.c +++ b/arch/alpha/kernel/sys_nautilus.c @@ -188,6 +188,10 @@ nautilus_machine_check(unsigned long vector, unsigned long la_ptr) extern void free_reserved_mem(void *, void *); extern void pcibios_claim_one_bus(struct pci_bus *); +static struct resource irongate_io = { + .name = "Irongate PCI IO", + .flags = IORESOURCE_IO, +}; static struct resource irongate_mem = { .name = "Irongate PCI MEM", .flags = IORESOURCE_MEM, @@ -209,6 +213,7 @@ nautilus_init_pci(void) irongate = pci_get_bus_and_slot(0, 0); bus->self = irongate; + bus->resource[0] = &irongate_io; bus->resource[1] = &irongate_mem; pci_bus_size_bridges(bus); -- cgit v1.2.3-55-g7522 From cd8d2331756751b6aeb855a3c9cb0a92fbd9c725 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Sun, 7 Apr 2013 21:36:10 +1200 Subject: alpha: makefile: don't enforce small data model for kernel builds Due to all of the goodness being packed into today's kernels, the resulting image isn't as slim as it once was. In light of this, don't pass -msmall-data to gcc, which otherwise results in link failures due to impossible relocations when compiling anything but the most trivial configurations. Cc: Richard Henderson Cc: Ivan Kokshaysky Reviewed-by: Matt Turner Tested-by: Thorsten Kranzkowski Signed-off-by: Will Deacon Signed-off-by: Michael Cree Signed-off-by: Linus Torvalds --- arch/alpha/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile index 4759fe751aa1..2cc3cc519c54 100644 --- a/arch/alpha/Makefile +++ b/arch/alpha/Makefile @@ -12,7 +12,7 @@ NM := $(NM) -B LDFLAGS_vmlinux := -static -N #-relax CHECKFLAGS += -D__alpha__ -m64 -cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data +cflags-y := -pipe -mno-fp-regs -ffixed-8 cflags-y += $(call cc-option, -fno-jump-tables) cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4 -- cgit v1.2.3-55-g7522 From e20800fd5cec2a75639a32e956b1cdc023cb87ce Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Sun, 7 Apr 2013 21:36:11 +1200 Subject: alpha: irq: run all handlers with interrupts disabled Linux has expected that interrupt handlers are executed with local interrupts disabled for a while now, so ensure that this is the case on Alpha even for non-device interrupts such as IPIs. Without this patch, secondary boot results in the following backtrace: warning: at kernel/softirq.c:139 __local_bh_enable+0xb8/0xd0() trace: __local_bh_enable+0xb8/0xd0 irq_enter+0x74/0xa0 scheduler_ipi+0x50/0x100 handle_ipi+0x84/0x260 do_entint+0x1ac/0x2e0 irq_exit+0x60/0xa0 handle_irq+0x98/0x100 do_entint+0x2c8/0x2e0 ret_from_sys_call+0x0/0x10 load_balance+0x3e4/0x870 cpu_idle+0x24/0x80 rcu_eqs_enter_common.isra.38+0x0/0x120 cpu_idle+0x40/0x80 rest_init+0xc0/0xe0 _stext+0x1c/0x20 A similar dump occurs if you try to reboot using magic-sysrq. Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Matt Turner Reviewed-by: Matt Turner Signed-off-by: Will Deacon Signed-off-by: Michael Cree Signed-off-by: Linus Torvalds --- arch/alpha/kernel/irq.c | 7 ------- arch/alpha/kernel/irq_alpha.c | 9 ++++++++- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c index 2872accd2215..7b2be251c30f 100644 --- a/arch/alpha/kernel/irq.c +++ b/arch/alpha/kernel/irq.c @@ -117,13 +117,6 @@ handle_irq(int irq) return; } - /* - * From here we must proceed with IPL_MAX. Note that we do not - * explicitly enable interrupts afterwards - some MILO PALcode - * (namely LX164 one) seems to have severe problems with RTI - * at IPL 0. - */ - local_irq_disable(); irq_enter(); generic_handle_irq_desc(irq, desc); irq_exit(); diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index 772ddfdb71a8..1216dfb4fcc5 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c @@ -45,6 +45,14 @@ do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr, struct pt_regs *regs) { struct pt_regs *old_regs; + + /* + * Disable interrupts during IRQ handling. + * Note that there is no matching local_irq_enable() due to + * severe problems with RTI at IPL0 and some MILO PALcode + * (namely LX164). + */ + local_irq_disable(); switch (type) { case 0: #ifdef CONFIG_SMP @@ -62,7 +70,6 @@ do_entInt(unsigned long type, unsigned long vector, { long cpu; - local_irq_disable(); smp_percpu_timer_interrupt(regs); cpu = smp_processor_id(); if (cpu != boot_cpuid) { -- cgit v1.2.3-55-g7522 From e74e25929ce4d4f5f5f4bae585b214bacef6960b Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Sun, 7 Apr 2013 21:36:12 +1200 Subject: alpha: irq: remove deprecated use of IRQF_DISABLED Interrupt handlers are always invoked with interrupts disabled, so remove all uses of the deprecated IRQF_DISABLED flag. Cc: Richard Henderson Cc: Ivan Kokshaysky Reviewed-by: Matt Turner Signed-off-by: Will Deacon Signed-off-by: Michael Cree Signed-off-by: Linus Torvalds --- arch/alpha/include/asm/floppy.h | 2 +- arch/alpha/kernel/irq_alpha.c | 1 - arch/alpha/kernel/sys_titan.c | 14 +++++++------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/arch/alpha/include/asm/floppy.h b/arch/alpha/include/asm/floppy.h index 46cefbd50e73..bae97eb19d26 100644 --- a/arch/alpha/include/asm/floppy.h +++ b/arch/alpha/include/asm/floppy.h @@ -26,7 +26,7 @@ #define fd_disable_irq() disable_irq(FLOPPY_IRQ) #define fd_cacheflush(addr,size) /* nothing */ #define fd_request_irq() request_irq(FLOPPY_IRQ, floppy_interrupt,\ - IRQF_DISABLED, "floppy", NULL) + 0, "floppy", NULL) #define fd_free_irq() free_irq(FLOPPY_IRQ, NULL) #ifdef CONFIG_PCI diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index 1216dfb4fcc5..f433fc11877a 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c @@ -229,7 +229,6 @@ process_mcheck_info(unsigned long vector, unsigned long la_ptr, struct irqaction timer_irqaction = { .handler = timer_interrupt, - .flags = IRQF_DISABLED, .name = "timer", }; diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 5cf4a481b8c5..a53cf03f49d5 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -280,15 +280,15 @@ titan_late_init(void) * all reported to the kernel as machine checks, so the handler * is a nop so it can be called to count the individual events. */ - titan_request_irq(63+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(63+16, titan_intr_nop, 0, "CChip Error", NULL); - titan_request_irq(62+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(62+16, titan_intr_nop, 0, "PChip 0 H_Error", NULL); - titan_request_irq(61+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(61+16, titan_intr_nop, 0, "PChip 1 H_Error", NULL); - titan_request_irq(60+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(60+16, titan_intr_nop, 0, "PChip 0 C_Error", NULL); - titan_request_irq(59+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(59+16, titan_intr_nop, 0, "PChip 1 C_Error", NULL); /* @@ -348,9 +348,9 @@ privateer_init_pci(void) * Hook a couple of extra err interrupts that the * common titan code won't. */ - titan_request_irq(53+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(53+16, titan_intr_nop, 0, "NMI", NULL); - titan_request_irq(50+16, titan_intr_nop, IRQF_DISABLED, + titan_request_irq(50+16, titan_intr_nop, 0, "Temperature Warning", NULL); /* -- cgit v1.2.3-55-g7522 From 31880c37c11e28cb81c70757e38392b42e695dc6 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 7 Apr 2013 20:49:54 -0700 Subject: Linux 3.9-rc6 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 58a165b02af1..6db672b15bda 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 9 SUBLEVEL = 0 -EXTRAVERSION = -rc5 +EXTRAVERSION = -rc6 NAME = Unicycling Gorilla # *DOCUMENTATION* -- cgit v1.2.3-55-g7522 From cab1e0a36c9dd0b0671fb84197ed294513f5adc1 Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Fri, 29 Mar 2013 16:20:09 +0100 Subject: ARM: clk-imx35: Bugfix iomux clock This patch enables iomuxc_gate clock. It is necessary to be able to reconfigure iomux pads. Without this clock enabled, the clk_disable_unused function will disable this clock and the iomux pads are not configurable anymore. This happens at every boot. After a reboot (watchdog system reset) the clock is not enabled again, so all iomux pad reconfigurations in boot code are without effect. The iomux pads should be always configurable, so this patch always enables it. Signed-off-by: Markus Pargmann Cc: stable@vger.kernel.org Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx35.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index e13a8fa5e62c..b95898a3912c 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -265,6 +265,7 @@ int __init mx35_clocks_init(void) clk_prepare_enable(clk[iim_gate]); clk_prepare_enable(clk[emi_gate]); clk_prepare_enable(clk[max_gate]); + clk_prepare_enable(clk[iomuxc_gate]); /* * SCC is needed to boot via mmc after a watchdog reset. The clock code -- cgit v1.2.3-55-g7522 From 75498083e25e96932ad998ffdeadb17234c68d3a Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Fri, 29 Mar 2013 16:20:10 +0100 Subject: ARM: imx35 Bugfix admux clock The admux clock seems to be the audmux clock as tests show. audmux does not work without this clock enabled. Currently imx35 does not register a clock device for audmux. This patch adds this registration. imx-audmux driver already handles a clock device, so no changes are necessary there. Signed-off-by: Markus Pargmann Cc: stable@vger.kernel.org Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx35.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index b95898a3912c..2193c834f55c 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -257,6 +257,7 @@ int __init mx35_clocks_init(void) clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0"); clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); + clk_register_clkdev(clk[admux_gate], "audmux", NULL); clk_prepare_enable(clk[spba_gate]); clk_prepare_enable(clk[gpio1_gate]); -- cgit v1.2.3-55-g7522 From 2bb4b70b1dbb45f0c1a3ba98066e6635d8aa3fe0 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 3 Apr 2013 23:50:09 +0800 Subject: ARM: imx: provide twd clock lookup from device tree While booting from device tree, imx6q used to provide twd clock lookup by calling clk_register_clkdev() in clock driver. However, the commit bd60345 (ARM: use device tree to get smp_twd clock) forces DT boot to look up the clock from device tree. It causes the failure below when twd driver tries to get the clock, and hence kernel has to calibrate the local timer frequency. smp_twd: clock not found -2 ... Calibrating local timer... 396.13MHz. Fix the regression by providing twd clock lookup from device tree, and remove the unused twd clk_register_clkdev() call from clock driver. Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl.dtsi | 1 + arch/arm/mach-imx/clk-imx6q.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 06ec460b4581..281a223591ff 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -91,6 +91,7 @@ compatible = "arm,cortex-a9-twd-timer"; reg = <0x00a00600 0x20>; interrupts = <1 13 0xf01>; + clocks = <&clks 15>; }; L2: l2-cache@00a02000 { diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 2f9ff93a4e61..22a3021a455b 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -443,7 +443,6 @@ int __init mx6q_clocks_init(void) clk_register_clkdev(clk[gpt_ipg], "ipg", "imx-gpt.0"); clk_register_clkdev(clk[gpt_ipg_per], "per", "imx-gpt.0"); - clk_register_clkdev(clk[twd], NULL, "smp_twd"); clk_register_clkdev(clk[cko1_sel], "cko1_sel", NULL); clk_register_clkdev(clk[ahb], "ahb", NULL); clk_register_clkdev(clk[cko1], "cko1", NULL); -- cgit v1.2.3-55-g7522 From e8094b2c17126c7dfdeafa296f206a4a3b122d23 Mon Sep 17 00:00:00 2001 From: Dirk Behme Date: Thu, 4 Apr 2013 16:03:29 +0200 Subject: ARM i.MX6: Fix ldb_di clock selection According to the recent i.MX6 Quad technical reference manual, mode 0x4 (100b) of the CCM_CS2DCR register (address 0x020C402C) bits [11-9] and [14-12] select the PLL3 clock, and not the PLL3 PFD1 540M clock. In our code, the PLL3 root clock is named 'pll3_usb_otg', select this instead of the 540M clock. Signed-off-by: Dirk Behme Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 22a3021a455b..d38e54f5b6d7 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -115,7 +115,7 @@ static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m" static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; -static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_pfd1_540m", }; +static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; -- cgit v1.2.3-55-g7522 From e27da53bae60247d87c29cf744fb92afce673d6a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 9 Apr 2013 08:58:22 +0200 Subject: ARM i.MX53: remove platform ahci support The i.MX53 ahci platform support is unused in mainline. To demotivate people using it just remove it from the tree. Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/devices/Kconfig | 4 - arch/arm/mach-imx/devices/Makefile | 1 - arch/arm/mach-imx/devices/devices-common.h | 10 -- arch/arm/mach-imx/devices/platform-ahci-imx.c | 157 -------------------------- 4 files changed, 172 deletions(-) delete mode 100644 arch/arm/mach-imx/devices/platform-ahci-imx.c diff --git a/arch/arm/mach-imx/devices/Kconfig b/arch/arm/mach-imx/devices/Kconfig index 9b9ba1f4ffe1..3dd2b1b041d1 100644 --- a/arch/arm/mach-imx/devices/Kconfig +++ b/arch/arm/mach-imx/devices/Kconfig @@ -86,7 +86,3 @@ config IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX config IMX_HAVE_PLATFORM_SPI_IMX bool - -config IMX_HAVE_PLATFORM_AHCI - bool - default y if ARCH_MX53 diff --git a/arch/arm/mach-imx/devices/Makefile b/arch/arm/mach-imx/devices/Makefile index 6acf37e0c119..67416fb1dc69 100644 --- a/arch/arm/mach-imx/devices/Makefile +++ b/arch/arm/mach-imx/devices/Makefile @@ -29,5 +29,4 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o -obj-$(CONFIG_IMX_HAVE_PLATFORM_AHCI) += platform-ahci-imx.o obj-$(CONFIG_IMX_HAVE_PLATFORM_MX2_EMMA) += platform-mx2-emma.o diff --git a/arch/arm/mach-imx/devices/devices-common.h b/arch/arm/mach-imx/devices/devices-common.h index 9bd5777ff0e7..453e20bc2657 100644 --- a/arch/arm/mach-imx/devices/devices-common.h +++ b/arch/arm/mach-imx/devices/devices-common.h @@ -344,13 +344,3 @@ struct platform_device *imx_add_imx_dma(char *name, resource_size_t iobase, int irq, int irq_err); struct platform_device *imx_add_imx_sdma(char *name, resource_size_t iobase, int irq, struct sdma_platform_data *pdata); - -#include -struct imx_ahci_imx_data { - const char *devid; - resource_size_t iobase; - resource_size_t irq; -}; -struct platform_device *__init imx_add_ahci_imx( - const struct imx_ahci_imx_data *data, - const struct ahci_platform_data *pdata); diff --git a/arch/arm/mach-imx/devices/platform-ahci-imx.c b/arch/arm/mach-imx/devices/platform-ahci-imx.c deleted file mode 100644 index 3d87dd9c284a..000000000000 --- a/arch/arm/mach-imx/devices/platform-ahci-imx.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include -#include -#include - -#include "../hardware.h" -#include "devices-common.h" - -#define imx_ahci_imx_data_entry_single(soc, _devid) \ - { \ - .devid = _devid, \ - .iobase = soc ## _SATA_BASE_ADDR, \ - .irq = soc ## _INT_SATA, \ - } - -#ifdef CONFIG_SOC_IMX53 -const struct imx_ahci_imx_data imx53_ahci_imx_data __initconst = - imx_ahci_imx_data_entry_single(MX53, "imx53-ahci"); -#endif - -enum { - HOST_CAP = 0x00, - HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ - HOST_PORTS_IMPL = 0x0c, - HOST_TIMER1MS = 0xe0, /* Timer 1-ms */ -}; - -static struct clk *sata_clk, *sata_ref_clk; - -/* AHCI module Initialization, if return 0, initialization is successful. */ -static int imx_sata_init(struct device *dev, void __iomem *addr) -{ - u32 tmpdata; - int ret = 0; - struct clk *clk; - - sata_clk = clk_get(dev, "ahci"); - if (IS_ERR(sata_clk)) { - dev_err(dev, "no sata clock.\n"); - return PTR_ERR(sata_clk); - } - ret = clk_prepare_enable(sata_clk); - if (ret) { - dev_err(dev, "can't prepare/enable sata clock.\n"); - goto put_sata_clk; - } - - /* Get the AHCI SATA PHY CLK */ - sata_ref_clk = clk_get(dev, "ahci_phy"); - if (IS_ERR(sata_ref_clk)) { - dev_err(dev, "no sata ref clock.\n"); - ret = PTR_ERR(sata_ref_clk); - goto release_sata_clk; - } - ret = clk_prepare_enable(sata_ref_clk); - if (ret) { - dev_err(dev, "can't prepare/enable sata ref clock.\n"); - goto put_sata_ref_clk; - } - - /* Get the AHB clock rate, and configure the TIMER1MS reg later */ - clk = clk_get(dev, "ahci_dma"); - if (IS_ERR(clk)) { - dev_err(dev, "no dma clock.\n"); - ret = PTR_ERR(clk); - goto release_sata_ref_clk; - } - tmpdata = clk_get_rate(clk) / 1000; - clk_put(clk); - - writel(tmpdata, addr + HOST_TIMER1MS); - - tmpdata = readl(addr + HOST_CAP); - if (!(tmpdata & HOST_CAP_SSS)) { - tmpdata |= HOST_CAP_SSS; - writel(tmpdata, addr + HOST_CAP); - } - - if (!(readl(addr + HOST_PORTS_IMPL) & 0x1)) - writel((readl(addr + HOST_PORTS_IMPL) | 0x1), - addr + HOST_PORTS_IMPL); - - return 0; - -release_sata_ref_clk: - clk_disable_unprepare(sata_ref_clk); -put_sata_ref_clk: - clk_put(sata_ref_clk); -release_sata_clk: - clk_disable_unprepare(sata_clk); -put_sata_clk: - clk_put(sata_clk); - - return ret; -} - -static void imx_sata_exit(struct device *dev) -{ - clk_disable_unprepare(sata_ref_clk); - clk_put(sata_ref_clk); - - clk_disable_unprepare(sata_clk); - clk_put(sata_clk); - -} -struct platform_device *__init imx_add_ahci_imx( - const struct imx_ahci_imx_data *data, - const struct ahci_platform_data *pdata) -{ - struct resource res[] = { - { - .start = data->iobase, - .end = data->iobase + SZ_4K - 1, - .flags = IORESOURCE_MEM, - }, { - .start = data->irq, - .end = data->irq, - .flags = IORESOURCE_IRQ, - }, - }; - - return imx_add_platform_device_dmamask(data->devid, 0, - res, ARRAY_SIZE(res), - pdata, sizeof(*pdata), DMA_BIT_MASK(32)); -} - -struct platform_device *__init imx53_add_ahci_imx(void) -{ - struct ahci_platform_data pdata = { - .init = imx_sata_init, - .exit = imx_sata_exit, - }; - - return imx_add_ahci_imx(&imx53_ahci_imx_data, &pdata); -} -- cgit v1.2.3-55-g7522 From 3442a7b51d1cfae144f3289ab0be44e27c236f53 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 9 Apr 2013 08:58:23 +0200 Subject: ARM: i.MX: remove unused ARCH_* configs This removes the unused Kconfig options ARCH_MX5, ARCH_MX51, ARCH_MX53 and MACH_MX21. Signed-off-by: Paul Bolle Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 4c9c6f9d2c55..6575e4ebe26e 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -83,24 +83,12 @@ config ARCH_MXC_IOMUX_V3 config ARCH_MX1 bool -config MACH_MX21 - bool - config ARCH_MX25 bool config MACH_MX27 bool -config ARCH_MX5 - bool - -config ARCH_MX51 - bool - -config ARCH_MX53 - bool - config SOC_IMX1 bool select ARCH_MX1 @@ -114,7 +102,6 @@ config SOC_IMX21 select COMMON_CLK select CPU_ARM926T select IMX_HAVE_IOMUX_V1 - select MACH_MX21 select MXC_AVIC config SOC_IMX25 @@ -155,7 +142,6 @@ config SOC_IMX35 config SOC_IMX5 bool select ARCH_HAS_CPUFREQ - select ARCH_MX5 select ARCH_MXC_IOMUX_V3 select COMMON_CLK select CPU_V7 @@ -163,8 +149,6 @@ config SOC_IMX5 config SOC_IMX51 bool - select ARCH_MX5 - select ARCH_MX51 select PINCTRL select PINCTRL_IMX51 select SOC_IMX5 @@ -789,8 +773,6 @@ comment "Device tree only" config SOC_IMX53 bool "i.MX53 support" - select ARCH_MX5 - select ARCH_MX53 select HAVE_CAN_FLEXCAN if CAN select IMX_HAVE_PLATFORM_IMX2_WDT select PINCTRL -- cgit v1.2.3-55-g7522 From 4e11f848c65b1c87782cb232a6e3b47a9d4c1f98 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 23 Oct 2012 15:45:56 -0600 Subject: dt: describe base reset signal binding This binding is intended to represent the hardware reset signals present internally in most IC (SoC, FPGA, ...) designs. It consists of a binding for a reset controller device (provider), and a pair of properties, "resets" and "reset-names", to link a device node (consumer) to its reset controller via phandle, similarly to the clock and interrupt bindings. The reset controller has all information necessary to reset the consumer device. That could be provided via device tree, or it could be implemented in hardware. The aim is to enable device drivers to request a framework API to issue a reset simply by providing their struct device pointer as the most common case. Signed-off-by: Stephen Warren Signed-off-by: Philipp Zabel Reviewed-by: Shawn Guo Reviewed-by: Marek Vasut Reviewed-by: Pavel Machek Acked-by: Rob Herring --- Documentation/devicetree/bindings/reset/reset.txt | 75 +++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/reset.txt diff --git a/Documentation/devicetree/bindings/reset/reset.txt b/Documentation/devicetree/bindings/reset/reset.txt new file mode 100644 index 000000000000..31db6ff84908 --- /dev/null +++ b/Documentation/devicetree/bindings/reset/reset.txt @@ -0,0 +1,75 @@ += Reset Signal Device Tree Bindings = + +This binding is intended to represent the hardware reset signals present +internally in most IC (SoC, FPGA, ...) designs. Reset signals for whole +standalone chips are most likely better represented as GPIOs, although there +are likely to be exceptions to this rule. + +Hardware blocks typically receive a reset signal. This signal is generated by +a reset provider (e.g. power management or clock module) and received by a +reset consumer (the module being reset, or a module managing when a sub- +ordinate module is reset). This binding exists to represent the provider and +consumer, and provide a way to couple the two together. + +A reset signal is represented by the phandle of the provider, plus a reset +specifier - a list of DT cells that represents the reset signal within the +provider. The length (number of cells) and semantics of the reset specifier +are dictated by the binding of the reset provider, although common schemes +are described below. + +A word on where to place reset signal consumers in device tree: It is possible +in hardware for a reset signal to affect multiple logically separate HW blocks +at once. In this case, it would be unwise to represent this reset signal in +the DT node of each affected HW block, since if activated, an unrelated block +may be reset. Instead, reset signals should be represented in the DT node +where it makes most sense to control it; this may be a bus node if all +children of the bus are affected by the reset signal, or an individual HW +block node for dedicated reset signals. The intent of this binding is to give +appropriate software access to the reset signals in order to manage the HW, +rather than to slavishly enumerate the reset signal that affects each HW +block. + += Reset providers = + +Required properties: +#reset-cells: Number of cells in a reset specifier; Typically 0 for nodes + with a single reset output and 1 for nodes with multiple + reset outputs. + +For example: + + rst: reset-controller { + #reset-cells = <1>; + }; + += Reset consumers = + +Required properties: +resets: List of phandle and reset specifier pairs, one pair + for each reset signal that affects the device, or that the + device manages. Note: if the reset provider specifies '0' for + #reset-cells, then only the phandle portion of the pair will + appear. + +Optional properties: +reset-names: List of reset signal name strings sorted in the same order as + the resets property. Consumers drivers will use reset-names to + match reset signal names with reset specifiers. + +For example: + + device { + resets = <&rst 20>; + reset-names = "reset"; + }; + +This represents a device with a single reset signal named "reset". + + bus { + resets = <&rst 10> <&rst 11> <&rst 12> <&rst 11>; + reset-names = "i2s1", "i2s2", "dma", "mixer"; + }; + +This represents a bus that controls the reset signal of each of four sub- +ordinate devices. Consider for example a bus that fails to operate unless no +child device has reset asserted. -- cgit v1.2.3-55-g7522 From 61fc41317666be400802ac793f47de816ef7bd57 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 19 Nov 2012 17:23:13 +0100 Subject: reset: Add reset controller API This adds a simple API for devices to request being reset by separate reset controller hardware and implements the reset signal device tree binding. Signed-off-by: Philipp Zabel Reviewed-by: Stephen Warren Reviewed-by: Shawn Guo Reviewed-by: Marek Vasut Reviewed-by: Pavel Machek --- drivers/Kconfig | 2 + drivers/Makefile | 3 + drivers/reset/Kconfig | 13 ++ drivers/reset/Makefile | 1 + drivers/reset/core.c | 297 +++++++++++++++++++++++++++++++++++++++ include/linux/reset-controller.h | 51 +++++++ include/linux/reset.h | 17 +++ 7 files changed, 384 insertions(+) create mode 100644 drivers/reset/Kconfig create mode 100644 drivers/reset/Makefile create mode 100644 drivers/reset/core.c create mode 100644 include/linux/reset-controller.h create mode 100644 include/linux/reset.h diff --git a/drivers/Kconfig b/drivers/Kconfig index 202fa6d051b9..847f8e31f3dd 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -162,4 +162,6 @@ source "drivers/irqchip/Kconfig" source "drivers/ipack/Kconfig" +source "drivers/reset/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index dce39a95fa71..1a64c4cd9094 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -37,6 +37,9 @@ obj-$(CONFIG_XEN) += xen/ # regulators early, since some subsystems rely on them to initialize obj-$(CONFIG_REGULATOR) += regulator/ +# reset controllers early, since gpu drivers might rely on them to initialize +obj-$(CONFIG_RESET_CONTROLLER) += reset/ + # tty/ comes before char/ so that the VT console is the boot-time # default. obj-y += tty/ diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig new file mode 100644 index 000000000000..c9d04f797862 --- /dev/null +++ b/drivers/reset/Kconfig @@ -0,0 +1,13 @@ +config ARCH_HAS_RESET_CONTROLLER + bool + +menuconfig RESET_CONTROLLER + bool "Reset Controller Support" + default y if ARCH_HAS_RESET_CONTROLLER + help + Generic Reset Controller support. + + This framework is designed to abstract reset handling of devices + via GPIOs or SoC-internal reset controller modules. + + If unsure, say no. diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile new file mode 100644 index 000000000000..1e2d83f2b995 --- /dev/null +++ b/drivers/reset/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_RESET_CONTROLLER) += core.o diff --git a/drivers/reset/core.c b/drivers/reset/core.c new file mode 100644 index 000000000000..a258277959b4 --- /dev/null +++ b/drivers/reset/core.c @@ -0,0 +1,297 @@ +/* + * Reset Controller framework + * + * Copyright 2013 Philipp Zabel, Pengutronix + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_MUTEX(reset_controller_list_mutex); +static LIST_HEAD(reset_controller_list); + +/** + * struct reset_control - a reset control + * @rcdev: a pointer to the reset controller device + * this reset control belongs to + * @id: ID of the reset controller in the reset + * controller device + */ +struct reset_control { + struct reset_controller_dev *rcdev; + struct device *dev; + unsigned int id; +}; + +/** + * of_reset_simple_xlate - translate reset_spec to the reset line number + * @rcdev: a pointer to the reset controller device + * @reset_spec: reset line specifier as found in the device tree + * @flags: a flags pointer to fill in (optional) + * + * This simple translation function should be used for reset controllers + * with 1:1 mapping, where reset lines can be indexed by number without gaps. + */ +int of_reset_simple_xlate(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec) +{ + if (WARN_ON(reset_spec->args_count != rcdev->of_reset_n_cells)) + return -EINVAL; + + if (reset_spec->args[0] >= rcdev->nr_resets) + return -EINVAL; + + return reset_spec->args[0]; +} +EXPORT_SYMBOL_GPL(of_reset_simple_xlate); + +/** + * reset_controller_register - register a reset controller device + * @rcdev: a pointer to the initialized reset controller device + */ +int reset_controller_register(struct reset_controller_dev *rcdev) +{ + if (!rcdev->of_xlate) { + rcdev->of_reset_n_cells = 1; + rcdev->of_xlate = of_reset_simple_xlate; + } + + mutex_lock(&reset_controller_list_mutex); + list_add(&rcdev->list, &reset_controller_list); + mutex_unlock(&reset_controller_list_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(reset_controller_register); + +/** + * reset_controller_unregister - unregister a reset controller device + * @rcdev: a pointer to the reset controller device + */ +void reset_controller_unregister(struct reset_controller_dev *rcdev) +{ + mutex_lock(&reset_controller_list_mutex); + list_del(&rcdev->list); + mutex_unlock(&reset_controller_list_mutex); +} +EXPORT_SYMBOL_GPL(reset_controller_unregister); + +/** + * reset_control_reset - reset the controlled device + * @rstc: reset controller + */ +int reset_control_reset(struct reset_control *rstc) +{ + if (rstc->rcdev->ops->reset) + return rstc->rcdev->ops->reset(rstc->rcdev, rstc->id); + + return -ENOSYS; +} +EXPORT_SYMBOL_GPL(reset_control_reset); + +/** + * reset_control_assert - asserts the reset line + * @rstc: reset controller + */ +int reset_control_assert(struct reset_control *rstc) +{ + if (rstc->rcdev->ops->assert) + return rstc->rcdev->ops->assert(rstc->rcdev, rstc->id); + + return -ENOSYS; +} +EXPORT_SYMBOL_GPL(reset_control_assert); + +/** + * reset_control_deassert - deasserts the reset line + * @rstc: reset controller + */ +int reset_control_deassert(struct reset_control *rstc) +{ + if (rstc->rcdev->ops->deassert) + return rstc->rcdev->ops->deassert(rstc->rcdev, rstc->id); + + return -ENOSYS; +} +EXPORT_SYMBOL_GPL(reset_control_deassert); + +/** + * reset_control_get - Lookup and obtain a reference to a reset controller. + * @dev: device to be reset by the controller + * @id: reset line name + * + * Returns a struct reset_control or IS_ERR() condition containing errno. + * + * Use of id names is optional. + */ +struct reset_control *reset_control_get(struct device *dev, const char *id) +{ + struct reset_control *rstc = ERR_PTR(-EPROBE_DEFER); + struct reset_controller_dev *r, *rcdev; + struct of_phandle_args args; + int index = 0; + int rstc_id; + int ret; + + if (!dev) + return ERR_PTR(-EINVAL); + + if (id) + index = of_property_match_string(dev->of_node, + "reset-names", id); + ret = of_parse_phandle_with_args(dev->of_node, "resets", "#reset-cells", + index, &args); + if (ret) + return ERR_PTR(ret); + + mutex_lock(&reset_controller_list_mutex); + rcdev = NULL; + list_for_each_entry(r, &reset_controller_list, list) { + if (args.np == r->of_node) { + rcdev = r; + break; + } + } + of_node_put(args.np); + + if (!rcdev) { + mutex_unlock(&reset_controller_list_mutex); + return ERR_PTR(-ENODEV); + } + + rstc_id = rcdev->of_xlate(rcdev, &args); + if (rstc_id < 0) { + mutex_unlock(&reset_controller_list_mutex); + return ERR_PTR(rstc_id); + } + + try_module_get(rcdev->owner); + mutex_unlock(&reset_controller_list_mutex); + + rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); + if (!rstc) { + module_put(rstc->rcdev->owner); + return ERR_PTR(-ENOMEM); + } + + rstc->dev = dev; + rstc->rcdev = rcdev; + rstc->id = rstc_id; + + return rstc; +} +EXPORT_SYMBOL_GPL(reset_control_get); + +/** + * reset_control_put - free the reset controller + * @rstc: reset controller + */ + +void reset_control_put(struct reset_control *rstc) +{ + if (IS_ERR(rstc)) + return; + + module_put(rstc->rcdev->owner); + kfree(rstc); +} +EXPORT_SYMBOL_GPL(reset_control_put); + +static void devm_reset_control_release(struct device *dev, void *res) +{ + reset_control_put(*(struct reset_control **)res); +} + +/** + * devm_reset_control_get - resource managed reset_control_get() + * @dev: device to be reset by the controller + * @id: reset line name + * + * Managed reset_control_get(). For reset controllers returned from this + * function, reset_control_put() is called automatically on driver detach. + * See reset_control_get() for more information. + */ +struct reset_control *devm_reset_control_get(struct device *dev, const char *id) +{ + struct reset_control **ptr, *rstc; + + ptr = devres_alloc(devm_reset_control_release, sizeof(*ptr), + GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + rstc = reset_control_get(dev, id); + if (!IS_ERR(rstc)) { + *ptr = rstc; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return rstc; +} +EXPORT_SYMBOL_GPL(devm_reset_control_get); + +static int devm_reset_control_match(struct device *dev, void *res, void *data) +{ + struct reset_control **rstc = res; + if (WARN_ON(!rstc || !*rstc)) + return 0; + return *rstc == data; +} + +/** + * devm_reset_control_put - resource managed reset_control_put() + * @rstc: reset controller to free + * + * Deallocate a reset control allocated withd devm_reset_control_get(). + * This function will not need to be called normally, as devres will take + * care of freeing the resource. + */ +void devm_reset_control_put(struct reset_control *rstc) +{ + int ret; + + ret = devres_release(rstc->dev, devm_reset_control_release, + devm_reset_control_match, rstc); + if (ret) + WARN_ON(ret); +} +EXPORT_SYMBOL_GPL(devm_reset_control_put); + +/** + * device_reset - find reset controller associated with the device + * and perform reset + * @dev: device to be reset by the controller + * + * Convenience wrapper for reset_control_get() and reset_control_reset(). + * This is useful for the common case of devices with single, dedicated reset + * lines. + */ +int device_reset(struct device *dev) +{ + struct reset_control *rstc; + int ret; + + rstc = reset_control_get(dev, NULL); + if (IS_ERR(rstc)) + return PTR_ERR(rstc); + + ret = reset_control_reset(rstc); + + reset_control_put(rstc); + + return ret; +} +EXPORT_SYMBOL_GPL(device_reset); diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h new file mode 100644 index 000000000000..2f61311ae3e0 --- /dev/null +++ b/include/linux/reset-controller.h @@ -0,0 +1,51 @@ +#ifndef _LINUX_RESET_CONTROLLER_H_ +#define _LINUX_RESET_CONTROLLER_H_ + +#include + +struct reset_controller_dev; + +/** + * struct reset_control_ops + * + * @reset: for self-deasserting resets, does all necessary + * things to reset the device + * @assert: manually assert the reset line, if supported + * @deassert: manually deassert the reset line, if supported + */ +struct reset_control_ops { + int (*reset)(struct reset_controller_dev *rcdev, unsigned long id); + int (*assert)(struct reset_controller_dev *rcdev, unsigned long id); + int (*deassert)(struct reset_controller_dev *rcdev, unsigned long id); +}; + +struct module; +struct device_node; + +/** + * struct reset_controller_dev - reset controller entity that might + * provide multiple reset controls + * @ops: a pointer to device specific struct reset_control_ops + * @owner: kernel module of the reset controller driver + * @list: internal list of reset controller devices + * @of_node: corresponding device tree node as phandle target + * @of_reset_n_cells: number of cells in reset line specifiers + * @of_xlate: translation function to translate from specifier as found in the + * device tree to id as given to the reset control ops + * @nr_resets: number of reset controls in this reset controller device + */ +struct reset_controller_dev { + struct reset_control_ops *ops; + struct module *owner; + struct list_head list; + struct device_node *of_node; + int of_reset_n_cells; + int (*of_xlate)(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec); + unsigned int nr_resets; +}; + +int reset_controller_register(struct reset_controller_dev *rcdev); +void reset_controller_unregister(struct reset_controller_dev *rcdev); + +#endif diff --git a/include/linux/reset.h b/include/linux/reset.h new file mode 100644 index 000000000000..6082247feab1 --- /dev/null +++ b/include/linux/reset.h @@ -0,0 +1,17 @@ +#ifndef _LINUX_RESET_H_ +#define _LINUX_RESET_H_ + +struct device; +struct reset_control; + +int reset_control_reset(struct reset_control *rstc); +int reset_control_assert(struct reset_control *rstc); +int reset_control_deassert(struct reset_control *rstc); + +struct reset_control *reset_control_get(struct device *dev, const char *id); +void reset_control_put(struct reset_control *rstc); +struct reset_control *devm_reset_control_get(struct device *dev, const char *id); + +int device_reset(struct device *dev); + +#endif -- cgit v1.2.3-55-g7522 From 6034bb22d8387708075c083385e5d2e1072a4f33 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 3 Apr 2013 08:02:53 +0300 Subject: reset: NULL deref on allocation failure "rstc" is NULL here and we should use "rcdev" instead of "rstc->rcdev". Signed-off-by: Dan Carpenter Signed-off-by: Philipp Zabel --- drivers/reset/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index a258277959b4..d1b6089a0ef8 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -181,7 +181,7 @@ struct reset_control *reset_control_get(struct device *dev, const char *id) rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); if (!rstc) { - module_put(rstc->rcdev->owner); + module_put(rcdev->owner); return ERR_PTR(-ENOMEM); } -- cgit v1.2.3-55-g7522 From e95dddb34c896f33e89f97365491e7932f89a0c0 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 20 Mar 2013 19:39:42 -0400 Subject: ARM: imx: enable anatop suspend/resume Anatop module have sereval configurations for user to reduce the power consumption in suspend, provide suspend/resume interface for further use and enable fet_odrive to reduce CORE LDO leakage during suspend. As we have a common anatop file, remove all the operations of anatop module in other files, use anatop interfaces to do that. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 4 +++ arch/arm/mach-imx/Makefile | 1 + arch/arm/mach-imx/anatop.c | 74 ++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/common.h | 7 +++- arch/arm/mach-imx/mach-imx6q.c | 48 ++++----------------------- arch/arm/mach-imx/pm-imx6q.c | 4 ++- 6 files changed, 94 insertions(+), 44 deletions(-) create mode 100644 arch/arm/mach-imx/anatop.c diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 6575e4ebe26e..f694074f2302 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -65,6 +65,9 @@ config IRAM_ALLOC bool select GENERIC_ALLOCATOR +config HAVE_IMX_ANATOP + bool + config HAVE_IMX_GPC bool @@ -795,6 +798,7 @@ config SOC_IMX6Q select CPU_V7 select HAVE_ARM_SCU select HAVE_CAN_FLEXCAN if CAN + select HAVE_IMX_ANATOP select HAVE_IMX_GPC select HAVE_IMX_MMDC select HAVE_IMX_SRC diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 23555b0c08a9..b16eb39b9f5d 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_MACH_EUKREA_CPUIMX35SD) += mach-cpuimx35.o obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o +obj-$(CONFIG_HAVE_IMX_ANATOP) += anatop.o obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o obj-$(CONFIG_HAVE_IMX_MMDC) += mmdc.o obj-$(CONFIG_HAVE_IMX_SRC) += src.o diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c new file mode 100644 index 000000000000..b396b92526d3 --- /dev/null +++ b/arch/arm/mach-imx/anatop.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2013 Freescale Semiconductor, Inc. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include + +#define REG_SET 0x4 +#define REG_CLR 0x8 + +#define ANADIG_REG_CORE 0x140 +#define ANADIG_USB1_CHRG_DETECT 0x1b0 +#define ANADIG_USB2_CHRG_DETECT 0x210 +#define ANADIG_DIGPROG 0x260 + +#define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 +#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000 +#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000 + +static struct regmap *anatop; + +static void imx_anatop_enable_fet_odrive(bool enable) +{ + regmap_write(anatop, ANADIG_REG_CORE + (enable ? REG_SET : REG_CLR), + BM_ANADIG_REG_CORE_FET_ODRIVE); +} + +void imx_anatop_pre_suspend(void) +{ + imx_anatop_enable_fet_odrive(true); +} + +void imx_anatop_post_resume(void) +{ + imx_anatop_enable_fet_odrive(false); +} + +void imx_anatop_usb_chrg_detect_disable(void) +{ + regmap_write(anatop, ANADIG_USB1_CHRG_DETECT, + BM_ANADIG_USB_CHRG_DETECT_EN_B + | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); + regmap_write(anatop, ANADIG_USB2_CHRG_DETECT, + BM_ANADIG_USB_CHRG_DETECT_EN_B | + BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); +} + +u32 imx_anatop_get_digprog(void) +{ + u32 val; + + regmap_read(anatop, ANADIG_DIGPROG, &val); + return val; +} + +void __init imx_anatop_init(void) +{ + anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop"); + if (IS_ERR(anatop)) { + pr_err("%s: failed to find imx6q-anatop regmap!\n", __func__); + return; + } +} diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 9fea2522d7a3..d557bf383289 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved. */ /* @@ -128,6 +128,11 @@ extern void imx_src_prepare_restart(void); extern void imx_gpc_init(void); extern void imx_gpc_pre_suspend(void); extern void imx_gpc_post_resume(void); +extern void imx_anatop_init(void); +extern void imx_anatop_pre_suspend(void); +extern void imx_anatop_post_resume(void); +extern void imx_anatop_usb_chrg_detect_disable(void); +extern u32 imx_anatop_get_digprog(void); extern int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); extern void imx6q_set_chicken_bit(void); diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 9ffd103b27e4..31aee4d5fcdd 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -39,27 +39,12 @@ #include "cpuidle.h" #include "hardware.h" -#define IMX6Q_ANALOG_DIGPROG 0x260 - static int imx6q_revision(void) { - struct device_node *np; - void __iomem *base; static u32 rev; - if (!rev) { - np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); - if (!np) - return IMX_CHIP_REVISION_UNKNOWN; - base = of_iomap(np, 0); - if (!base) { - of_node_put(np); - return IMX_CHIP_REVISION_UNKNOWN; - } - rev = readl_relaxed(base + IMX6Q_ANALOG_DIGPROG); - iounmap(base); - of_node_put(np); - } + if (!rev) + rev = imx_anatop_get_digprog(); switch (rev & 0xff) { case 0: @@ -165,29 +150,7 @@ static void __init imx6q_1588_init(void) } static void __init imx6q_usb_init(void) { - struct regmap *anatop; - -#define HW_ANADIG_USB1_CHRG_DETECT 0x000001b0 -#define HW_ANADIG_USB2_CHRG_DETECT 0x00000210 - -#define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x00100000 -#define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x00080000 - - anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop"); - if (!IS_ERR(anatop)) { - /* - * The external charger detector needs to be disabled, - * or the signal at DP will be poor - */ - regmap_write(anatop, HW_ANADIG_USB1_CHRG_DETECT, - BM_ANADIG_USB_CHRG_DETECT_EN_B - | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); - regmap_write(anatop, HW_ANADIG_USB2_CHRG_DETECT, - BM_ANADIG_USB_CHRG_DETECT_EN_B | - BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B); - } else { - pr_warn("failed to find fsl,imx6q-anatop regmap\n"); - } + imx_anatop_usb_chrg_detect_disable(); } static void __init imx6q_init_machine(void) @@ -197,9 +160,11 @@ static void __init imx6q_init_machine(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + imx_anatop_init(); imx6q_pm_init(); imx6q_usb_init(); imx6q_1588_init(); + imx_print_silicon_rev("i.MX6Q", imx6q_revision()); } #define OCOTP_CFG3 0x440 @@ -293,7 +258,6 @@ static void __init imx6q_timer_init(void) { mx6q_clocks_init(); twd_local_timer_of_register(); - imx_print_silicon_rev("i.MX6Q", imx6q_revision()); } static const char *imx6q_dt_compat[] __initdata = { diff --git a/arch/arm/mach-imx/pm-imx6q.c b/arch/arm/mach-imx/pm-imx6q.c index 5faba7a3c95f..204942749e21 100644 --- a/arch/arm/mach-imx/pm-imx6q.c +++ b/arch/arm/mach-imx/pm-imx6q.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -34,10 +34,12 @@ static int imx6q_pm_enter(suspend_state_t state) case PM_SUSPEND_MEM: imx6q_set_lpm(STOP_POWER_OFF); imx_gpc_pre_suspend(); + imx_anatop_pre_suspend(); imx_set_cpu_jump(0, v7_cpu_resume); /* Zzz ... */ cpu_suspend(0, imx6q_suspend_finish); imx_smp_prepare(); + imx_anatop_post_resume(); imx_gpc_post_resume(); imx6q_set_lpm(WAIT_CLOCKED); break; -- cgit v1.2.3-55-g7522 From e7b82d645d8b0345508d4b7be85e10f961fbfa3e Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 20 Mar 2013 19:39:43 -0400 Subject: ARM: imx: enable periphery well bias for suspend Enable periphery charge pump for well biasing at suspend to reduce periphery leakage. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index d38e54f5b6d7..262b7b6c79aa 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -23,6 +23,9 @@ #include "clk.h" #include "common.h" +#define CCR 0x0 +#define BM_CCR_WB_COUNT (0x7 << 16) + #define CCGR0 0x68 #define CCGR1 0x6c #define CCGR2 0x70 @@ -67,6 +70,29 @@ void imx6q_set_chicken_bit(void) writel_relaxed(val, ccm_base + CGPR); } +static void imx6q_enable_wb(bool enable) +{ + u32 val; + static bool last_wb_mode; + + if (last_wb_mode == enable) + return; + + /* configure well bias enable bit */ + val = readl_relaxed(ccm_base + CLPCR); + val &= ~BM_CLPCR_WB_PER_AT_LPM; + val |= enable ? BM_CLPCR_WB_PER_AT_LPM : 0; + writel_relaxed(val, ccm_base + CLPCR); + + /* configure well bias count */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_WB_COUNT; + val |= enable ? BM_CCR_WB_COUNT : 0; + writel_relaxed(val, ccm_base + CCR); + + last_wb_mode = enable; +} + int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) { u32 val = readl_relaxed(ccm_base + CLPCR); @@ -74,6 +100,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) val &= ~BM_CLPCR_LPM; switch (mode) { case WAIT_CLOCKED: + imx6q_enable_wb(false); break; case WAIT_UNCLOCKED: val |= 0x1 << BP_CLPCR_LPM; @@ -92,6 +119,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) val |= 0x3 << BP_CLPCR_STBY_COUNT; val |= BM_CLPCR_VSTBY; val |= BM_CLPCR_SBYOS; + imx6q_enable_wb(true); break; default: return -EINVAL; -- cgit v1.2.3-55-g7522 From 263475d4e0b0623fb7a22f8ac0a5c01017eabf20 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Thu, 21 Mar 2013 10:58:06 -0400 Subject: ARM: imx: enable RBC to support anatop LPM mode RBC is to control whether some ANATOP sub modules can enter lpm mode when SOC is into STOP mode, if RBC is enabled and PMIC_VSTBY_REQ is set, ANATOP will have below behaviors: 1. Digital LDOs(CORE, SOC and PU) are bypassed; 2. Analog LDOs(1P1, 2P5, 3P0) are disabled; As the 2P5 is necessary for DRAM IO pre-drive in STOP mode, so we need to enable weak 2P5 in STOP mode when 2P5 LDO is disabled. For RBC settings, there are some rules as below due to hardware design: 1. All interrupts must be masked during operating RBC registers; 2. At least 2 CKIL(32K) cycles is needed after the RBC setting is changed. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/anatop.c | 19 +++++++++++++++++++ arch/arm/mach-imx/clk-imx6q.c | 43 +++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-imx/common.h | 2 ++ arch/arm/mach-imx/gpc.c | 23 ++++++++++++++++++++++- 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index b396b92526d3..8b18b3c3bcf0 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -19,17 +19,34 @@ #define REG_SET 0x4 #define REG_CLR 0x8 +#define ANADIG_REG_2P5 0x130 #define ANADIG_REG_CORE 0x140 +#define ANADIG_ANA_MISC0 0x150 #define ANADIG_USB1_CHRG_DETECT 0x1b0 #define ANADIG_USB2_CHRG_DETECT 0x210 #define ANADIG_DIGPROG 0x260 +#define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 #define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 +#define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG 0x1000 #define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B 0x80000 #define BM_ANADIG_USB_CHRG_DETECT_EN_B 0x100000 static struct regmap *anatop; +static void imx_anatop_enable_weak2p5(bool enable) +{ + u32 reg, val; + + regmap_read(anatop, ANADIG_ANA_MISC0, &val); + + /* can only be enabled when stop_mode_config is clear. */ + reg = ANADIG_REG_2P5; + reg += (enable && (val & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) ? + REG_SET : REG_CLR; + regmap_write(anatop, reg, BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG); +} + static void imx_anatop_enable_fet_odrive(bool enable) { regmap_write(anatop, ANADIG_REG_CORE + (enable ? REG_SET : REG_CLR), @@ -38,12 +55,14 @@ static void imx_anatop_enable_fet_odrive(bool enable) void imx_anatop_pre_suspend(void) { + imx_anatop_enable_weak2p5(true); imx_anatop_enable_fet_odrive(true); } void imx_anatop_post_resume(void) { imx_anatop_enable_fet_odrive(false); + imx_anatop_enable_weak2p5(false); } void imx_anatop_usb_chrg_detect_disable(void) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 262b7b6c79aa..23b799a51e6c 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,8 @@ #define CCR 0x0 #define BM_CCR_WB_COUNT (0x7 << 16) +#define BM_CCR_RBC_BYPASS_COUNT (0x3f << 21) +#define BM_CCR_RBC_EN (0x1 << 27) #define CCGR0 0x68 #define CCGR1 0x6c @@ -70,6 +73,44 @@ void imx6q_set_chicken_bit(void) writel_relaxed(val, ccm_base + CGPR); } +static void imx6q_enable_rbc(bool enable) +{ + u32 val; + static bool last_rbc_mode; + + if (last_rbc_mode == enable) + return; + /* + * need to mask all interrupts in GPC before + * operating RBC configurations + */ + imx_gpc_mask_all(); + + /* configure RBC enable bit */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_RBC_EN; + val |= enable ? BM_CCR_RBC_EN : 0; + writel_relaxed(val, ccm_base + CCR); + + /* configure RBC count */ + val = readl_relaxed(ccm_base + CCR); + val &= ~BM_CCR_RBC_BYPASS_COUNT; + val |= enable ? BM_CCR_RBC_BYPASS_COUNT : 0; + writel(val, ccm_base + CCR); + + /* + * need to delay at least 2 cycles of CKIL(32K) + * due to hardware design requirement, which is + * ~61us, here we use 65us for safe + */ + udelay(65); + + /* restore GPC interrupt mask settings */ + imx_gpc_restore_all(); + + last_rbc_mode = enable; +} + static void imx6q_enable_wb(bool enable) { u32 val; @@ -101,6 +142,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) switch (mode) { case WAIT_CLOCKED: imx6q_enable_wb(false); + imx6q_enable_rbc(false); break; case WAIT_UNCLOCKED: val |= 0x1 << BP_CLPCR_LPM; @@ -120,6 +162,7 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) val |= BM_CLPCR_VSTBY; val |= BM_CLPCR_SBYOS; imx6q_enable_wb(true); + imx6q_enable_rbc(true); break; default: return -EINVAL; diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index d557bf383289..bcb11b1751d8 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -128,6 +128,8 @@ extern void imx_src_prepare_restart(void); extern void imx_gpc_init(void); extern void imx_gpc_pre_suspend(void); extern void imx_gpc_post_resume(void); +extern void imx_gpc_mask_all(void); +extern void imx_gpc_restore_all(void); extern void imx_anatop_init(void); extern void imx_anatop_pre_suspend(void); extern void imx_anatop_post_resume(void); diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index a96ccc7f5012..c20445c56032 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -1,5 +1,5 @@ /* - * Copyright 2011 Freescale Semiconductor, Inc. + * Copyright 2011-2013 Freescale Semiconductor, Inc. * Copyright 2011 Linaro Ltd. * * The code contained herein is licensed under the GNU General Public @@ -68,6 +68,27 @@ static int imx_gpc_irq_set_wake(struct irq_data *d, unsigned int on) return 0; } +void imx_gpc_mask_all(void) +{ + void __iomem *reg_imr1 = gpc_base + GPC_IMR1; + int i; + + for (i = 0; i < IMR_NUM; i++) { + gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4); + writel_relaxed(~0, reg_imr1 + i * 4); + } + +} + +void imx_gpc_restore_all(void) +{ + void __iomem *reg_imr1 = gpc_base + GPC_IMR1; + int i; + + for (i = 0; i < IMR_NUM; i++) + writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); +} + static void imx_gpc_irq_unmask(struct irq_data *d) { void __iomem *reg; -- cgit v1.2.3-55-g7522 From fcc4f9fc5b23e6bb80f2c7833da323a485cad1b6 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 25 Mar 2013 09:20:41 -0300 Subject: ARM: mach-imx: anatop: Include "common.h" Fix the following sparse warnings: arch/arm/mach-imx/anatop.c:56:6: warning: symbol 'imx_anatop_pre_suspend' was not declared. Should it be static? arch/arm/mach-imx/anatop.c:62:6: warning: symbol 'imx_anatop_post_resume' was not declared. Should it be static? arch/arm/mach-imx/anatop.c:68:6: warning: symbol 'imx_anatop_usb_chrg_detect_disable' was not declared. Should it be static? arch/arm/mach-imx/anatop.c:78:5: warning: symbol 'imx_anatop_get_digprog' was not declared. Should it be static? arch/arm/mach-imx/anatop.c:86:13: warning: symbol 'imx_anatop_init' was not declared. Should it be static? Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-imx/anatop.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 8b18b3c3bcf0..472beee9cd98 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -15,6 +15,7 @@ #include #include #include +#include "common.h" #define REG_SET 0x4 #define REG_CLR 0x8 -- cgit v1.2.3-55-g7522 From 8ecb167f4978d86fa39d6a9c533a4c1ef3169c81 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 27 Mar 2013 10:51:33 +0100 Subject: ARM i.MX53: Add GPU clocks to clock tree This patch adds the missing GPU2D and GPU3D mux and gate clocks, and the graphics arbiter gate clock. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/clock/imx5-clock.txt | 5 +++++ arch/arm/mach-imx/clk-imx51-imx53.c | 9 ++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.txt b/Documentation/devicetree/bindings/clock/imx5-clock.txt index 2a0c904c46ae..342ad0fce53d 100644 --- a/Documentation/devicetree/bindings/clock/imx5-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx5-clock.txt @@ -172,6 +172,11 @@ clocks and IDs. can1_serial_gate 157 can1_ipg_gate 158 owire_gate 159 + gpu3d_s 160 + gpu2d_s 161 + gpu3d_gate 162 + gpu2d_gate 163 + garb_gate 164 Examples (for mx53): diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index 0f39f8c93b94..fdd86571aa6a 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -47,6 +47,8 @@ static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", }; static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", }; static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", }; static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; +static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; +static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", }; @@ -83,7 +85,7 @@ enum imx5_clks { ssi2_root_gate, ssi3_root_gate, ssi_ext1_gate, ssi_ext2_gate, epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate, can_sel, can1_serial_gate, can1_ipg_gate, - owire_gate, + owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate, clk_max }; @@ -200,6 +202,11 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk[nfc_gate] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20); clk[ipu_di0_gate] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10); clk[ipu_di1_gate] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12); + clk[gpu3d_s] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel)); + clk[gpu2d_s] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel)); + clk[gpu3d_gate] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2); + clk[garb_gate] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4); + clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14); clk[vpu_s] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel)); clk[vpu_gate] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6); clk[vpu_reference_gate] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8); -- cgit v1.2.3-55-g7522 From 686631042325a209766be89b5566b426875ca05e Mon Sep 17 00:00:00 2001 From: Markus Pargmann Date: Wed, 27 Mar 2013 14:01:31 +0100 Subject: ARM: imx27, imx5: Add kconfig selects for cpufreq-cpu0 There are some config options not selected by imx27 and imx5 that are necessary to use the cpufreq-cpu0 driver. Signed-off-by: Markus Pargmann Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index f694074f2302..1ab069cf722f 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -118,6 +118,8 @@ config SOC_IMX25 config SOC_IMX27 bool + select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP select COMMON_CLK select CPU_ARM926T select IMX_HAVE_IOMUX_V1 @@ -145,6 +147,7 @@ config SOC_IMX35 config SOC_IMX5 bool select ARCH_HAS_CPUFREQ + select ARCH_HAS_OPP select ARCH_MXC_IOMUX_V3 select COMMON_CLK select CPU_V7 -- cgit v1.2.3-55-g7522 From b1a3582dc6f1f85a56b60f688305a5194e266e02 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 27 Mar 2013 18:30:37 +0100 Subject: ARM i.MX6q: export imx6q_revision So it can be used in clk-imx6q.c for revision dependent clock tree setup. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/common.h | 1 + arch/arm/mach-imx/mach-imx6q.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index bcb11b1751d8..4cba7dbb079f 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -74,6 +74,7 @@ extern void mxc_set_cpu_type(unsigned int type); extern void mxc_restart(char, const char *); extern void mxc_arch_reset_init(void __iomem *); extern int mx53_revision(void); +extern int imx6q_revision(void); extern int mx53_display_revision(void); extern void imx_set_aips(void __iomem *); extern int mxc_device_init(void); diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 31aee4d5fcdd..0af330d7e592 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -39,7 +39,7 @@ #include "cpuidle.h" #include "hardware.h" -static int imx6q_revision(void) +int imx6q_revision(void) { static u32 rev; -- cgit v1.2.3-55-g7522 From 3ce921702bea62fb1d4466939d4ea841a10d534e Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 27 Mar 2013 18:30:40 +0100 Subject: ARM i.MX: Add imx_clk_divider_flags and imx_clk_mux_flags The default is for dividers to set CLK_SET_PARENT_RATE and for muxes to not set that flag. In the LDB clock tree, we need the opposite, so add functions to create divider and mux clocks with configurable flags. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h index 9d1f3b99d1d3..d9d9d9c66dff 100644 --- a/arch/arm/mach-imx/clk.h +++ b/arch/arm/mach-imx/clk.h @@ -59,6 +59,14 @@ static inline struct clk *imx_clk_divider(const char *name, const char *parent, reg, shift, width, 0, &imx_ccm_lock); } +static inline struct clk *imx_clk_divider_flags(const char *name, + const char *parent, void __iomem *reg, u8 shift, u8 width, + unsigned long flags) +{ + return clk_register_divider(NULL, name, parent, flags, + reg, shift, width, 0, &imx_ccm_lock); +} + static inline struct clk *imx_clk_gate(const char *name, const char *parent, void __iomem *reg, u8 shift) { @@ -73,6 +81,15 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg, width, 0, &imx_ccm_lock); } +static inline struct clk *imx_clk_mux_flags(const char *name, + void __iomem *reg, u8 shift, u8 width, const char **parents, + int num_parents, unsigned long flags) +{ + return clk_register_mux(NULL, name, parents, num_parents, + flags, reg, shift, width, 0, + &imx_ccm_lock); +} + static inline struct clk *imx_clk_fixed_factor(const char *name, const char *parent, unsigned int mult, unsigned int div) { -- cgit v1.2.3-55-g7522 From cc7b633909877c5e004e3feae19a11b4053eb157 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 27 Mar 2013 18:30:41 +0100 Subject: ARM i.MX53: fix ldb di divider and selector clocks Use imx_clk_mux_flags and imx_clk_divider_flags to set the appropriate flags for the LDB display interface divider and selector clocks. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index fdd86571aa6a..8a448c30d3f0 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -430,15 +430,15 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk[pll3_sw] = imx_clk_pllv2("pll3_sw", "osc", MX53_DPLL3_BASE); clk[pll4_sw] = imx_clk_pllv2("pll4_sw", "osc", MX53_DPLL4_BASE); - clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1, - mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel)); clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); - clk[ldb_di1_div] = imx_clk_divider("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1); + clk[ldb_di1_div] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0); + clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1, + mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT); clk[di_pll4_podf] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3); - clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1, - mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel)); clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); - clk[ldb_di0_div] = imx_clk_divider("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1); + clk[ldb_di0_div] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0); + clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1, + mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT); clk[ldb_di0_gate] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28); clk[ldb_di1_gate] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30); clk[ipu_di0_sel] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, -- cgit v1.2.3-55-g7522 From d19dacb732209ba25e2e1f912b74d9d64a608bb0 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 27 Mar 2013 18:30:42 +0100 Subject: ARM i.MX6q: fix ldb di divider and selector clocks Use imx_clk_mux_flags and imx_clk_divider_flags to set the appropriate flags for the LDB display interface divider and selector clocks. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 23b799a51e6c..47d0af1c4210 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -354,8 +354,8 @@ int __init mx6q_clocks_init(void) clk[gpu3d_shader_sel] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); clk[ipu1_sel] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); - clk[ldb_di0_sel] = imx_clk_mux("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); - clk[ldb_di1_sel] = imx_clk_mux("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels)); + clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); + clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); @@ -403,9 +403,9 @@ int __init mx6q_clocks_init(void) clk[ipu1_podf] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); clk[ipu2_podf] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); clk[ldb_di0_div_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); - clk[ldb_di0_podf] = imx_clk_divider("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1); + clk[ldb_di0_podf] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0); clk[ldb_di1_div_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); - clk[ldb_di1_podf] = imx_clk_divider("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1); + clk[ldb_di1_podf] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0); clk[ipu1_di0_pre] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3); clk[ipu1_di1_pre] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3); clk[ipu2_di0_pre] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3); -- cgit v1.2.3-55-g7522 From 2df1d026edc11e88ad0a2216e79232737f5939e2 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Fri, 29 Mar 2013 19:29:02 +0800 Subject: ARM i.MX6q: Add audio/video PLL post dividers for i.MX6q rev 1.1 Query silicon revision to determine clock tree and add post dividers for newer revisions. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- .../devicetree/bindings/clock/imx6q-clock.txt | 3 ++ arch/arm/mach-imx/clk-imx6q.c | 40 ++++++++++++++++++---- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/imx6q-clock.txt b/Documentation/devicetree/bindings/clock/imx6q-clock.txt index 969b38e06ad3..6deb6fd1c7cd 100644 --- a/Documentation/devicetree/bindings/clock/imx6q-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx6q-clock.txt @@ -205,6 +205,9 @@ clocks and IDs. enet_ref 190 usbphy1_gate 191 usbphy2_gate 192 + pll4_post_div 193 + pll5_post_div 194 + pll5_video_div 195 Examples: diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 47d0af1c4210..2b230f83170b 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -23,6 +23,7 @@ #include "clk.h" #include "common.h" +#include "hardware.h" #define CCR 0x0 #define BM_CCR_WB_COUNT (0x7 << 16) @@ -180,29 +181,29 @@ static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", }; static const char *periph_sels[] = { "periph_pre", "periph_clk2", }; static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "pll3_pfd1_540m", }; -static const char *audio_sels[] = { "pll4_audio", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; +static const char *audio_sels[] = { "pll4_post_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; static const char *gpu_axi_sels[] = { "axi", "ahb", }; static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd9_720m", }; static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; static const char *ldb_di_sels[] = { "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; -static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; +static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", }; static const char *pcie_axi_sels[] = { "axi", "ahb", }; -static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio", }; +static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_post_div", }; static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", }; static const char *emi_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", }; static const char *vdo_axi_sels[] = { "axi", "ahb", }; static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", }; -static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video", +static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", - "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio", }; + "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_post_div", }; enum mx6q_clks { dummy, ckil, ckih, osc, pll2_pfd0_352m, pll2_pfd1_594m, pll2_pfd2_396m, @@ -236,7 +237,7 @@ enum mx6q_clks { pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg, ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5, sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate, - usbphy2_gate, clk_max + usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, clk_max }; static struct clk *clk[clk_max]; @@ -253,6 +254,21 @@ static struct clk_div_table clk_enet_ref_table[] = { { .val = 3, .div = 4, }, }; +static struct clk_div_table post_div_table[] = { + { .val = 2, .div = 1, }, + { .val = 1, .div = 2, }, + { .val = 0, .div = 4, }, + { } +}; + +static struct clk_div_table video_div_table[] = { + { .val = 0, .div = 1, }, + { .val = 1, .div = 2, }, + { .val = 2, .div = 1, }, + { .val = 3, .div = 4, }, + { } +}; + int __init mx6q_clocks_init(void) { struct device_node *np; @@ -279,6 +295,14 @@ int __init mx6q_clocks_init(void) base = of_iomap(np, 0); WARN_ON(!base); + /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */ + if (imx6q_revision() == IMX_CHIP_REVISION_1_0) { + post_div_table[1].div = 1; + post_div_table[2].div = 1; + video_div_table[1].div = 1; + video_div_table[2].div = 1; + }; + /* type name parent_name base div_mask */ clk[pll1_sys] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f); clk[pll2_bus] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1); @@ -331,6 +355,10 @@ int __init mx6q_clocks_init(void) clk[pll3_60m] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); clk[twd] = imx_clk_fixed_factor("twd", "arm", 1, 2); + clk[pll4_post_div] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); + clk[pll5_post_div] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); + clk[pll5_video_div] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm"); base = of_iomap(np, 0); WARN_ON(!base); -- cgit v1.2.3-55-g7522 From 32f3b8da222b0817e0544acd888071aff674b629 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 28 Mar 2013 16:23:32 +0100 Subject: ARM i.MX6q: set the LDB serial clock parent to the video PLL On i.MX6q revision 1.1 and later, set the video PLL as parent for the LDB clock branch. On revision 1.0, the video PLL is useless due to missing dividers, so keep the default parent (mmdc_ch1_axi). Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 2b230f83170b..43dbcd618be3 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -547,6 +547,11 @@ int __init mx6q_clocks_init(void) clk_register_clkdev(clk[cko1], "cko1", NULL); clk_register_clkdev(clk[arm], NULL, "cpu0"); + if (imx6q_revision() != IMX_CHIP_REVISION_1_0) { + clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]); + clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]); + } + /* * The gpmi needs 100MHz frequency in the EDO/Sync mode, * We can not get the 100MHz from the pll2_pfd0_352m. -- cgit v1.2.3-55-g7522 From 7006ba24c26313631f21fff5a087c971f5c7d2ef Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Sun, 31 Mar 2013 22:39:22 +0800 Subject: ARM: imx: do not use regmap_read for ANADIG_DIGPROG Function imx_anatop_get_digprog() that reads register ANADIG_DIGPROG is called to identify silicon version. Users might query silicon version earlier than regmap subsystem is ready. For example, imx6q clock driver query revision in mx6q_clocks_init(), where regmap is not initialized yet. Change imx_anatop_get_digprog() to map anatop block and read ANADIG_DIGPROG in the native way, so that the function can work at very early stage. While at it, let's move imx_print_silicon_rev() back to imx6q_timer_init() to have the message show up a little earlier. Signed-off-by: Shawn Guo --- arch/arm/mach-imx/anatop.c | 15 ++++++++++++--- arch/arm/mach-imx/mach-imx6q.c | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 472beee9cd98..0cfa07dd9aa4 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -78,10 +78,19 @@ void imx_anatop_usb_chrg_detect_disable(void) u32 imx_anatop_get_digprog(void) { - u32 val; + struct device_node *np; + void __iomem *anatop_base; + static u32 digprog; - regmap_read(anatop, ANADIG_DIGPROG, &val); - return val; + if (digprog) + return digprog; + + np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); + anatop_base = of_iomap(np, 0); + WARN_ON(!anatop_base); + digprog = readl_relaxed(anatop_base + ANADIG_DIGPROG); + + return digprog; } void __init imx_anatop_init(void) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 0af330d7e592..221f31991939 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -164,7 +164,6 @@ static void __init imx6q_init_machine(void) imx6q_pm_init(); imx6q_usb_init(); imx6q_1588_init(); - imx_print_silicon_rev("i.MX6Q", imx6q_revision()); } #define OCOTP_CFG3 0x440 @@ -258,6 +257,7 @@ static void __init imx6q_timer_init(void) { mx6q_clocks_init(); twd_local_timer_of_register(); + imx_print_silicon_rev("i.MX6Q", imx6q_revision()); } static const char *imx6q_dt_compat[] __initdata = { -- cgit v1.2.3-55-g7522 From 02985b94638b4de3ef9f2eb2ac5befe5bab12c26 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 28 Mar 2013 17:35:19 +0100 Subject: ARM i.MX6q: Add GPU, VPU, IPU, and OpenVG resets to System Reset Controller (SRC) The SRC has auto-deasserting reset bits that control reset lines to the GPU, VPU, IPU, and OpenVG IP modules. This patch adds a reset controller that can be controlled by those devices using the reset controller API. Signed-off-by: Philipp Zabel Reviewed-by: Stephen Warren Reviewed-by: Marek Vasut Reviewed-by: Pavel Machek Signed-off-by: Shawn Guo --- .../devicetree/bindings/reset/fsl,imx-src.txt | 49 ++++++++++++++++ arch/arm/mach-imx/Kconfig | 1 + arch/arm/mach-imx/src.c | 65 ++++++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 Documentation/devicetree/bindings/reset/fsl,imx-src.txt diff --git a/Documentation/devicetree/bindings/reset/fsl,imx-src.txt b/Documentation/devicetree/bindings/reset/fsl,imx-src.txt new file mode 100644 index 000000000000..13301777e11c --- /dev/null +++ b/Documentation/devicetree/bindings/reset/fsl,imx-src.txt @@ -0,0 +1,49 @@ +Freescale i.MX System Reset Controller +====================================== + +Please also refer to reset.txt in this directory for common reset +controller binding usage. + +Required properties: +- compatible: Should be "fsl,-src" +- reg: should be register base and length as documented in the + datasheet +- interrupts: Should contain SRC interrupt and CPU WDOG interrupt, + in this order. +- #reset-cells: 1, see below + +example: + +src: src@020d8000 { + compatible = "fsl,imx6q-src"; + reg = <0x020d8000 0x4000>; + interrupts = <0 91 0x04 0 96 0x04>; + #reset-cells = <1>; +}; + +Specifying reset lines connected to IP modules +============================================== + +The system reset controller can be used to reset the GPU, VPU, +IPU, and OpenVG IP modules on i.MX5 and i.MX6 ICs. Those device +nodes should specify the reset line on the SRC in their resets +property, containing a phandle to the SRC device node and a +RESET_INDEX specifying which module to reset, as described in +reset.txt + +example: + + ipu1: ipu@02400000 { + resets = <&src 2>; + }; + ipu2: ipu@02800000 { + resets = <&src 4>; + }; + +The following RESET_INDEX values are valid for i.MX5: +GPU_RESET 0 +VPU_RESET 1 +IPU1_RESET 2 +OPEN_VG_RESET 3 +The following additional RESET_INDEX value is valid for i.MX6: +IPU2_RESET 4 diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 1ab069cf722f..5b676d425bab 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -76,6 +76,7 @@ config HAVE_IMX_MMDC config HAVE_IMX_SRC def_bool y if SMP + select ARCH_HAS_RESET_CONTROLLER config IMX_HAVE_IOMUX_V1 bool diff --git a/arch/arm/mach-imx/src.c b/arch/arm/mach-imx/src.c index 09a742f8c7ab..dec641108b54 100644 --- a/arch/arm/mach-imx/src.c +++ b/arch/arm/mach-imx/src.c @@ -14,16 +14,72 @@ #include #include #include +#include #include #include #define SRC_SCR 0x000 #define SRC_GPR1 0x020 #define BP_SRC_SCR_WARM_RESET_ENABLE 0 +#define BP_SRC_SCR_SW_GPU_RST 1 +#define BP_SRC_SCR_SW_VPU_RST 2 +#define BP_SRC_SCR_SW_IPU1_RST 3 +#define BP_SRC_SCR_SW_OPEN_VG_RST 4 +#define BP_SRC_SCR_SW_IPU2_RST 12 #define BP_SRC_SCR_CORE1_RST 14 #define BP_SRC_SCR_CORE1_ENABLE 22 static void __iomem *src_base; +static DEFINE_SPINLOCK(scr_lock); + +static const int sw_reset_bits[5] = { + BP_SRC_SCR_SW_GPU_RST, + BP_SRC_SCR_SW_VPU_RST, + BP_SRC_SCR_SW_IPU1_RST, + BP_SRC_SCR_SW_OPEN_VG_RST, + BP_SRC_SCR_SW_IPU2_RST +}; + +static int imx_src_reset_module(struct reset_controller_dev *rcdev, + unsigned long sw_reset_idx) +{ + unsigned long timeout; + unsigned long flags; + int bit; + u32 val; + + if (!src_base) + return -ENODEV; + + if (sw_reset_idx >= ARRAY_SIZE(sw_reset_bits)) + return -EINVAL; + + bit = 1 << sw_reset_bits[sw_reset_idx]; + + spin_lock_irqsave(&scr_lock, flags); + val = readl_relaxed(src_base + SRC_SCR); + val |= bit; + writel_relaxed(val, src_base + SRC_SCR); + spin_unlock_irqrestore(&scr_lock, flags); + + timeout = jiffies + msecs_to_jiffies(1000); + while (readl(src_base + SRC_SCR) & bit) { + if (time_after(jiffies, timeout)) + return -ETIME; + cpu_relax(); + } + + return 0; +} + +static struct reset_control_ops imx_src_ops = { + .reset = imx_src_reset_module, +}; + +static struct reset_controller_dev imx_reset_controller = { + .ops = &imx_src_ops, + .nr_resets = ARRAY_SIZE(sw_reset_bits), +}; void imx_enable_cpu(int cpu, bool enable) { @@ -31,9 +87,11 @@ void imx_enable_cpu(int cpu, bool enable) cpu = cpu_logical_map(cpu); mask = 1 << (BP_SRC_SCR_CORE1_ENABLE + cpu - 1); + spin_lock(&scr_lock); val = readl_relaxed(src_base + SRC_SCR); val = enable ? val | mask : val & ~mask; writel_relaxed(val, src_base + SRC_SCR); + spin_unlock(&scr_lock); } void imx_set_cpu_jump(int cpu, void *jump_addr) @@ -60,9 +118,11 @@ void imx_src_prepare_restart(void) u32 val; /* clear enable bits of secondary cores */ + spin_lock(&scr_lock); val = readl_relaxed(src_base + SRC_SCR); val &= ~(0x7 << BP_SRC_SCR_CORE1_ENABLE); writel_relaxed(val, src_base + SRC_SCR); + spin_unlock(&scr_lock); /* clear persistent entry register of primary core */ writel_relaxed(0, src_base + SRC_GPR1); @@ -77,11 +137,16 @@ void __init imx_src_init(void) src_base = of_iomap(np, 0); WARN_ON(!src_base); + imx_reset_controller.of_node = np; + reset_controller_register(&imx_reset_controller); + /* * force warm reset sources to generate cold reset * for a more reliable restart */ + spin_lock(&scr_lock); val = readl_relaxed(src_base + SRC_SCR); val &= ~(1 << BP_SRC_SCR_WARM_RESET_ENABLE); writel_relaxed(val, src_base + SRC_SCR); + spin_unlock(&scr_lock); } -- cgit v1.2.3-55-g7522 From 6c64155de972e8c42750340c21e225a2f8b78f26 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 28 Mar 2013 17:35:21 +0100 Subject: staging: drm/imx: Use SRC to reset IPU Request the System Reset Controller to reset the IPU if specified via device tree phandle. Signed-off-by: Philipp Zabel Reviewed-by: Stephen Warren Reviewed-by: Marek Vasut Reviewed-by: Pavel Machek Acked-by: Greg Kroah-Hartman Signed-off-by: Shawn Guo --- .../devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt | 3 +++ drivers/staging/imx-drm/ipu-v3/ipu-common.c | 12 +++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt index 07654f0338b6..f7698573cb9c 100644 --- a/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt +++ b/Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt @@ -8,6 +8,8 @@ Required properties: - interrupts: Should contain sync interrupt and error interrupt, in this order. - #crtc-cells: 1, See below +- resets: phandle pointing to the system reset controller and + reset line index, see reset/fsl,imx-src.txt for details example: @@ -16,6 +18,7 @@ ipu: ipu@18000000 { compatible = "fsl,imx53-ipu"; reg = <0x18000000 0x080000000>; interrupts = <11 10>; + resets = <&src 2>; }; Parallel display support diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c index 366f259e3756..04b8320d6579 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -660,7 +661,7 @@ int ipu_idmac_disable_channel(struct ipuv3_channel *channel) } EXPORT_SYMBOL_GPL(ipu_idmac_disable_channel); -static int ipu_reset(struct ipu_soc *ipu) +static int ipu_memory_reset(struct ipu_soc *ipu) { unsigned long timeout; @@ -1104,7 +1105,12 @@ static int ipu_probe(struct platform_device *pdev) if (ret) goto out_failed_irq; - ret = ipu_reset(ipu); + ret = device_reset(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "failed to reset: %d\n", ret); + goto out_failed_reset; + } + ret = ipu_memory_reset(ipu); if (ret) goto out_failed_reset; @@ -1130,8 +1136,8 @@ static int ipu_probe(struct platform_device *pdev) failed_add_clients: ipu_submodules_exit(ipu); failed_submodules_init: - ipu_irq_exit(ipu); out_failed_reset: + ipu_irq_exit(ipu); out_failed_irq: clk_disable_unprepare(ipu->clk); failed_clk_get: -- cgit v1.2.3-55-g7522 From 04b41e84ff6a49e62c8a787b278af823e78354f4 Mon Sep 17 00:00:00 2001 From: Martin Fuzzey Date: Tue, 19 Mar 2013 17:57:01 +0100 Subject: ARM: i.MX53 Add the cko1, cko2 clock outputs. These two clocks connect to external pins and can be muxed to various internal clocks. They are typically used either for debugging or to provide clocks to external chips (eg audio codecs). Currently only the selectable clocks that already exist in the clock tree have been added. Signed-off-by: Martin Fuzzey Acked-by: Sascha Hauer Signed-off-by: Shawn Guo --- .../devicetree/bindings/clock/imx5-clock.txt | 6 ++++ arch/arm/mach-imx/clk-imx51-imx53.c | 34 ++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.txt b/Documentation/devicetree/bindings/clock/imx5-clock.txt index 342ad0fce53d..838ab8801e93 100644 --- a/Documentation/devicetree/bindings/clock/imx5-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx5-clock.txt @@ -177,6 +177,12 @@ clocks and IDs. gpu3d_gate 162 gpu2d_gate 163 garb_gate 164 + cko1_sel 165 + cko1_podf 166 + cko1 167 + cko2_sel 168 + cko2_podf 169 + cko2 170 Examples (for mx53): diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index 8a448c30d3f0..a163e0e365dc 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -51,6 +51,28 @@ static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", }; +static const char *mx53_cko1_sel[] = { + "cpu_podf", "pll1_sw", "pll2_sw", "pll3_sw", + "emi_slow_podf", "pll4_sw", "nfc_podf", "dummy", + "di_pred", "dummy", "dummy", "ahb", + "ipg", "per_root", "ckil", "dummy",}; +static const char *mx53_cko2_sel[] = { + "dummy"/* dptc_core */, "dummy"/* dptc_perich */, + "dummy", "esdhc_a_podf", + "usboh3_podf", "dummy"/* wrck_clk_root */, + "ecspi_podf", "dummy"/* pll1_ref_clk */, + "esdhc_b_podf", "dummy"/* ddr_clk_root */, + "dummy"/* arm_axi_clk_root */, "dummy"/* usb_phy_out */, + "vpu_sel", "ipu_sel", + "osc", "ckih1", + "dummy", "esdhc_c_sel", + "ssi1_root_podf", "ssi2_root_podf", + "dummy", "dummy", + "dummy"/* lpsr_clk_root */, "dummy"/* pgc_clk_root */, + "dummy"/* tve_out */, "usb_phy_sel", + "tve_sel", "lp_apm", + "uart_root", "dummy"/* spdif0_clk_root */, + "dummy", "dummy", }; enum imx5_clks { dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred, @@ -86,6 +108,8 @@ enum imx5_clks { epit1_ipg_gate, epit1_hf_gate, epit2_ipg_gate, epit2_hf_gate, can_sel, can1_serial_gate, can1_ipg_gate, owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate, + cko1_sel, cko1_podf, cko1, + cko2_sel, cko2_podf, cko2, clk_max }; @@ -463,6 +487,16 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6); clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); + clk[cko1_sel] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4, + mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel)); + clk[cko1_podf] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3); + clk[cko1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7); + + clk[cko2_sel] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5, + mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel)); + clk[cko2_podf] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3); + clk[cko2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24); + for (i = 0; i < ARRAY_SIZE(clk); i++) if (IS_ERR(clk[i])) pr_err("i.MX53 clk %d: register failed with %ld\n", -- cgit v1.2.3-55-g7522 From e72f745c4631ce4175b1764a861b12f67fcf60ad Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 15 Feb 2013 15:32:01 -0200 Subject: ARM: imx_v6_v7_defconfig: Select CONFIG_PERF_EVENTS Select CONFIG_PERF_EVENTS so that oprofile can be used. Signed-off-by: Fabio Estevam Acked-by: Dirk Behme Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/configs/imx_v6_v7_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index e36b01025321..12f50c7963fd 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -9,6 +9,7 @@ CONFIG_CGROUPS=y CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y +CONFIG_PERF_EVENTS=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set CONFIG_MODULES=y -- cgit v1.2.3-55-g7522 From 7c3e48b5a4b46a0cdb12c824caa66d1a68c3def5 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 18 Feb 2013 12:45:20 -0300 Subject: ARM: imx_v4_v5_defconfig: Add CONFIG_GPIO_SYSFS Add CONFIG_GPIO_SYSFS as it is helpful for accessing GPIO from userspace. Signed-off-by: Fabio Estevam Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/configs/imx_v4_v5_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig index 02c657af4005..f07a847b00c9 100644 --- a/arch/arm/configs/imx_v4_v5_defconfig +++ b/arch/arm/configs/imx_v4_v5_defconfig @@ -109,6 +109,7 @@ CONFIG_I2C_IMX=y CONFIG_SPI=y CONFIG_SPI_IMX=y CONFIG_SPI_SPIDEV=y +CONFIG_GPIO_SYSFS=y CONFIG_W1=y CONFIG_W1_MASTER_MXC=y CONFIG_W1_SLAVE_THERM=y -- cgit v1.2.3-55-g7522 From 9a37ac481aab63c61488562c03125ba279ad57c6 Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Sat, 16 Mar 2013 16:49:59 +0100 Subject: ARM: imx1: mm: add call to mxc_device_init mxc_device_init() is mandatory for mxc_aips and mxc_ahb bus registration, needed as parents, at least, for gpio and dma. Signed-off-by: Gwenhael Goavec-Merou Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mm-imx1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/mm-imx1.c b/arch/arm/mach-imx/mm-imx1.c index 7a146671e65a..3c609c52d3eb 100644 --- a/arch/arm/mach-imx/mm-imx1.c +++ b/arch/arm/mach-imx/mm-imx1.c @@ -51,6 +51,8 @@ void __init mx1_init_irq(void) void __init imx1_soc_init(void) { + mxc_device_init(); + mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256, MX1_GPIO_INT_PORTA, 0); mxc_register_gpio("imx1-gpio", 1, MX1_GPIO2_BASE_ADDR, SZ_256, -- cgit v1.2.3-55-g7522 From 3c03a2fed63881abf5ecb5596625157ecfc9e4eb Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Mon, 1 Apr 2013 22:13:32 +0800 Subject: ARM: imx: add initial imx6dl support The i.MX6 DualLite/Solo is another i.MX6 family SoC, which is highly compatible with i.MX6 Quad/Dual. And that's why we choose to support it using imx6q code with cpu_is_imx6dl() check when necessary. Signed-off-by: Shawn Guo --- arch/arm/Kconfig.debug | 4 ++-- arch/arm/mach-imx/Kconfig | 2 +- arch/arm/mach-imx/clk-imx6q.c | 2 +- arch/arm/mach-imx/mach-imx6q.c | 30 +++++++++++++++++++++--------- arch/arm/mach-imx/mxc.h | 11 +++++++++++ 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 9b31f4311ea2..7e911fd4dd89 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -234,11 +234,11 @@ choice on i.MX53. config DEBUG_IMX6Q_UART - bool "i.MX6Q Debug UART" + bool "i.MX6Q/DL Debug UART" depends on SOC_IMX6Q help Say Y here if you want kernel low-level debugging support - on i.MX6Q. + on i.MX6Q/DL. config DEBUG_MMP_UART2 bool "Kernel low-level debugging message via MMP UART2" diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 5b676d425bab..2b09a0471d7b 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -790,7 +790,7 @@ config SOC_IMX53 This enables support for Freescale i.MX53 processor. config SOC_IMX6Q - bool "i.MX6 Quad support" + bool "i.MX6 Quad/DualLite support" select ARCH_HAS_CPUFREQ select ARCH_HAS_OPP select ARM_CPU_SUSPEND if PM diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 43dbcd618be3..151259003086 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -296,7 +296,7 @@ int __init mx6q_clocks_init(void) WARN_ON(!base); /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */ - if (imx6q_revision() == IMX_CHIP_REVISION_1_0) { + if (cpu_is_imx6q() && imx6q_revision() == IMX_CHIP_REVISION_1_0) { post_div_table[1].div = 1; post_div_table[2].div = 1; video_div_table[1].div = 1; diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 221f31991939..8aa9d9065e8e 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -39,23 +39,32 @@ #include "cpuidle.h" #include "hardware.h" +static u32 chip_revision; + int imx6q_revision(void) { - static u32 rev; + return chip_revision; +} - if (!rev) - rev = imx_anatop_get_digprog(); +static void __init imx6q_init_revision(void) +{ + u32 rev = imx_anatop_get_digprog(); switch (rev & 0xff) { case 0: - return IMX_CHIP_REVISION_1_0; + chip_revision = IMX_CHIP_REVISION_1_0; + break; case 1: - return IMX_CHIP_REVISION_1_1; + chip_revision = IMX_CHIP_REVISION_1_1; + break; case 2: - return IMX_CHIP_REVISION_1_2; + chip_revision = IMX_CHIP_REVISION_1_2; + break; default: - return IMX_CHIP_REVISION_UNKNOWN; + chip_revision = IMX_CHIP_REVISION_UNKNOWN; } + + mxc_set_cpu_type(rev >> 16 & 0xff); } void imx6q_restart(char mode, const char *cmd) @@ -247,6 +256,7 @@ static void __init imx6q_map_io(void) static void __init imx6q_init_irq(void) { + imx6q_init_revision(); l2x0_of_init(0, ~0UL); imx_src_init(); imx_gpc_init(); @@ -257,15 +267,17 @@ static void __init imx6q_timer_init(void) { mx6q_clocks_init(); twd_local_timer_of_register(); - imx_print_silicon_rev("i.MX6Q", imx6q_revision()); + imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", + imx6q_revision()); } static const char *imx6q_dt_compat[] __initdata = { + "fsl,imx6dl", "fsl,imx6q", NULL, }; -DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad (Device Tree)") +DT_MACHINE_START(IMX6Q, "Freescale i.MX6 Quad/DualLite (Device Tree)") .smp = smp_ops(imx_smp_ops), .map_io = imx6q_map_io, .init_irq = imx6q_init_irq, diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index 7dce17a9fe6c..8629e5be7ecd 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -34,6 +34,8 @@ #define MXC_CPU_MX35 35 #define MXC_CPU_MX51 51 #define MXC_CPU_MX53 53 +#define MXC_CPU_IMX6DL 0x61 +#define MXC_CPU_IMX6Q 0x63 #define IMX_CHIP_REVISION_1_0 0x10 #define IMX_CHIP_REVISION_1_1 0x11 @@ -150,6 +152,15 @@ extern unsigned int __mxc_cpu_type; #endif #ifndef __ASSEMBLY__ +static inline bool cpu_is_imx6dl(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX6DL; +} + +static inline bool cpu_is_imx6q(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX6Q; +} struct cpu_op { u32 cpu_rate; -- cgit v1.2.3-55-g7522 From dc13ba2950acdd7ca64de3a8addcf85ada8ee908 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 2 Apr 2013 16:37:21 +0800 Subject: ARM: imx: do not bring up unavailable cores The i.MX6 Quad can be fused as i.MX6 Dual chip, and similarly i.MX6 DualLite can be fused as i.MX6 Solo. The actual number of available cores can be found out from SCU. Since we do not reflect the fusing thing in device tree, the function arm_dt_init_cpu_maps() will always call set_cpu_possible(true) for 4 cores on i.MX6 Quad/Dual and 2 cores for i.MX6 DualLite/Solo. This causes failures when kernel tries to bring those unavailable cores online. For example, the following failure message will be seen when booting an i.MX6 Solo chip. CPU1: failed to come online Though kernel will still boot fine, the message is somehow annoying. Let's get rid of it by calling set_cpu_possible(false) on those unavailable cores. While at it, the set_cpu_possible(true) for available cores is removed, since it's already been done in arm_dt_init_cpu_maps(). Signed-off-by: Shawn Guo --- arch/arm/mach-imx/platsmp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/platsmp.c b/arch/arm/mach-imx/platsmp.c index 7c0b03f67b05..7061bdedfdb0 100644 --- a/arch/arm/mach-imx/platsmp.c +++ b/arch/arm/mach-imx/platsmp.c @@ -79,8 +79,8 @@ static void __init imx_smp_init_cpus(void) ncores = scu_get_core_count(scu_base); - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); + for (i = ncores; i < NR_CPUS; i++) + set_cpu_possible(i, false); } void imx_smp_prepare(void) -- cgit v1.2.3-55-g7522 From 5d530bb0ad84d403d1aac79a8a8acf2c2b0a8dd7 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 4 Apr 2013 11:25:08 +0200 Subject: ARM: i.MX5: Add PATA and SRTC clocks This adds the clock gates and the binding documentation for PATA and SRTC. Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/clock/imx5-clock.txt | 2 ++ arch/arm/mach-imx/clk-imx51-imx53.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.txt b/Documentation/devicetree/bindings/clock/imx5-clock.txt index 838ab8801e93..84cae1f187ca 100644 --- a/Documentation/devicetree/bindings/clock/imx5-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx5-clock.txt @@ -183,6 +183,8 @@ clocks and IDs. cko2_sel 168 cko2_podf 169 cko2 170 + srtc_gate 171 + pata_gate 172 Examples (for mx53): diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index a163e0e365dc..efbccc0dcada 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -110,6 +110,7 @@ enum imx5_clks { owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate, cko1_sel, cko1_podf, cko1, cko2_sel, cko2_podf, cko2, + srtc_gate, pata_gate, clk_max }; @@ -266,6 +267,8 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk[epit2_ipg_gate] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6); clk[epit2_hf_gate] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8); clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22); + clk[srtc_gate] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28); + clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0); for (i = 0; i < ARRAY_SIZE(clk); i++) if (IS_ERR(clk[i])) -- cgit v1.2.3-55-g7522 From 3f487bed1b78140a38760d774b893ff2ea8e3d17 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 8 Apr 2013 16:46:19 +0200 Subject: ARM i.MX5: Remove tve_sel clock from i.MX53 clock tree On i.MX53, there is only tve_ext_sel. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index efbccc0dcada..a68bb3882b80 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -45,7 +45,7 @@ static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", " static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", }; static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", }; static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", }; -static const char *tve_sel[] = { "tve_pred", "tve_ext_sel", }; +static const char *mx51_tve_sel[] = { "tve_pred", "tve_ext_sel", }; static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; @@ -188,7 +188,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3); clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); clk[tve_di] = imx_clk_fixed("tve_di", 65000000); /* FIXME */ - clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, tve_sel, ARRAY_SIZE(tve_sel)); clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8); @@ -367,6 +366,8 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel)); + clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, + mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel)); clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30); clk[tve_pred] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3); clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); -- cgit v1.2.3-55-g7522 From 866f2f0d8d94957a36811bde43a14abd373dfb37 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 8 Apr 2013 16:46:20 +0200 Subject: ARM i.MX53: Remove unused tve_gate clkdev entry Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index a68bb3882b80..7e50ec9c865d 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -319,7 +319,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.0"); clk_register_clkdev(clk[dummy], NULL, "imx2-wdt.1"); clk_register_clkdev(clk[dummy], NULL, "imx-keypad"); - clk_register_clkdev(clk[tve_gate], NULL, "imx-tve.0"); clk_register_clkdev(clk[ipu_di1_gate], "di1", "imx-tve.0"); clk_register_clkdev(clk[gpc_dvfs], "gpc_dvfs", NULL); clk_register_clkdev(clk[epit1_ipg_gate], "ipg", "imx-epit.0"); -- cgit v1.2.3-55-g7522 From f550e70175c43686e5b2df24b1a4054c5afce6e4 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 8 Apr 2013 16:46:21 +0200 Subject: ARM i.MX53: make tve_ext_sel propagate rate change to PLL This is needed so the Television Encoder driver can set the rate on tve_clk and have it propagated up to pll4_sw. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index 7e50ec9c865d..a107e811004a 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -472,8 +472,8 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel)); clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel)); - clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, - mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel)); + clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, + mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT); clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30); clk[tve_pred] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3); clk[esdhc1_per_gate] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); -- cgit v1.2.3-55-g7522 From d24de4952314afbbcd51b1fb72e5a320d60379dc Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 8 Apr 2013 16:46:22 +0200 Subject: ARM i.MX53: tve_di clock is not part of the CCM, but of TVE Remove the tve_di clock from the CCM clock tree. It will be provided by the Television Encoder driver, as this clock is an output signal of the TVE module. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/clock/imx5-clock.txt | 1 - arch/arm/mach-imx/clk-imx51-imx53.c | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/imx5-clock.txt b/Documentation/devicetree/bindings/clock/imx5-clock.txt index 84cae1f187ca..d71b4b2c077d 100644 --- a/Documentation/devicetree/bindings/clock/imx5-clock.txt +++ b/Documentation/devicetree/bindings/clock/imx5-clock.txt @@ -38,7 +38,6 @@ clocks and IDs. usb_phy_podf 23 cpu_podf 24 di_pred 25 - tve_di 26 tve_s 27 uart1_ipg_gate 28 uart1_per_gate 29 diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index a107e811004a..cac6a5fce9de 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -78,7 +78,7 @@ enum imx5_clks { dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred, uart_root, esdhc_a_pred, esdhc_b_pred, esdhc_c_s, esdhc_d_s, emi_sel, emi_slow_podf, nfc_podf, ecspi_pred, ecspi_podf, usboh3_pred, - usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di, + usboh3_podf, usb_phy_pred, usb_phy_podf, cpu_podf, di_pred, tve_di_unused, tve_s, uart1_ipg_gate, uart1_per_gate, uart2_ipg_gate, uart2_per_gate, uart3_ipg_gate, uart3_per_gate, i2c1_gate, i2c2_gate, gpt_ipg_gate, pwm1_ipg_gate, pwm1_hf_gate, pwm2_ipg_gate, pwm2_hf_gate, @@ -187,7 +187,6 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); clk[cpu_podf] = imx_clk_divider("cpu_podf", "pll1_sw", MXC_CCM_CACRR, 0, 3); clk[di_pred] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); - clk[tve_di] = imx_clk_fixed("tve_di", 65000000); /* FIXME */ clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); clk[uart1_ipg_gate] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); clk[uart1_per_gate] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8); -- cgit v1.2.3-55-g7522 From 80f72d2d33263429ac6a50b84b2ec5fa681a5e84 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 8 Apr 2013 16:46:23 +0200 Subject: ARM i.MX53: set CLK_SET_RATE_PARENT flag on the tve_ext_sel clock Use imx_clk_mux_flags to set the appropriate flags for the TVE selector clock. This is needed so tve_clk rate changes can propagate up to pll4_sw. Signed-off-by: Philipp Zabel Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx51-imx53.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index cac6a5fce9de..41dd4d6e5b91 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c @@ -362,8 +362,8 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc, mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel)); clk[ipu_di1_sel] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); - clk[tve_ext_sel] = imx_clk_mux("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, - mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel)); + clk[tve_ext_sel] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, + mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT); clk[tve_s] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel)); clk[tve_gate] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30); -- cgit v1.2.3-55-g7522