# Runtime PM: 장치를 쓰는 동안 잠들지 않게 하는 방법

v6.6 / drivers/base/power/runtime.c

시스템 전체가 켜져 있어도 사용하지 않는 장치는 전력을 줄이려고 정지할 수 있습니다. Runtime PM은 장치별 사용량과 상태를 관리하면서 필요한 때 드라이버의 재개 동작을 실행합니다. __pm_runtime_resume 전체는 사용 계수를 선택적으로 올리고 상태 잠금을 잡아 내부 재개 절차에 넘기는 입구입니다. 실제 하드웨어 전원 복구는 rpm_resume과 장치별 콜백에서 이어집니다.

## __pm_runtime_resume

```c

int __pm_runtime_resume(struct device *dev, int rpmflags)
{
	unsigned long flags;
	int retval;

	might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe &&
			dev->power.runtime_status != RPM_ACTIVE);

	if (rpmflags & RPM_GET_PUT)
		atomic_inc(&dev->power.usage_count);

	spin_lock_irqsave(&dev->power.lock, flags);
	retval = rpm_resume(dev, rpmflags);
	spin_unlock_irqrestore(&dev->power.lock, flags);

	return retval;
}

```

### 1158행

```c

int __pm_runtime_resume(struct device *dev, int rpmflags)

```

재개할 장치와 동기·비동기, 사용 계수 변경 여부 등의 rpmflags를 받습니다.

### 1160행

```c

	unsigned long flags;

```

잠금 전 인터럽트 상태를 저장할 변수입니다.

### 1161행

```c

	int retval;

```

내부 재개 함수의 결과를 보관합니다.

### 1163행

```c

	might_sleep_if(!(rpmflags & RPM_ASYNC) && !dev->power.irq_safe &&

```

비동기가 아니며 IRQ 안전 장치도 아닌 경우 잠들 수 있는 호출인지 검사할 조건을 구성합니다.

### 1164행

```c

			dev->power.runtime_status != RPM_ACTIVE);

```

이미 ACTIVE가 아닌 경우에만 might_sleep_if 진단을 적용합니다. 이 매크로 자체가 장치를 재개하거나 일부러 잠드는 것은 아닙니다.

### 1166행

```c

	if (rpmflags & RPM_GET_PUT)

```

이번 API가 사용 계수도 함께 증가시키도록 요구했는지 확인합니다.

### 1167행

```c

		atomic_inc(&dev->power.usage_count);

```

동시 사용자와 충돌하지 않도록 usage_count를 원자적으로 증가시킵니다.

### 1169행

```c

	spin_lock_irqsave(&dev->power.lock, flags);

```

인터럽트 상태를 보존하고 장치 전원관리 상태를 보호하는 스핀락을 잡습니다.

### 1170행

```c

	retval = rpm_resume(dev, rpmflags);

```

내부 상태 기계에 장치와 플래그를 넘겨 실제 재개 처리 또는 예약을 수행합니다.

### 1171행

```c

	spin_unlock_irqrestore(&dev->power.lock, flags);

```

상태 잠금을 풀고 진입 전 인터럽트 상태로 돌립니다.

### 1173행

```c

	return retval;

```

재개 처리 결과를 반환합니다. 사용 계수 증가를 이 함수 안에서 자동 취소하지 않는다는 점을 확인하십시오.

