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 — начальный и конечный физические адреса или номер IRQ

  • name — удобная строка-идентификатор (например, «mmio», «irq»)

  • flags — указывает тип ресурса: - IORESOURCE_MEM — область памяти (MMIO) - IORESOURCE_IRQ — номер прерывания (IRQ) - и др.

22.4. Функции доступа к ресурсам

  1. 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));
  1. 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() позволяет драйверу быть максимально абстрагированным от конкретной архитектуры и сосредоточиться на логике управления устройством.