hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/fsi/fsi-core.c
....@@ -1,16 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * FSI core driver
34 *
45 * Copyright (C) IBM Corporation 2016
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2 as
8
- * published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
146 *
157 * TODO:
168 * - Rework topology
....@@ -58,6 +50,7 @@
5850 #define FSI_SMODE 0x0 /* R/W: Mode register */
5951 #define FSI_SISC 0x8 /* R/W: Interrupt condition */
6052 #define FSI_SSTAT 0x14 /* R : Slave status */
53
+#define FSI_SLBUS 0x30 /* W : LBUS Ownership */
6154 #define FSI_LLMODE 0x100 /* R/W: Link layer mode register */
6255
6356 /*
....@@ -73,6 +66,11 @@
7366 #define FSI_SMODE_SD_MASK 0xf /* Send delay mask */
7467 #define FSI_SMODE_LBCRR_SHIFT 8 /* Clk ratio shift */
7568 #define FSI_SMODE_LBCRR_MASK 0xf /* Clk ratio mask */
69
+
70
+/*
71
+ * SLBUS fields
72
+ */
73
+#define FSI_SLBUS_FORCE 0x80000000 /* Force LBUS ownership */
7674
7775 /*
7876 * LLMODE fields
....@@ -989,7 +987,7 @@
989987 uint32_t cfam_id;
990988 struct fsi_slave *slave;
991989 uint8_t crc;
992
- __be32 data, llmode;
990
+ __be32 data, llmode, slbus;
993991 int rc;
994992
995993 /* Currently, we only support single slaves on a link, and use the
....@@ -1059,6 +1057,14 @@
10591057 slave->chip_id = prop;
10601058
10611059 }
1060
+
1061
+ slbus = cpu_to_be32(FSI_SLBUS_FORCE);
1062
+ rc = fsi_master_write(master, link, id, FSI_SLAVE_BASE + FSI_SLBUS,
1063
+ &slbus, sizeof(slbus));
1064
+ if (rc)
1065
+ dev_warn(&master->dev,
1066
+ "can't set slbus on slave:%02x:%02x %d\n", link, id,
1067
+ rc);
10621068
10631069 rc = fsi_slave_set_smode(slave);
10641070 if (rc) {
....@@ -1162,10 +1168,18 @@
11621168 return rc;
11631169 }
11641170
1171
+static int fsi_master_link_disable(struct fsi_master *master, int link)
1172
+{
1173
+ if (master->link_enable)
1174
+ return master->link_enable(master, link, false);
1175
+
1176
+ return 0;
1177
+}
1178
+
11651179 static int fsi_master_link_enable(struct fsi_master *master, int link)
11661180 {
11671181 if (master->link_enable)
1168
- return master->link_enable(master, link);
1182
+ return master->link_enable(master, link, true);
11691183
11701184 return 0;
11711185 }
....@@ -1200,12 +1214,15 @@
12001214 }
12011215 rc = fsi_master_break(master, link);
12021216 if (rc) {
1217
+ fsi_master_link_disable(master, link);
12031218 dev_dbg(&master->dev,
12041219 "break to link %d failed: %d\n", link, rc);
12051220 continue;
12061221 }
12071222
1208
- fsi_slave_init(master, link, 0);
1223
+ rc = fsi_slave_init(master, link, 0);
1224
+ if (rc)
1225
+ fsi_master_link_disable(master, link);
12091226 }
12101227
12111228 return 0;
....@@ -1272,6 +1289,19 @@
12721289
12731290 static DEVICE_ATTR(break, 0200, NULL, master_break_store);
12741291
1292
+static struct attribute *master_attrs[] = {
1293
+ &dev_attr_break.attr,
1294
+ &dev_attr_rescan.attr,
1295
+ NULL
1296
+};
1297
+
1298
+ATTRIBUTE_GROUPS(master);
1299
+
1300
+static struct class fsi_master_class = {
1301
+ .name = "fsi-master",
1302
+ .dev_groups = master_groups,
1303
+};
1304
+
12751305 int fsi_master_register(struct fsi_master *master)
12761306 {
12771307 int rc;
....@@ -1279,24 +1309,14 @@
12791309
12801310 mutex_init(&master->scan_lock);
12811311 master->idx = ida_simple_get(&master_ida, 0, INT_MAX, GFP_KERNEL);
1312
+ if (master->idx < 0)
1313
+ return master->idx;
1314
+
12821315 dev_set_name(&master->dev, "fsi%d", master->idx);
1316
+ master->dev.class = &fsi_master_class;
12831317
12841318 rc = device_register(&master->dev);
12851319 if (rc) {
1286
- ida_simple_remove(&master_ida, master->idx);
1287
- return rc;
1288
- }
1289
-
1290
- rc = device_create_file(&master->dev, &dev_attr_rescan);
1291
- if (rc) {
1292
- device_del(&master->dev);
1293
- ida_simple_remove(&master_ida, master->idx);
1294
- return rc;
1295
- }
1296
-
1297
- rc = device_create_file(&master->dev, &dev_attr_break);
1298
- if (rc) {
1299
- device_del(&master->dev);
13001320 ida_simple_remove(&master_ida, master->idx);
13011321 return rc;
13021322 }
....@@ -1381,8 +1401,15 @@
13811401 rc = bus_register(&fsi_bus_type);
13821402 if (rc)
13831403 goto fail_bus;
1404
+
1405
+ rc = class_register(&fsi_master_class);
1406
+ if (rc)
1407
+ goto fail_class;
1408
+
13841409 return 0;
13851410
1411
+ fail_class:
1412
+ bus_unregister(&fsi_bus_type);
13861413 fail_bus:
13871414 unregister_chrdev_region(fsi_base_dev, FSI_CHAR_MAX_DEVICES);
13881415 return rc;
....@@ -1391,6 +1418,7 @@
13911418
13921419 static void fsi_exit(void)
13931420 {
1421
+ class_unregister(&fsi_master_class);
13941422 bus_unregister(&fsi_bus_type);
13951423 unregister_chrdev_region(fsi_base_dev, FSI_CHAR_MAX_DEVICES);
13961424 ida_destroy(&fsi_minor_ida);