aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSowmini Varadhan <sowmini.varadhan@oracle.com>2014-09-16 11:37:08 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-16 21:31:31 -0400
commitc21c4ab0d6921f7160a43216fa6973b5924de561 (patch)
tree8f850b4f2103eace27bf0f4320042d98562043e4 /arch
parent05aa1651e8b9ca078b1808a2fe7b50703353ec02 (diff)
sparc64: Move request_irq() from ldc_bind() to ldc_alloc()
The request_irq() needs to be done from ldc_alloc() to avoid the following (caught by lockdep) [00000000004a0738] __might_sleep+0xf8/0x120 [000000000058bea4] kmem_cache_alloc_trace+0x184/0x2c0 [00000000004faf80] request_threaded_irq+0x80/0x160 [000000000044f71c] ldc_bind+0x7c/0x220 [0000000000452454] vio_port_up+0x54/0xe0 [00000000101f6778] probe_disk+0x38/0x220 [sunvdc] [00000000101f6b8c] vdc_port_probe+0x22c/0x300 [sunvdc] [0000000000451a88] vio_device_probe+0x48/0x60 [000000000074c56c] really_probe+0x6c/0x300 [000000000074c83c] driver_probe_device+0x3c/0xa0 [000000000074c92c] __driver_attach+0x8c/0xa0 [000000000074a6ec] bus_for_each_dev+0x6c/0xa0 [000000000074c1dc] driver_attach+0x1c/0x40 [000000000074b0fc] bus_add_driver+0xbc/0x280 Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com> Acked-by: Dwight Engen <dwight.engen@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/sparc/include/asm/ldc.h5
-rw-r--r--arch/sparc/kernel/ds.c4
-rw-r--r--arch/sparc/kernel/ldc.c41
-rw-r--r--arch/sparc/kernel/viohs.c4
4 files changed, 28 insertions, 26 deletions
diff --git a/arch/sparc/include/asm/ldc.h b/arch/sparc/include/asm/ldc.h
index c8c67f621f4f..58ab64de25d2 100644
--- a/arch/sparc/include/asm/ldc.h
+++ b/arch/sparc/include/asm/ldc.h
@@ -53,13 +53,14 @@ struct ldc_channel;
53/* Allocate state for a channel. */ 53/* Allocate state for a channel. */
54struct ldc_channel *ldc_alloc(unsigned long id, 54struct ldc_channel *ldc_alloc(unsigned long id,
55 const struct ldc_channel_config *cfgp, 55 const struct ldc_channel_config *cfgp,
56 void *event_arg); 56 void *event_arg,
57 const char *name);
57 58
58/* Shut down and free state for a channel. */ 59/* Shut down and free state for a channel. */
59void ldc_free(struct ldc_channel *lp); 60void ldc_free(struct ldc_channel *lp);
60 61
61/* Register TX and RX queues of the link with the hypervisor. */ 62/* Register TX and RX queues of the link with the hypervisor. */
62int ldc_bind(struct ldc_channel *lp, const char *name); 63int ldc_bind(struct ldc_channel *lp);
63 64
64/* For non-RAW protocols we need to complete a handshake before 65/* For non-RAW protocols we need to complete a handshake before
65 * communication can proceed. ldc_connect() does that, if the 66 * communication can proceed. ldc_connect() does that, if the
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c
index dff60abbea01..f87a55d77094 100644
--- a/arch/sparc/kernel/ds.c
+++ b/arch/sparc/kernel/ds.c
@@ -1200,14 +1200,14 @@ static int ds_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1200 ds_cfg.tx_irq = vdev->tx_irq; 1200 ds_cfg.tx_irq = vdev->tx_irq;
1201 ds_cfg.rx_irq = vdev->rx_irq; 1201 ds_cfg.rx_irq = vdev->rx_irq;
1202 1202
1203 lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp); 1203 lp = ldc_alloc(vdev->channel_id, &ds_cfg, dp, "DS");
1204 if (IS_ERR(lp)) { 1204 if (IS_ERR(lp)) {
1205 err = PTR_ERR(lp); 1205 err = PTR_ERR(lp);
1206 goto out_free_ds_states; 1206 goto out_free_ds_states;
1207 } 1207 }
1208 dp->lp = lp; 1208 dp->lp = lp;
1209 1209
1210 err = ldc_bind(lp, "DS"); 1210 err = ldc_bind(lp);
1211 if (err) 1211 if (err)
1212 goto out_free_ldc; 1212 goto out_free_ldc;
1213 1213
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c
index 66dacd56bb10..27bb55485472 100644
--- a/arch/sparc/kernel/ldc.c
+++ b/arch/sparc/kernel/ldc.c
@@ -1078,7 +1078,8 @@ static void ldc_iommu_release(struct ldc_channel *lp)
1078 1078
1079struct ldc_channel *ldc_alloc(unsigned long id, 1079struct ldc_channel *ldc_alloc(unsigned long id,
1080 const struct ldc_channel_config *cfgp, 1080 const struct ldc_channel_config *cfgp,
1081 void *event_arg) 1081 void *event_arg,
1082 const char *name)
1082{ 1083{
1083 struct ldc_channel *lp; 1084 struct ldc_channel *lp;
1084 const struct ldc_mode_ops *mops; 1085 const struct ldc_mode_ops *mops;
@@ -1093,6 +1094,8 @@ struct ldc_channel *ldc_alloc(unsigned long id,
1093 err = -EINVAL; 1094 err = -EINVAL;
1094 if (!cfgp) 1095 if (!cfgp)
1095 goto out_err; 1096 goto out_err;
1097 if (!name)
1098 goto out_err;
1096 1099
1097 switch (cfgp->mode) { 1100 switch (cfgp->mode) {
1098 case LDC_MODE_RAW: 1101 case LDC_MODE_RAW:
@@ -1185,6 +1188,21 @@ struct ldc_channel *ldc_alloc(unsigned long id,
1185 1188
1186 INIT_HLIST_HEAD(&lp->mh_list); 1189 INIT_HLIST_HEAD(&lp->mh_list);
1187 1190
1191 snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name);
1192 snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
1193
1194 err = request_irq(lp->cfg.rx_irq, ldc_rx, 0,
1195 lp->rx_irq_name, lp);
1196 if (err)
1197 goto out_free_txq;
1198
1199 err = request_irq(lp->cfg.tx_irq, ldc_tx, 0,
1200 lp->tx_irq_name, lp);
1201 if (err) {
1202 free_irq(lp->cfg.rx_irq, lp);
1203 goto out_free_txq;
1204 }
1205
1188 return lp; 1206 return lp;
1189 1207
1190out_free_txq: 1208out_free_txq:
@@ -1237,31 +1255,14 @@ EXPORT_SYMBOL(ldc_free);
1237 * state. This does not initiate a handshake, ldc_connect() does 1255 * state. This does not initiate a handshake, ldc_connect() does
1238 * that. 1256 * that.
1239 */ 1257 */
1240int ldc_bind(struct ldc_channel *lp, const char *name) 1258int ldc_bind(struct ldc_channel *lp)
1241{ 1259{
1242 unsigned long hv_err, flags; 1260 unsigned long hv_err, flags;
1243 int err = -EINVAL; 1261 int err = -EINVAL;
1244 1262
1245 if (!name || 1263 if (lp->state != LDC_STATE_INIT)
1246 (lp->state != LDC_STATE_INIT))
1247 return -EINVAL; 1264 return -EINVAL;
1248 1265
1249 snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name);
1250 snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
1251
1252 err = request_irq(lp->cfg.rx_irq, ldc_rx, 0,
1253 lp->rx_irq_name, lp);
1254 if (err)
1255 return err;
1256
1257 err = request_irq(lp->cfg.tx_irq, ldc_tx, 0,
1258 lp->tx_irq_name, lp);
1259 if (err) {
1260 free_irq(lp->cfg.rx_irq, lp);
1261 return err;
1262 }
1263
1264
1265 spin_lock_irqsave(&lp->lock, flags); 1266 spin_lock_irqsave(&lp->lock, flags);
1266 1267
1267 enable_irq(lp->cfg.rx_irq); 1268 enable_irq(lp->cfg.rx_irq);
diff --git a/arch/sparc/kernel/viohs.c b/arch/sparc/kernel/viohs.c
index f8e7dd53e1c7..9c5fbd0b8a04 100644
--- a/arch/sparc/kernel/viohs.c
+++ b/arch/sparc/kernel/viohs.c
@@ -714,7 +714,7 @@ int vio_ldc_alloc(struct vio_driver_state *vio,
714 cfg.tx_irq = vio->vdev->tx_irq; 714 cfg.tx_irq = vio->vdev->tx_irq;
715 cfg.rx_irq = vio->vdev->rx_irq; 715 cfg.rx_irq = vio->vdev->rx_irq;
716 716
717 lp = ldc_alloc(vio->vdev->channel_id, &cfg, event_arg); 717 lp = ldc_alloc(vio->vdev->channel_id, &cfg, event_arg, vio->name);
718 if (IS_ERR(lp)) 718 if (IS_ERR(lp))
719 return PTR_ERR(lp); 719 return PTR_ERR(lp);
720 720
@@ -746,7 +746,7 @@ void vio_port_up(struct vio_driver_state *vio)
746 746
747 err = 0; 747 err = 0;
748 if (state == LDC_STATE_INIT) { 748 if (state == LDC_STATE_INIT) {
749 err = ldc_bind(vio->lp, vio->name); 749 err = ldc_bind(vio->lp);
750 if (err) 750 if (err)
751 printk(KERN_WARNING "%s: Port %lu bind failed, " 751 printk(KERN_WARNING "%s: Port %lu bind failed, "
752 "err=%d\n", 752 "err=%d\n",