From patchwork Wed Apr 20 08:39:03 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Hellstrom X-Patchwork-Id: 92107 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id A8A041007DA for ; Wed, 20 Apr 2011 18:39:51 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752161Ab1DTIjv (ORCPT ); Wed, 20 Apr 2011 04:39:51 -0400 Received: from mail201c2.megamailservers.com ([69.49.111.102]:35314 "EHLO mail201c2.megamailservers.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751340Ab1DTIju (ORCPT ); Wed, 20 Apr 2011 04:39:50 -0400 X-POP-User: magnus.gaisler.com Received: from localhost.localdomain (gaisler.se [92.33.28.242]) by mail201c2.megamailservers.com (8.13.6/8.13.1) with ESMTP id p3K8di78000832; Wed, 20 Apr 2011 04:39:45 -0400 From: Daniel Hellstrom To: davem@davemloft.net Cc: sparclinux@vger.kernel.org, sam@ravnborg.org Subject: [PATCH 1/7 v2] sparc32, leon: must protect IRQ controller register with spinlock Date: Wed, 20 Apr 2011 10:39:03 +0200 Message-Id: <1303288747-28521-1-git-send-email-daniel@gaisler.com> X-Mailer: git-send-email 1.5.4 X-CSC: 0 X-CHA: v=1.1 cv=Ma2F9VxktdrohpwE1Ldo3j5zboDzDSax3kyf6Hawm04= c=1 sm=1 a=_bDoO88a3kkA:10 a=U62ajLuCel8A:10 a=jXKJviUpWSOlMmIvGrHOfw==:17 a=ebG-ZW-8AAAA:8 a=7gkXJVJtAAAA:8 a=EkeLdSzprFsYckE-FI8A:9 a=SpeB4snN30g4x7FaICkA:7 a=cCYF7-FHeg4A:10 a=JmBWkid0h3cA:10 a=jXKJviUpWSOlMmIvGrHOfw==:117 Sender: sparclinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: sparclinux@vger.kernel.org The LEON interrupt controller has one single mask register for all IRQs per CPU, even though the genirq layer protects us from accessing the same IRQ at the same time other IRQs share the same mask register and may thus interfere. Some other IRQ controllers has a mask register or similar per IRQ instead which makes spinlocks unncessary. Signed-off-by: Daniel Hellstrom Acked-by: Sam Ravnborg --- arch/sparc/kernel/leon_kernel.c | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 8591cf1..390e469 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c @@ -31,6 +31,7 @@ int leondebug_irq_disable; int leon_debug_irqout; static int dummy_master_l10_counter; unsigned long amba_system_id; +static DEFINE_SPINLOCK(leon_irq_lock); unsigned long leon3_gptimer_irq; /* interrupt controller irq number */ unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */ @@ -88,10 +89,10 @@ static void leon_unmask_irq(struct irq_data *data) unsigned long mask, flags; mask = (unsigned long)data->chip_data; - local_irq_save(flags); + spin_lock_irqsave(&leon_irq_lock, flags); LEON3_BYPASS_STORE_PA(LEON_IMASK, (LEON3_BYPASS_LOAD_PA(LEON_IMASK) | (mask))); - local_irq_restore(flags); + spin_unlock_irqrestore(&leon_irq_lock, flags); } static void leon_mask_irq(struct irq_data *data) @@ -99,11 +100,10 @@ static void leon_mask_irq(struct irq_data *data) unsigned long mask, flags; mask = (unsigned long)data->chip_data; - local_irq_save(flags); + spin_lock_irqsave(&leon_irq_lock, flags); LEON3_BYPASS_STORE_PA(LEON_IMASK, (LEON3_BYPASS_LOAD_PA(LEON_IMASK) & ~(mask))); - local_irq_restore(flags); - + spin_unlock_irqrestore(&leon_irq_lock, flags); } static unsigned int leon_startup_irq(struct irq_data *data) @@ -383,10 +383,10 @@ void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu) { unsigned long mask, flags, *addr; mask = get_irqmask(irq_nr); - local_irq_save(flags); + spin_lock_irqsave(&leon_irq_lock, flags); addr = (unsigned long *)&(leon3_irqctrl_regs->mask[cpu]); LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | (mask))); - local_irq_restore(flags); + spin_unlock_irqrestore(&leon_irq_lock, flags); } #endif