diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 15:15:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 15:15:16 -0400 |
commit | 4378dcca8578b0fd0fba883a3354ad4820d4f85f (patch) | |
tree | 6e9a93e58fd1cabb1483ee48bb76dd77c6d61552 /arch/sparc64/kernel | |
parent | c3c2233d84bee397b8271923c007264eb3efa67b (diff) | |
parent | 7ae93f51d7fa8b9130d47e0b7d17979a165c5bc3 (diff) |
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.
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/irq.c | 10 | ||||
-rw-r--r-- | arch/sparc64/kernel/ldc.c | 38 | ||||
-rw-r--r-- | arch/sparc64/kernel/time.c | 15 |
3 files changed, 38 insertions, 25 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index b441a26b73b0..c481673d249c 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
@@ -621,8 +621,9 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) | |||
621 | unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) | 621 | unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) |
622 | { | 622 | { |
623 | struct irq_handler_data *data; | 623 | struct irq_handler_data *data; |
624 | struct ino_bucket *bucket; | ||
625 | unsigned long hv_err, cookie; | 624 | unsigned long hv_err, cookie; |
625 | struct ino_bucket *bucket; | ||
626 | struct irq_desc *desc; | ||
626 | unsigned int virt_irq; | 627 | unsigned int virt_irq; |
627 | 628 | ||
628 | bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); | 629 | bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC); |
@@ -643,6 +644,13 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino) | |||
643 | if (unlikely(!data)) | 644 | if (unlikely(!data)) |
644 | return 0; | 645 | return 0; |
645 | 646 | ||
647 | /* In order to make the LDC channel startup sequence easier, | ||
648 | * especially wrt. locking, we do not let request_irq() enable | ||
649 | * the interrupt. | ||
650 | */ | ||
651 | desc = irq_desc + virt_irq; | ||
652 | desc->status |= IRQ_NOAUTOEN; | ||
653 | |||
646 | set_irq_chip_data(virt_irq, data); | 654 | set_irq_chip_data(virt_irq, data); |
647 | 655 | ||
648 | /* Catch accidental accesses to these things. IMAP/ICLR handling | 656 | /* Catch accidental accesses to these things. IMAP/ICLR handling |
diff --git a/arch/sparc64/kernel/ldc.c b/arch/sparc64/kernel/ldc.c index 63969f610284..d68982330f66 100644 --- a/arch/sparc64/kernel/ldc.c +++ b/arch/sparc64/kernel/ldc.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* ldc.c: Logical Domain Channel link-layer protocol driver. | 1 | /* ldc.c: Logical Domain Channel link-layer protocol driver. |
2 | * | 2 | * |
3 | * Copyright (C) 2007 David S. Miller <davem@davemloft.net> | 3 | * Copyright (C) 2007, 2008 David S. Miller <davem@davemloft.net> |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <linux/kernel.h> | 6 | #include <linux/kernel.h> |
@@ -23,8 +23,8 @@ | |||
23 | 23 | ||
24 | #define DRV_MODULE_NAME "ldc" | 24 | #define DRV_MODULE_NAME "ldc" |
25 | #define PFX DRV_MODULE_NAME ": " | 25 | #define PFX DRV_MODULE_NAME ": " |
26 | #define DRV_MODULE_VERSION "1.0" | 26 | #define DRV_MODULE_VERSION "1.1" |
27 | #define DRV_MODULE_RELDATE "June 25, 2007" | 27 | #define DRV_MODULE_RELDATE "July 22, 2008" |
28 | 28 | ||
29 | static char version[] __devinitdata = | 29 | static char version[] __devinitdata = |
30 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 30 | 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) | |||
1235 | unsigned long hv_err, flags; | 1235 | unsigned long hv_err, flags; |
1236 | int err = -EINVAL; | 1236 | int err = -EINVAL; |
1237 | 1237 | ||
1238 | spin_lock_irqsave(&lp->lock, flags); | 1238 | if (!name || |
1239 | 1239 | (lp->state != LDC_STATE_INIT)) | |
1240 | if (!name) | 1240 | return -EINVAL; |
1241 | goto out_err; | ||
1242 | |||
1243 | if (lp->state != LDC_STATE_INIT) | ||
1244 | goto out_err; | ||
1245 | 1241 | ||
1246 | snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); | 1242 | snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); |
1247 | snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); | 1243 | 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) | |||
1250 | IRQF_SAMPLE_RANDOM | IRQF_SHARED, | 1246 | IRQF_SAMPLE_RANDOM | IRQF_SHARED, |
1251 | lp->rx_irq_name, lp); | 1247 | lp->rx_irq_name, lp); |
1252 | if (err) | 1248 | if (err) |
1253 | goto out_err; | 1249 | return err; |
1254 | 1250 | ||
1255 | err = request_irq(lp->cfg.tx_irq, ldc_tx, | 1251 | err = request_irq(lp->cfg.tx_irq, ldc_tx, |
1256 | IRQF_SAMPLE_RANDOM | IRQF_SHARED, | 1252 | IRQF_SAMPLE_RANDOM | IRQF_SHARED, |
1257 | lp->tx_irq_name, lp); | 1253 | lp->tx_irq_name, lp); |
1258 | if (err) | 1254 | if (err) { |
1259 | goto out_free_rx_irq; | 1255 | free_irq(lp->cfg.rx_irq, lp); |
1256 | return err; | ||
1257 | } | ||
1258 | |||
1260 | 1259 | ||
1260 | spin_lock_irqsave(&lp->lock, flags); | ||
1261 | |||
1262 | enable_irq(lp->cfg.rx_irq); | ||
1263 | enable_irq(lp->cfg.tx_irq); | ||
1261 | 1264 | ||
1262 | lp->flags |= LDC_FLAG_REGISTERED_IRQS; | 1265 | lp->flags |= LDC_FLAG_REGISTERED_IRQS; |
1263 | 1266 | ||
1264 | err = -ENODEV; | 1267 | err = -ENODEV; |
1265 | hv_err = sun4v_ldc_tx_qconf(lp->id, 0, 0); | 1268 | hv_err = sun4v_ldc_tx_qconf(lp->id, 0, 0); |
1266 | if (hv_err) | 1269 | if (hv_err) |
1267 | goto out_free_tx_irq; | 1270 | goto out_free_irqs; |
1268 | 1271 | ||
1269 | hv_err = sun4v_ldc_tx_qconf(lp->id, lp->tx_ra, lp->tx_num_entries); | 1272 | hv_err = sun4v_ldc_tx_qconf(lp->id, lp->tx_ra, lp->tx_num_entries); |
1270 | if (hv_err) | 1273 | if (hv_err) |
1271 | goto out_free_tx_irq; | 1274 | goto out_free_irqs; |
1272 | 1275 | ||
1273 | hv_err = sun4v_ldc_rx_qconf(lp->id, 0, 0); | 1276 | hv_err = sun4v_ldc_rx_qconf(lp->id, 0, 0); |
1274 | if (hv_err) | 1277 | if (hv_err) |
@@ -1304,14 +1307,11 @@ out_unmap_rx: | |||
1304 | out_unmap_tx: | 1307 | out_unmap_tx: |
1305 | sun4v_ldc_tx_qconf(lp->id, 0, 0); | 1308 | sun4v_ldc_tx_qconf(lp->id, 0, 0); |
1306 | 1309 | ||
1307 | out_free_tx_irq: | 1310 | out_free_irqs: |
1308 | lp->flags &= ~LDC_FLAG_REGISTERED_IRQS; | 1311 | lp->flags &= ~LDC_FLAG_REGISTERED_IRQS; |
1309 | free_irq(lp->cfg.tx_irq, lp); | 1312 | free_irq(lp->cfg.tx_irq, lp); |
1310 | |||
1311 | out_free_rx_irq: | ||
1312 | free_irq(lp->cfg.rx_irq, lp); | 1313 | free_irq(lp->cfg.rx_irq, lp); |
1313 | 1314 | ||
1314 | out_err: | ||
1315 | spin_unlock_irqrestore(&lp->lock, flags); | 1315 | spin_unlock_irqrestore(&lp->lock, flags); |
1316 | 1316 | ||
1317 | return err; | 1317 | return err; |
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index bedc4c159b1c..a0c6a97eec6e 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
@@ -884,6 +884,16 @@ static struct notifier_block sparc64_cpufreq_notifier_block = { | |||
884 | .notifier_call = sparc64_cpufreq_notifier | 884 | .notifier_call = sparc64_cpufreq_notifier |
885 | }; | 885 | }; |
886 | 886 | ||
887 | static int __init register_sparc64_cpufreq_notifier(void) | ||
888 | { | ||
889 | |||
890 | cpufreq_register_notifier(&sparc64_cpufreq_notifier_block, | ||
891 | CPUFREQ_TRANSITION_NOTIFIER); | ||
892 | return 0; | ||
893 | } | ||
894 | |||
895 | core_initcall(register_sparc64_cpufreq_notifier); | ||
896 | |||
887 | #endif /* CONFIG_CPU_FREQ */ | 897 | #endif /* CONFIG_CPU_FREQ */ |
888 | 898 | ||
889 | static int sparc64_next_event(unsigned long delta, | 899 | static int sparc64_next_event(unsigned long delta, |
@@ -1050,11 +1060,6 @@ void __init time_init(void) | |||
1050 | sparc64_clockevent.mult, sparc64_clockevent.shift); | 1060 | sparc64_clockevent.mult, sparc64_clockevent.shift); |
1051 | 1061 | ||
1052 | setup_sparc64_timer(); | 1062 | setup_sparc64_timer(); |
1053 | |||
1054 | #ifdef CONFIG_CPU_FREQ | ||
1055 | cpufreq_register_notifier(&sparc64_cpufreq_notifier_block, | ||
1056 | CPUFREQ_TRANSITION_NOTIFIER); | ||
1057 | #endif | ||
1058 | } | 1063 | } |
1059 | 1064 | ||
1060 | unsigned long long sched_clock(void) | 1065 | unsigned long long sched_clock(void) |