Merge tag 'ntb-5.3' of git://github.com/jonmason/ntb
[sfrench/cifs-2.6.git] / drivers / ntb / hw / mscc / ntb_hw_switchtec.c
index db4967748e4d1fe4de8e52da14b843826ff02077..f4959458d90967621919b6274814ef3c1befc244 100644 (file)
@@ -86,7 +86,8 @@ struct switchtec_ntb {
        bool link_is_up;
        enum ntb_speed link_speed;
        enum ntb_width link_width;
-       struct work_struct link_reinit_work;
+       struct work_struct check_link_status_work;
+       bool link_force_down;
 };
 
 static struct switchtec_ntb *ntb_sndev(struct ntb_dev *ntb)
@@ -485,33 +486,11 @@ enum switchtec_msg {
 
 static int switchtec_ntb_reinit_peer(struct switchtec_ntb *sndev);
 
-static void link_reinit_work(struct work_struct *work)
-{
-       struct switchtec_ntb *sndev;
-
-       sndev = container_of(work, struct switchtec_ntb, link_reinit_work);
-
-       switchtec_ntb_reinit_peer(sndev);
-}
-
-static void switchtec_ntb_check_link(struct switchtec_ntb *sndev,
-                                    enum switchtec_msg msg)
+static void switchtec_ntb_link_status_update(struct switchtec_ntb *sndev)
 {
        int link_sta;
        int old = sndev->link_is_up;
 
-       if (msg == MSG_LINK_FORCE_DOWN) {
-               schedule_work(&sndev->link_reinit_work);
-
-               if (sndev->link_is_up) {
-                       sndev->link_is_up = 0;
-                       ntb_link_event(&sndev->ntb);
-                       dev_info(&sndev->stdev->dev, "ntb link forced down\n");
-               }
-
-               return;
-       }
-
        link_sta = sndev->self_shared->link_sta;
        if (link_sta) {
                u64 peer = ioread64(&sndev->peer_shared->magic);
@@ -536,6 +515,38 @@ static void switchtec_ntb_check_link(struct switchtec_ntb *sndev,
        }
 }
 
+static void check_link_status_work(struct work_struct *work)
+{
+       struct switchtec_ntb *sndev;
+
+       sndev = container_of(work, struct switchtec_ntb,
+                            check_link_status_work);
+
+       if (sndev->link_force_down) {
+               sndev->link_force_down = false;
+               switchtec_ntb_reinit_peer(sndev);
+
+               if (sndev->link_is_up) {
+                       sndev->link_is_up = 0;
+                       ntb_link_event(&sndev->ntb);
+                       dev_info(&sndev->stdev->dev, "ntb link forced down\n");
+               }
+
+               return;
+       }
+
+       switchtec_ntb_link_status_update(sndev);
+}
+
+static void switchtec_ntb_check_link(struct switchtec_ntb *sndev,
+                                     enum switchtec_msg msg)
+{
+       if (msg == MSG_LINK_FORCE_DOWN)
+               sndev->link_force_down = true;
+
+       schedule_work(&sndev->check_link_status_work);
+}
+
 static void switchtec_ntb_link_notification(struct switchtec_dev *stdev)
 {
        struct switchtec_ntb *sndev = stdev->sndev;
@@ -568,7 +579,7 @@ static int switchtec_ntb_link_enable(struct ntb_dev *ntb,
        sndev->self_shared->link_sta = 1;
        switchtec_ntb_send_msg(sndev, LINK_MESSAGE, MSG_LINK_UP);
 
-       switchtec_ntb_check_link(sndev, MSG_CHECK_LINK);
+       switchtec_ntb_link_status_update(sndev);
 
        return 0;
 }
@@ -582,7 +593,7 @@ static int switchtec_ntb_link_disable(struct ntb_dev *ntb)
        sndev->self_shared->link_sta = 0;
        switchtec_ntb_send_msg(sndev, LINK_MESSAGE, MSG_LINK_DOWN);
 
-       switchtec_ntb_check_link(sndev, MSG_CHECK_LINK);
+       switchtec_ntb_link_status_update(sndev);
 
        return 0;
 }
@@ -835,7 +846,8 @@ static int switchtec_ntb_init_sndev(struct switchtec_ntb *sndev)
        sndev->ntb.topo = NTB_TOPO_SWITCH;
        sndev->ntb.ops = &switchtec_ntb_ops;
 
-       INIT_WORK(&sndev->link_reinit_work, link_reinit_work);
+       INIT_WORK(&sndev->check_link_status_work, check_link_status_work);
+       sndev->link_force_down = false;
 
        sndev->self_partition = sndev->stdev->partition;
 
@@ -872,7 +884,7 @@ static int switchtec_ntb_init_sndev(struct switchtec_ntb *sndev)
                }
 
                sndev->peer_partition = ffs(tpart_vec) - 1;
-               if (!(part_map & (1 << sndev->peer_partition))) {
+               if (!(part_map & (1ULL << sndev->peer_partition))) {
                        dev_err(&sndev->stdev->dev,
                                "ntb target partition is not NT partition\n");
                        return -ENODEV;
@@ -1448,10 +1460,16 @@ static void switchtec_ntb_deinit_db_msg_irq(struct switchtec_ntb *sndev)
 
 static int switchtec_ntb_reinit_peer(struct switchtec_ntb *sndev)
 {
-       dev_info(&sndev->stdev->dev, "peer reinitialized\n");
-       switchtec_ntb_deinit_shared_mw(sndev);
-       switchtec_ntb_init_mw(sndev);
-       return switchtec_ntb_init_shared_mw(sndev);
+       int rc;
+
+       if (crosslink_is_enabled(sndev))
+               return 0;
+
+       dev_info(&sndev->stdev->dev, "reinitialize shared memory window\n");
+       rc = config_rsvd_lut_win(sndev, sndev->mmio_peer_ctrl, 0,
+                                sndev->self_partition,
+                                sndev->self_shared_dma);
+       return rc;
 }
 
 static int switchtec_ntb_add(struct device *dev,