hc
2024-05-10 10ebd8556b7990499c896a550e3d416b444211e6
kernel/arch/mips/sgi-ip27/ip27-xtalk.c
....@@ -1,17 +1,20 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
34 * Copyright (C) 1999, 2000 Silcon Graphics, Inc.
45 * Copyright (C) 2004 Christoph Hellwig.
5
- * Released under GPL v2.
66 *
77 * Generic XTALK initialization code
88 */
99
1010 #include <linux/kernel.h>
1111 #include <linux/smp.h>
12
+#include <linux/platform_device.h>
13
+#include <linux/platform_data/sgi-w1.h>
14
+#include <linux/platform_data/xtalk-bridge.h>
15
+#include <asm/sn/addrs.h>
1216 #include <asm/sn/types.h>
1317 #include <asm/sn/klconfig.h>
14
-#include <asm/sn/hub.h>
1518 #include <asm/pci/bridge.h>
1619 #include <asm/xtalk/xtalk.h>
1720
....@@ -20,7 +23,107 @@
2023 #define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbow in Xbridge */
2124 #define BASE_XBOW_PORT 8 /* Lowest external port */
2225
23
-extern int bridge_probe(nasid_t nasid, int widget, int masterwid);
26
+static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
27
+{
28
+ struct xtalk_bridge_platform_data *bd;
29
+ struct sgi_w1_platform_data *wd;
30
+ struct platform_device *pdev_wd;
31
+ struct platform_device *pdev_bd;
32
+ struct resource w1_res;
33
+ unsigned long offset;
34
+
35
+ offset = NODE_OFFSET(nasid);
36
+
37
+ wd = kzalloc(sizeof(*wd), GFP_KERNEL);
38
+ if (!wd) {
39
+ pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
40
+ return;
41
+ }
42
+
43
+ snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx",
44
+ offset + (widget << SWIN_SIZE_BITS));
45
+
46
+ memset(&w1_res, 0, sizeof(w1_res));
47
+ w1_res.start = offset + (widget << SWIN_SIZE_BITS) +
48
+ offsetof(struct bridge_regs, b_nic);
49
+ w1_res.end = w1_res.start + 3;
50
+ w1_res.flags = IORESOURCE_MEM;
51
+
52
+ pdev_wd = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
53
+ if (!pdev_wd) {
54
+ pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
55
+ goto err_kfree_wd;
56
+ }
57
+ if (platform_device_add_resources(pdev_wd, &w1_res, 1)) {
58
+ pr_warn("xtalk:n%d/%x bridge failed to add platform resources.\n", nasid, widget);
59
+ goto err_put_pdev_wd;
60
+ }
61
+ if (platform_device_add_data(pdev_wd, wd, sizeof(*wd))) {
62
+ pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget);
63
+ goto err_put_pdev_wd;
64
+ }
65
+ if (platform_device_add(pdev_wd)) {
66
+ pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget);
67
+ goto err_put_pdev_wd;
68
+ }
69
+ /* platform_device_add_data() duplicates the data */
70
+ kfree(wd);
71
+
72
+ bd = kzalloc(sizeof(*bd), GFP_KERNEL);
73
+ if (!bd) {
74
+ pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
75
+ goto err_unregister_pdev_wd;
76
+ }
77
+ pdev_bd = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
78
+ if (!pdev_bd) {
79
+ pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
80
+ goto err_kfree_bd;
81
+ }
82
+
83
+
84
+ bd->bridge_addr = RAW_NODE_SWIN_BASE(nasid, widget);
85
+ bd->intr_addr = BIT_ULL(47) + 0x01800000 + PI_INT_PEND_MOD;
86
+ bd->nasid = nasid;
87
+ bd->masterwid = masterwid;
88
+
89
+ bd->mem.name = "Bridge PCI MEM";
90
+ bd->mem.start = offset + (widget << SWIN_SIZE_BITS) + BRIDGE_DEVIO0;
91
+ bd->mem.end = offset + (widget << SWIN_SIZE_BITS) + SWIN_SIZE - 1;
92
+ bd->mem.flags = IORESOURCE_MEM;
93
+ bd->mem_offset = offset;
94
+
95
+ bd->io.name = "Bridge PCI IO";
96
+ bd->io.start = offset + (widget << SWIN_SIZE_BITS) + BRIDGE_DEVIO0;
97
+ bd->io.end = offset + (widget << SWIN_SIZE_BITS) + SWIN_SIZE - 1;
98
+ bd->io.flags = IORESOURCE_IO;
99
+ bd->io_offset = offset;
100
+
101
+ if (platform_device_add_data(pdev_bd, bd, sizeof(*bd))) {
102
+ pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget);
103
+ goto err_put_pdev_bd;
104
+ }
105
+ if (platform_device_add(pdev_bd)) {
106
+ pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget);
107
+ goto err_put_pdev_bd;
108
+ }
109
+ /* platform_device_add_data() duplicates the data */
110
+ kfree(bd);
111
+ pr_info("xtalk:n%d/%x bridge widget\n", nasid, widget);
112
+ return;
113
+
114
+err_put_pdev_bd:
115
+ platform_device_put(pdev_bd);
116
+err_kfree_bd:
117
+ kfree(bd);
118
+err_unregister_pdev_wd:
119
+ platform_device_unregister(pdev_wd);
120
+ return;
121
+err_put_pdev_wd:
122
+ platform_device_put(pdev_wd);
123
+err_kfree_wd:
124
+ kfree(wd);
125
+ return;
126
+}
24127
25128 static int probe_one_port(nasid_t nasid, int widget, int masterwid)
26129 {
....@@ -31,15 +134,14 @@
31134 (RAW_NODE_SWIN_BASE(nasid, widget) + WIDGET_ID);
32135 partnum = XWIDGET_PART_NUM(widget_id);
33136
34
- printk(KERN_INFO "Cpu %d, Nasid 0x%x, widget 0x%x (partnum 0x%x) is ",
35
- smp_processor_id(), nasid, widget, partnum);
36
-
37137 switch (partnum) {
38138 case BRIDGE_WIDGET_PART_NUM:
39139 case XBRIDGE_WIDGET_PART_NUM:
40
- bridge_probe(nasid, widget, masterwid);
140
+ bridge_platform_create(nasid, widget, masterwid);
41141 break;
42142 default:
143
+ pr_info("xtalk:n%d/%d unknown widget (0x%x)\n",
144
+ nasid, widget, partnum);
43145 break;
44146 }
45147
....@@ -51,8 +153,6 @@
51153 lboard_t *brd;
52154 klxbow_t *xbow_p;
53155 unsigned masterwid, i;
54
-
55
- printk("is xbow\n");
56156
57157 /*
58158 * found xbow, so may have multiple bridges
....@@ -99,14 +199,12 @@
99199 return 0;
100200 }
101201
102
-void xtalk_probe_node(cnodeid_t nid)
202
+static void xtalk_probe_node(nasid_t nasid)
103203 {
104204 volatile u64 hubreg;
105
- nasid_t nasid;
106205 xwidget_part_num_t partnum;
107206 widgetreg_t widget_id;
108207
109
- nasid = COMPACT_TO_NASID_NODEID(nid);
110208 hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
111209
112210 /* check whether the link is up */
....@@ -117,19 +215,28 @@
117215 (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
118216 partnum = XWIDGET_PART_NUM(widget_id);
119217
120
- printk(KERN_INFO "Cpu %d, Nasid 0x%x: partnum 0x%x is ",
121
- smp_processor_id(), nasid, partnum);
122
-
123218 switch (partnum) {
124219 case BRIDGE_WIDGET_PART_NUM:
125
- bridge_probe(nasid, 0x8, 0xa);
220
+ bridge_platform_create(nasid, 0x8, 0xa);
126221 break;
127222 case XBOW_WIDGET_PART_NUM:
128223 case XXBOW_WIDGET_PART_NUM:
224
+ pr_info("xtalk:n%d/0 xbow widget\n", nasid);
129225 xbow_probe(nasid);
130226 break;
131227 default:
132
- printk(" unknown widget??\n");
228
+ pr_info("xtalk:n%d/0 unknown widget (0x%x)\n", nasid, partnum);
133229 break;
134230 }
135231 }
232
+
233
+static int __init xtalk_init(void)
234
+{
235
+ nasid_t nasid;
236
+
237
+ for_each_online_node(nasid)
238
+ xtalk_probe_node(nasid);
239
+
240
+ return 0;
241
+}
242
+arch_initcall(xtalk_init);