Browse Source

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
  sparc64: Fix cpufreq notifier registry.
  sparc64: Fix lockdep issues in LDC protocol layer.
Linus Torvalds 17 years ago
parent
commit
4378dcca85
3 changed files with 38 additions and 25 deletions
  1. 9 1
      arch/sparc64/kernel/irq.c
  2. 19 19
      arch/sparc64/kernel/ldc.c
  3. 10 5
      arch/sparc64/kernel/time.c

+ 9 - 1
arch/sparc64/kernel/irq.c

@@ -621,8 +621,9 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino)
 unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
 {
 	struct irq_handler_data *data;
-	struct ino_bucket *bucket;
 	unsigned long hv_err, cookie;
+	struct ino_bucket *bucket;
+	struct irq_desc *desc;
 	unsigned int virt_irq;
 
 	bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
@@ -643,6 +644,13 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
 	if (unlikely(!data))
 		return 0;
 
+	/* In order to make the LDC channel startup sequence easier,
+	 * especially wrt. locking, we do not let request_irq() enable
+	 * the interrupt.
+	 */
+	desc = irq_desc + virt_irq;
+	desc->status |= IRQ_NOAUTOEN;
+
 	set_irq_chip_data(virt_irq, data);
 
 	/* Catch accidental accesses to these things.  IMAP/ICLR handling

+ 19 - 19
arch/sparc64/kernel/ldc.c

@@ -1,6 +1,6 @@
 /* ldc.c: Logical Domain Channel link-layer protocol driver.
  *
- * Copyright (C) 2007 David S. Miller <davem@davemloft.net>
+ * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net>
  */
 
 #include <linux/kernel.h>
@@ -23,8 +23,8 @@
 
 #define DRV_MODULE_NAME		"ldc"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.0"
-#define DRV_MODULE_RELDATE	"June 25, 2007"
+#define DRV_MODULE_VERSION	"1.1"
+#define DRV_MODULE_RELDATE	"July 22, 2008"
 
 static char version[] __devinitdata =
 	DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
@@ -1235,13 +1235,9 @@ int ldc_bind(struct ldc_channel *lp, const char *name)
 	unsigned long hv_err, flags;
 	int err = -EINVAL;
 
-	spin_lock_irqsave(&lp->lock, flags);
-
-	if (!name)
-		goto out_err;
-
-	if (lp->state != LDC_STATE_INIT)
-		goto out_err;
+	if (!name ||
+	    (lp->state != LDC_STATE_INIT))
+		return -EINVAL;
 
 	snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name);
 	snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
@@ -1250,25 +1246,32 @@ int ldc_bind(struct ldc_channel *lp, const char *name)
 			  IRQF_SAMPLE_RANDOM | IRQF_SHARED,
 			  lp->rx_irq_name, lp);
 	if (err)
-		goto out_err;
+		return err;
 
 	err = request_irq(lp->cfg.tx_irq, ldc_tx,
 			  IRQF_SAMPLE_RANDOM | IRQF_SHARED,
 			  lp->tx_irq_name, lp);
-	if (err)
-		goto out_free_rx_irq;
+	if (err) {
+		free_irq(lp->cfg.rx_irq, lp);
+		return err;
+	}
+
 
+	spin_lock_irqsave(&lp->lock, flags);
+
+	enable_irq(lp->cfg.rx_irq);
+	enable_irq(lp->cfg.tx_irq);
 
 	lp->flags |= LDC_FLAG_REGISTERED_IRQS;
 
 	err = -ENODEV;
 	hv_err = sun4v_ldc_tx_qconf(lp->id, 0, 0);
 	if (hv_err)
-		goto out_free_tx_irq;
+		goto out_free_irqs;
 
 	hv_err = sun4v_ldc_tx_qconf(lp->id, lp->tx_ra, lp->tx_num_entries);
 	if (hv_err)
-		goto out_free_tx_irq;
+		goto out_free_irqs;
 
 	hv_err = sun4v_ldc_rx_qconf(lp->id, 0, 0);
 	if (hv_err)
@@ -1304,14 +1307,11 @@ out_unmap_rx:
 out_unmap_tx:
 	sun4v_ldc_tx_qconf(lp->id, 0, 0);
 
-out_free_tx_irq:
+out_free_irqs:
 	lp->flags &= ~LDC_FLAG_REGISTERED_IRQS;
 	free_irq(lp->cfg.tx_irq, lp);
-
-out_free_rx_irq:
 	free_irq(lp->cfg.rx_irq, lp);
 
-out_err:
 	spin_unlock_irqrestore(&lp->lock, flags);
 
 	return err;

+ 10 - 5
arch/sparc64/kernel/time.c

@@ -884,6 +884,16 @@ static struct notifier_block sparc64_cpufreq_notifier_block = {
 	.notifier_call	= sparc64_cpufreq_notifier
 };
 
+static int __init register_sparc64_cpufreq_notifier(void)
+{
+
+	cpufreq_register_notifier(&sparc64_cpufreq_notifier_block,
+				  CPUFREQ_TRANSITION_NOTIFIER);
+	return 0;
+}
+
+core_initcall(register_sparc64_cpufreq_notifier);
+
 #endif /* CONFIG_CPU_FREQ */
 
 static int sparc64_next_event(unsigned long delta,
@@ -1050,11 +1060,6 @@ void __init time_init(void)
 	       sparc64_clockevent.mult, sparc64_clockevent.shift);
 
 	setup_sparc64_timer();
-
-#ifdef CONFIG_CPU_FREQ
-	cpufreq_register_notifier(&sparc64_cpufreq_notifier_block,
-				  CPUFREQ_TRANSITION_NOTIFIER);
-#endif
 }
 
 unsigned long long sched_clock(void)