arch/mips/sgi-ip27/ip27-xtalk.c

Source file repositories/reference/linux-study-clean/arch/mips/sgi-ip27/ip27-xtalk.c

File Facts

System
Linux kernel
Corpus path
arch/mips/sgi-ip27/ip27-xtalk.c
Extension
.c
Size
6242 bytes
Lines
243
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
 * Copyright (C) 1999, 2000 Silcon Graphics, Inc.
 * Copyright (C) 2004 Christoph Hellwig.
 *
 * Generic XTALK initialization code
 */

#include <linux/kernel.h>
#include <linux/smp.h>
#include <linux/platform_device.h>
#include <linux/platform_data/sgi-w1.h>
#include <linux/platform_data/xtalk-bridge.h>
#include <asm/sn/addrs.h>
#include <asm/sn/types.h>
#include <asm/sn/klconfig.h>
#include <asm/pci/bridge.h>
#include <asm/xtalk/xtalk.h>


#define XBOW_WIDGET_PART_NUM	0x0
#define XXBOW_WIDGET_PART_NUM	0xd000	/* Xbow in Xbridge */
#define BASE_XBOW_PORT		8     /* Lowest external port */

static void bridge_platform_create(nasid_t nasid, int widget, int masterwid)
{
	struct xtalk_bridge_platform_data *bd;
	struct sgi_w1_platform_data *wd;
	struct platform_device *pdev_wd;
	struct platform_device *pdev_bd;
	struct resource w1_res;
	unsigned long offset;

	offset = NODE_OFFSET(nasid);

	wd = kzalloc_obj(*wd);
	if (!wd) {
		pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
		return;
	}

	snprintf(wd->dev_id, sizeof(wd->dev_id), "bridge-%012lx",
		 offset + (widget << SWIN_SIZE_BITS));

	memset(&w1_res, 0, sizeof(w1_res));
	w1_res.start = offset + (widget << SWIN_SIZE_BITS) +
				offsetof(struct bridge_regs, b_nic);
	w1_res.end = w1_res.start + 3;
	w1_res.flags = IORESOURCE_MEM;

	pdev_wd = platform_device_alloc("sgi_w1", PLATFORM_DEVID_AUTO);
	if (!pdev_wd) {
		pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
		goto err_kfree_wd;
	}
	if (platform_device_add_resources(pdev_wd, &w1_res, 1)) {
		pr_warn("xtalk:n%d/%x bridge failed to add platform resources.\n", nasid, widget);
		goto err_put_pdev_wd;
	}
	if (platform_device_add_data(pdev_wd, wd, sizeof(*wd))) {
		pr_warn("xtalk:n%d/%x bridge failed to add platform data.\n", nasid, widget);
		goto err_put_pdev_wd;
	}
	if (platform_device_add(pdev_wd)) {
		pr_warn("xtalk:n%d/%x bridge failed to add platform device.\n", nasid, widget);
		goto err_put_pdev_wd;
	}
	/* platform_device_add_data() duplicates the data */
	kfree(wd);

	bd = kzalloc_obj(*bd);
	if (!bd) {
		pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
		goto err_unregister_pdev_wd;
	}
	pdev_bd = platform_device_alloc("xtalk-bridge", PLATFORM_DEVID_AUTO);
	if (!pdev_bd) {
		pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget);
		goto err_kfree_bd;
	}


	bd->bridge_addr = RAW_NODE_SWIN_BASE(nasid, widget);
	bd->intr_addr	= BIT_ULL(47) + 0x01800000 + PI_INT_PEND_MOD;
	bd->nasid	= nasid;
	bd->masterwid	= masterwid;

	bd->mem.name	= "Bridge PCI MEM";
	bd->mem.start	= offset + (widget << SWIN_SIZE_BITS) + BRIDGE_DEVIO0;

Annotation

Implementation Notes