22. 5.21: Platform Driver Resources
В этом разделе мы изучаем, как платформа устройства (Platform Device) описывает аппаратные ресурсы, такие как регистры памяти и прерывания, и как драйвер получает к ним доступ.
22.1. struct platform_device
В ядре Linux структура platform_device представляет собой устройство, не использующее шину с автообнаружением (например, I2C, PCI), и описывает его ресурсы:
struct platform_device {
const char *name;
int id;
struct device dev;
u32 num_resources;
struct resource *resource;
...
};
Платформенные ресурсы задаются через структуру struct resource.
22.2. struct resource
Структура описания ресурсов (например, адресов MMIO или IRQ):
struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
struct resource *parent, *sibling, *child;
};
22.3. Пояснение полей resource
startиend— начальный и конечный физические адреса или номер IRQname— удобная строка-идентификатор (например, «mmio», «irq»)flags— указывает тип ресурса: - IORESOURCE_MEM — область памяти (MMIO) - IORESOURCE_IRQ — номер прерывания (IRQ) - и др.
22.4. Функции доступа к ресурсам
platform_get_resource()
struct resource *platform_get_resource(struct platform_device *pdev,
unsigned int type, unsigned int num);
Получает ресурс типа IORESOURCE_MEM или IORESOURCE_IRQ с заданным индексом num.
Пример:
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res)
base = ioremap(res->start, resource_size(res));
platform_get_irq()
int platform_get_irq(struct platform_device *pdev, unsigned int num);
Получает номер IRQ из ресурсов.
Пример:
int irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
22.5. Пример использования
static int my_probe(struct platform_device *pdev) {
struct resource *res;
void __iomem *base;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
int irq = platform_get_irq(pdev, 0);
return 0;
}
22.6. Заключение
Использование структуры ресурсов и платформенных функций platform_get_resource() и platform_get_irq() позволяет драйверу быть максимально абстрагированным от конкретной архитектуры и сосредоточиться на логике управления устройством.