⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ops-pmcmsp.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * PMC-Sierra MSP board specific pci_ops * * Copyright 2001 MontaVista Software Inc. * Copyright 2005-2007 PMC-Sierra, Inc * * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net * * Much of the code is derived from the original DDB5074 port by * Geert Uytterhoeven <geert@sonycom.com> * * This program is free software; you can redistribute  it and/or modify it * under  the terms of  the GNU General  Public License as published by the * Free Software Foundation;  either version 2 of the  License, or (at your * option) any later version. * */#define PCI_COUNTERS	1#include <linux/types.h>#include <linux/pci.h>#include <linux/interrupt.h>#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)#include <linux/proc_fs.h>#include <linux/seq_file.h>#endif /* CONFIG_PROC_FS && PCI_COUNTERS */#include <linux/kernel.h>#include <linux/init.h>#include <asm/byteorder.h>#if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)#include <asm/mipsmtregs.h>#endif#include <msp_prom.h>#include <msp_cic_int.h>#include <msp_pci.h>#include <msp_regs.h>#include <msp_regops.h>#define PCI_ACCESS_READ		0#define PCI_ACCESS_WRITE	1#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)static char proc_init;extern struct proc_dir_entry *proc_bus_pci_dir;unsigned int pci_int_count[32];static void pci_proc_init(void);/***************************************************************************** * *  FUNCTION: read_msp_pci_counts *  _________________________________________________________________________ * *  DESCRIPTION: Prints the count of how many times each PCI *               interrupt has asserted. Can be invoked by the *               /proc filesystem. * *  INPUTS:      page    - part of STDOUT calculation *               off     - part of STDOUT calculation *               count   - part of STDOUT calculation *               data    - unused * *  OUTPUTS:     start   - new start location *               eof     - end of file pointer * *  RETURNS:     len     - STDOUT length * ****************************************************************************/static int read_msp_pci_counts(char *page, char **start, off_t off,				int count, int *eof, void *data){	int i;	int len = 0;	unsigned int intcount, total = 0;	for (i = 0; i < 32; ++i) {		intcount = pci_int_count[i];		if (intcount != 0) {			len += sprintf(page + len, "[%d] = %u\n", i, intcount);			total += intcount;		}	}	len += sprintf(page + len, "total = %u\n", total);	if (len <= off+count)		*eof = 1;	*start = page + off;	len -= off;	if (len > count)		len = count;	if (len < 0)		len = 0;	return len;}/***************************************************************************** * *  FUNCTION: gen_pci_cfg_wr *  _________________________________________________________________________ * *  DESCRIPTION: Generates a configuration write cycle for debug purposes. *               The IDSEL line asserted and location and data written are *               immaterial. Just want to be able to prove that a *               configuration write can be correctly generated on the *               PCI bus.  Intent is that this function by invocable from *               the /proc filesystem. * *  INPUTS:      page    - part of STDOUT calculation *               off     - part of STDOUT calculation *               count   - part of STDOUT calculation *               data    - unused * *  OUTPUTS:     start   - new start location *               eof     - end of file pointer * *  RETURNS:     len     - STDOUT length * ****************************************************************************/static int gen_pci_cfg_wr(char *page, char **start, off_t off,				int count, int *eof, void *data){	unsigned char where = 0; /* Write to static Device/Vendor ID */	unsigned char bus_num = 0; /* Bus 0 */	unsigned char dev_fn = 0xF; /* Arbitrary device number */	u32 wr_data = 0xFF00AA00; /* Arbitrary data */	struct msp_pci_regs *preg = (void *)PCI_BASE_REG;	int len = 0;	unsigned long value;	int intr;	len += sprintf(page + len, "PMC MSP PCI: Beginning\n");	if (proc_init == 0) {		pci_proc_init();		proc_init = ~0;	}	len += sprintf(page + len, "PMC MSP PCI: Before Cfg Wr\n");	/*	 * Generate PCI Configuration Write Cycle	 */	/* Clear cause register bits */	preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);	/* Setup address that is to appear on PCI bus */	preg->config_addr = BPCI_CFGADDR_ENABLE |		(bus_num << BPCI_CFGADDR_BUSNUM_SHF) |		(dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) |		(where & 0xFC);	value = cpu_to_le32(wr_data);	/* Launch the PCI configuration write cycle */	*PCI_CONFIG_SPACE_REG = value;	/*	 * Check if the PCI configuration cycle (rd or wr) succeeded, by	 * checking the status bits for errors like master or target abort.	 */	intr = preg->if_status;	len += sprintf(page + len, "PMC MSP PCI: After Cfg Wr\n");	/* Handle STDOUT calculations */	if (len <= off+count)		*eof = 1;	*start = page + off;	len -= off;	if (len > count)		len = count;	if (len < 0)		len = 0;	return len;}/***************************************************************************** * *  FUNCTION: pci_proc_init *  _________________________________________________________________________ * *  DESCRIPTION: Create entries in the /proc filesystem for debug access. * *  INPUTS:      none * *  OUTPUTS:     none * *  RETURNS:     none * ****************************************************************************/static void pci_proc_init(void){	create_proc_read_entry("pmc_msp_pci_rd_cnt", 0, NULL,				read_msp_pci_counts, NULL);	create_proc_read_entry("pmc_msp_pci_cfg_wr", 0, NULL,				gen_pci_cfg_wr, NULL);}#endif /* CONFIG_PROC_FS && PCI_COUNTERS */DEFINE_SPINLOCK(bpci_lock);/***************************************************************************** * *  STRUCT: pci_io_resource *  _________________________________________________________________________ * *  DESCRIPTION: Defines the address range that pciauto() will use to *               assign to the I/O BARs of PCI devices. * *               Use the start and end addresses of the MSP7120 PCI Host *               Controller I/O space, in the form that they appear on the *               PCI bus AFTER MSP7120 has performed address translation. * *               For I/O accesses, MSP7120 ignores OATRAN and maps I/O *               accesses into the bottom 0xFFF region of address space, *               so that is the range to put into the pci_io_resource *               struct. * *               In MSP4200, the start address was 0x04 instead of the * 		 expected 0x00. Will just assume there was a good reason * 		 for this! * *  NOTES:       Linux, by default, will assign I/O space to the lowest *               region of address space. Since MSP7120 and Linux, *               by default, have no offset in between how they map, the *               io_offset element of pci_controller struct should be set *               to zero. *  ELEMENTS: *    name       - String used for a meaningful name. * *    start      - Start address of MSP7120's I/O space, as MSP7120 presents *                 the address on the PCI bus. * *    end        - End address of MSP7120's I/O space, as MSP7120 presents *                 the address on the PCI bus. * *    flags      - Attributes indicating the type of resource. In this case, *                 indicate I/O space. * ****************************************************************************/static struct resource pci_io_resource = {	.name	= "pci IO space",	.start	= 0x04,	.end	= 0x0FFF,	.flags	= IORESOURCE_IO	/* I/O space */};/***************************************************************************** * *  STRUCT: pci_mem_resource *  _________________________________________________________________________ * *  DESCRIPTION: Defines the address range that pciauto() will use to *               assign to the memory BARs of PCI devices. * *               The .start and .end values are dependent upon how address *               translation is performed by the OATRAN regiser. * *               The values to use for .start and .end are the values *               in the form they appear on the PCI bus AFTER MSP7120 has *               performed OATRAN address translation. * *  ELEMENTS: *    name       - String used for a meaningful name. * *    start      - Start address of MSP7120's memory space, as MSP7120 presents *                 the address on the PCI bus. * *    end        - End address of MSP7120's memory space, as MSP7120 presents *                 the address on the PCI bus. * *    flags      - Attributes indicating the type of resource. In this case, *                 indicate memory space. * ****************************************************************************/static struct resource pci_mem_resource = {	.name	= "pci memory space",	.start	= MSP_PCI_SPACE_BASE,	.end	= MSP_PCI_SPACE_END,	.flags	= IORESOURCE_MEM	 /* memory space */};/***************************************************************************** * *  FUNCTION: bpci_interrupt *  _________________________________________________________________________ * *  DESCRIPTION: PCI status interrupt handler. Updates the count of how *               many times each status bit has been set, then clears *               the status bits. If the appropriate macros are defined, *               these counts can be viewed via the /proc filesystem. * *  INPUTS:      irq     - unused *               dev_id  - unused *               pt_regs - unused * *  OUTPUTS:     none * *  RETURNS:     PCIBIOS_SUCCESSFUL  - success * ****************************************************************************/static int bpci_interrupt(int irq, void *dev_id){	struct msp_pci_regs *preg = (void *)PCI_BASE_REG;	unsigned int stat = preg->if_status;#if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)	int i;	for (i = 0; i < 32; ++i) {		if ((1 << i) & stat)			++pci_int_count[i];	}#endif /* PROC_FS && PCI_COUNTERS */	/* printk("PCI ISR: Status=%08X\n", stat); */	/* write to clear all asserted interrupts */	preg->if_status = stat;	return PCIBIOS_SUCCESSFUL;}/*****************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -