[C] request_mem_region ()은 실제로 무엇을 필요로 하는가?


Answers

request_mem_region 은 드라이버가이 범위의 I / O 주소를 사용한다는 것을 커널에 알려 request_mem_region 다른 드라이버가 request_mem_region 통해 동일한 영역에 대한 중첩 호출을하지 못하게합니다. 이 메커니즘은 어떤 종류의 매핑도하지 않으며 순수한 예약 메커니즘입니다. 모든 커널 장치 드라이버가 훌륭해야하며 request_mem_region 호출하고 반환 값을 확인하고 오류가 발생하면 올바르게 동작해야합니다.

따라서 코드가 request_mem_region 없이 작동한다는 것은 완전히 논리적입니다. 단지 커널 코딩 규칙을 준수하지 않는다는 것입니다.

그러나 코드가 커널 코딩 스타일을 따르지 않습니다. 또한 GPIO 뱅크 레지스터를 수동으로 다시 매핑하는 대신 gpiolib이라는 GPIO를 처리 할 수있는 기존 인프라가 있습니다. 어떤 플랫폼에서 작업하고 있습니까?

Question

저는 임베디드 리눅스 드라이버 작성에 대해 공부하고 있으며, GPIO를 약간 발사하여 책 (LDD3, chap9.4.1)을 올바르게 이해하고 있습니다.

올바른 GPIO 핀을 의도대로 제어 할 수 있습니다 (높고 낮게, 멀티 미터로 프로빙했습니다). 그러나, 나는 2 개의 코드를 테스트했다. 하나는 request_mem_region() 이고 다른 하나는 테스트하지 request_mem_region() . 나는없이 하나를 기대하고 있지만, 둘 다 잘 작동합니다.

request_mem_region 사용한 코드 :

if( request_mem_region( PIN3_CONF_PHYS, MAPPED_SIZE_GPIO_CONF,DEVICE_NAME ) == NULL )
  {
    printk( KERN_ALERT
            "GPIO_140_141_conf_phys error:%s: unable to obtain I/O memory address 0x%08llX\n",
            DEVICE_NAME, PIN3_CONF_PHYS );

    return -EBUSY;
  }

pin3_conf = (u32)ioremap( PIN3_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin4_conf = (u32)ioremap( PIN4_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin5_conf = (u32)ioremap( PIN5_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin6_conf = (u32)ioremap( PIN6_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
//-----------------------------------------------------------------
if( request_mem_region( GPIO_BANK5_PHYS, MAPPED_SIZE_GPIO_5,DEVICE_NAME ) == NULL )
  {
    printk( KERN_ALERT
            "error:%s: unable to obtain I/O memory address 0x%08llX\n",
            DEVICE_NAME, GPIO_BANK5_PHYS );

    return -EBUSY;
  }

gpio_virt = (u32)ioremap( GPIO_BANK5_PHYS, MAPPED_SIZE_GPIO_5 );

//some iowrite32() functions continue...

request_mem_region() 없는 코드 :

pin3_conf = (u32)ioremap( PIN3_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin4_conf = (u32)ioremap( PIN4_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin5_conf = (u32)ioremap( PIN5_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
pin6_conf = (u32)ioremap( PIN6_CONF_PHYS, MAPPED_SIZE_GPIO_CONF);
gpio_virt = (u32)ioremap( GPIO_BANK5_PHYS, MAPPED_SIZE_GPIO_5 );
//some iowrite32() functions continue...

두 경우 모두에서 관찰 할 수있는 유일한 차이점은 cat /proc/iomem 을 수행 한 결과이며 request_mem_region() 이있는 것은 49056000-49056097 : GPIO3 나타내는 추가 행을 표시합니다.

내 질문은 왜 ioremap() 만 사용하여 하드웨어 주소와 통신 할 수 있기 때문에 request_mem_region() 이 필요한 이유입니까? 그러면 언제 실제로 request_mem_region() 을 사용해야합니까?

어떤 답장을 보내 주셔서 감사합니다!