linux串口驱动ioremap,linux pci driver中的ioremap

xapp1022里:

static int XPCIe_init(void)

{

gDev = pci_find_device (PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_XILINX_PCIE, gDev);

if (NULL == gDev) {

printk(/*KERN_WARNING*/"%s: Init: Hardware not found.\n", gDrvrName);

//return (CRIT_ERR);

return (-1);

}

if (0 > pci_enable_device(gDev)) {

printk(/*KERN_WARNING*/"%s: Init: Device not enabled.\n", gDrvrName);

//return (CRIT_ERR);

return (-1);

}

// Get Base Address of registers from pci structure. Should come from pci_dev

// structure, but that element seems to be missing on the development system.

gBaseHdwr = pci_resource_start (gDev, 0);

if (0 > gBaseHdwr) {

printk(/*KERN_WARNING*/"%s: Init: Base Address not set.\n", gDrvrName);

//return (CRIT_ERR);

return (-1);

}

printk(/*KERN_WARNING*/"Base hw val %X\n", (unsigned int)gBaseHdwr);

gBaseLen = pci_resource_len (gDev, 0);

printk(/*KERN_WARNING*/"Base hw len %d\n", (unsigned int)gBaseLen);

// Remap the I/O register block so that it can be safely accessed.

// I/O register block starts at gBaseHdwr and is 32 bytes long.

// It is cast to char because that is the way Linus does it.

// Reference "/usr/src/Linux-2.4/Documentation/IO-mapping.txt".

gBaseVirt = ioremap(gBaseHdwr, gBaseLen);

if (!gBaseVirt) {

printk(/*KERN_WARNING*/"%s: Init: Could not remap memory.\n", gDrvrName);

//return (CRIT_ERR);

return (-1);

}

printk(/*KERN_WARNING*/"Virt hw val %X\n", (unsigned int)gBaseVirt);

// Get IRQ from pci_dev structure. It may have been remapped by the kernel,

// and this value will be the correct one.

gIrq = gDev->irq;

printk("irq: %d\n",gIrq);

//--- START: Initialize Hardware

// Try to gain exclusive control of memory for demo hardware.

if (0 > check_mem_region(gBaseHdwr, KINBURN_REGISTER_SIZE)) {

printk(/*KERN_WARNING*/"%s: Init: Memory in use.\n", gDrvrName);

//return (CRIT_ERR);

return (-1);

}

request_mem_region(gBaseHdwr, KINBURN_REGISTER_SIZE, "3GIO_Demo_Drv");

gStatFlags = gStatFlags | HAVE_REGION;

printk(/*KERN_WARNING*/"%s: Init: Initialize Hardware Done..\n",gDrvrName);

// Request IRQ from OS.

#if 0

if (0 > request_irq(gIrq, &XPCIe_IRQHandler,/* SA_INTERRUPT |*/ SA_SHIRQ, gDrvrName, gDev)) {

printk(/*KERN_WARNING*/"%s: Init: Unable to allocate IRQ",gDrvrName);

return (-1);

}

gStatFlags = gStatFlags | HAVE_IRQ;

#endif

initcode();

//--- END: Initialize Hardware

//--- START: Allocate Buffers

gBufferUnaligned = kmalloc(BUF_SIZE, GFP_KERNEL);

gReadBuffer = gBufferUnaligned;

if (NULL == gBufferUnaligned) {

printk(KERN_CRIT"%s: Init: Unable to allocate gBuffer.\n",gDrvrName);

return (-1);

}

gWriteBuffer = kmalloc(BUF_SIZE, GFP_KERNEL);

if (NULL == gWriteBuffer) {

printk(KERN_CRIT"%s: Init: Unable to allocate gBuffer.\n",gDrvrName);

return (-1);

}

//--- END: Allocate Buffers

//--- START: Register Driver

// Register with the kernel as a character device.

// Abort if it fails.

if (0 > register_chrdev(gDrvrMajor, gDrvrName, &XPCIe_Intf)) {

printk(KERN_WARNING"%s: Init: will not register\n", gDrvrName);

return (CRIT_ERR);

}

printk(KERN_INFO"%s: Init: module registered\n", gDrvrName);

gStatFlags = gStatFlags | HAVE_KREG;

printk("%s driver is loaded\n", gDrvrName);

return 0;

}

gBaseHdwr = pci_resource_start (gDev, 0)从resource结构获得BAR0空间的基地址,该地址 为存储器域的物理地址,不是PCI总线域的物理地址(pci_read_config_word()函数获取)。

ioremap()函数将存储器域的物理地址映射成为Linux系统中的虚拟地址,然后可以用gBaseVirt全局指针访问板卡中存储器映射的寄存器。

比如:

u32 XPCIe_ReadReg (u32 dw_offset)

{

u32 ret = 0;

u32 reg_addr = (u32)(gBaseVirt + dw_offset);

ret = readb((void*)reg_addr);

return ret;

}

void XPCIe_WriteReg (u32 dw_offset, u32 val)

{

u32 reg_addr = (u32)(gBaseVirt + dw_offset);

writeb(val, (void*)reg_addr);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值