.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org) |
---|
3 | 4 | * Copyright (C) 1999, 2000 Silcon Graphics, Inc. |
---|
4 | 5 | * Copyright (C) 2004 Christoph Hellwig. |
---|
5 | | - * Released under GPL v2. |
---|
6 | 6 | * |
---|
7 | 7 | * Generic XTALK initialization code |
---|
8 | 8 | */ |
---|
9 | 9 | |
---|
10 | 10 | #include <linux/kernel.h> |
---|
11 | 11 | #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> |
---|
12 | 16 | #include <asm/sn/types.h> |
---|
13 | 17 | #include <asm/sn/klconfig.h> |
---|
14 | | -#include <asm/sn/hub.h> |
---|
15 | 18 | #include <asm/pci/bridge.h> |
---|
16 | 19 | #include <asm/xtalk/xtalk.h> |
---|
17 | 20 | |
---|
.. | .. |
---|
20 | 23 | #define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbow in Xbridge */ |
---|
21 | 24 | #define BASE_XBOW_PORT 8 /* Lowest external port */ |
---|
22 | 25 | |
---|
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 | +} |
---|
24 | 127 | |
---|
25 | 128 | static int probe_one_port(nasid_t nasid, int widget, int masterwid) |
---|
26 | 129 | { |
---|
.. | .. |
---|
31 | 134 | (RAW_NODE_SWIN_BASE(nasid, widget) + WIDGET_ID); |
---|
32 | 135 | partnum = XWIDGET_PART_NUM(widget_id); |
---|
33 | 136 | |
---|
34 | | - printk(KERN_INFO "Cpu %d, Nasid 0x%x, widget 0x%x (partnum 0x%x) is ", |
---|
35 | | - smp_processor_id(), nasid, widget, partnum); |
---|
36 | | - |
---|
37 | 137 | switch (partnum) { |
---|
38 | 138 | case BRIDGE_WIDGET_PART_NUM: |
---|
39 | 139 | case XBRIDGE_WIDGET_PART_NUM: |
---|
40 | | - bridge_probe(nasid, widget, masterwid); |
---|
| 140 | + bridge_platform_create(nasid, widget, masterwid); |
---|
41 | 141 | break; |
---|
42 | 142 | default: |
---|
| 143 | + pr_info("xtalk:n%d/%d unknown widget (0x%x)\n", |
---|
| 144 | + nasid, widget, partnum); |
---|
43 | 145 | break; |
---|
44 | 146 | } |
---|
45 | 147 | |
---|
.. | .. |
---|
51 | 153 | lboard_t *brd; |
---|
52 | 154 | klxbow_t *xbow_p; |
---|
53 | 155 | unsigned masterwid, i; |
---|
54 | | - |
---|
55 | | - printk("is xbow\n"); |
---|
56 | 156 | |
---|
57 | 157 | /* |
---|
58 | 158 | * found xbow, so may have multiple bridges |
---|
.. | .. |
---|
99 | 199 | return 0; |
---|
100 | 200 | } |
---|
101 | 201 | |
---|
102 | | -void xtalk_probe_node(cnodeid_t nid) |
---|
| 202 | +static void xtalk_probe_node(nasid_t nasid) |
---|
103 | 203 | { |
---|
104 | 204 | volatile u64 hubreg; |
---|
105 | | - nasid_t nasid; |
---|
106 | 205 | xwidget_part_num_t partnum; |
---|
107 | 206 | widgetreg_t widget_id; |
---|
108 | 207 | |
---|
109 | | - nasid = COMPACT_TO_NASID_NODEID(nid); |
---|
110 | 208 | hubreg = REMOTE_HUB_L(nasid, IIO_LLP_CSR); |
---|
111 | 209 | |
---|
112 | 210 | /* check whether the link is up */ |
---|
.. | .. |
---|
117 | 215 | (RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID); |
---|
118 | 216 | partnum = XWIDGET_PART_NUM(widget_id); |
---|
119 | 217 | |
---|
120 | | - printk(KERN_INFO "Cpu %d, Nasid 0x%x: partnum 0x%x is ", |
---|
121 | | - smp_processor_id(), nasid, partnum); |
---|
122 | | - |
---|
123 | 218 | switch (partnum) { |
---|
124 | 219 | case BRIDGE_WIDGET_PART_NUM: |
---|
125 | | - bridge_probe(nasid, 0x8, 0xa); |
---|
| 220 | + bridge_platform_create(nasid, 0x8, 0xa); |
---|
126 | 221 | break; |
---|
127 | 222 | case XBOW_WIDGET_PART_NUM: |
---|
128 | 223 | case XXBOW_WIDGET_PART_NUM: |
---|
| 224 | + pr_info("xtalk:n%d/0 xbow widget\n", nasid); |
---|
129 | 225 | xbow_probe(nasid); |
---|
130 | 226 | break; |
---|
131 | 227 | default: |
---|
132 | | - printk(" unknown widget??\n"); |
---|
| 228 | + pr_info("xtalk:n%d/0 unknown widget (0x%x)\n", nasid, partnum); |
---|
133 | 229 | break; |
---|
134 | 230 | } |
---|
135 | 231 | } |
---|
| 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); |
---|