从熟悉的开始。
设备驱动模型。 device device driver class bus
dra7xx pcie驱动 bus:platform bus device:platform_device device driver: platform_driver struct platform_driver { int (*probe)(struct platform_device *); int (*remove)(struct platform_device *); void (*shutdown)(struct platform_device *); int (*suspend)(struct platform_device *, pm_message_t state); int (*resume)(struct platform_device *); struct device_driver driver; const struct platform_device_id *id_table; bool prevent_deferred_probe; };
static struct platform_driver dra7xx_pcie_driver = { .driver = { .name = “dra7-pcie”, .of_match_table = of_dra7xx_pcie_match, .suppress_bind_attrs = true, .pm = &dra7xx_pcie_pm_ops, }, .shutdown = dra7xx_pcie_shutdown, };
/* device_driver */ struct device_driver { const char *name; struct bus_type *bus;
struct module *owner; const char *mod_name; /* used for built-in modules */ bool suppress_bind_attrs; /* disables bind/unbind via sysfs */ enum probe_type probe_type; const struct of_device_id *of_match_table; const struct acpi_device_id *acpi_match_table; int (*probe) (struct device *dev); int (*remove) (struct device *dev); void (*shutdown) (struct device *dev); int (*suspend) (struct device *dev, pm_message_t state); int (*resume) (struct device *dev); const struct attribute_group **groups; const struct dev_pm_ops *pm; void (*coredump) (struct device *dev); struct driver_private *p;};
__platform_driver_register(drv, module); int __platform_driver_register(struct platform_driver *drv, struct module *owner) { drv->driver.owner = owner; drv->driver.bus = &platform_bus_type; drv->driver.probe = platform_drv_probe; drv->driver.remove = platform_drv_remove; drv->driver.shutdown = platform_drv_shutdown;
return driver_register(&drv->driver); }
struct platform_device { const char *name; int id; bool id_auto; struct device dev; u32 num_resources; struct resource *resource;
const struct platform_device_id *id_entry; char *driver_override; /* Driver name to force a match */ /* MFD cell pointer */ struct mfd_cell *mfd_cell; /* arch specific additions */ struct pdev_archdata archdata;}; platform_device 比struct device 多了,以下结构 struct resource { resource_size_t start; resource_size_t end; const char *name; unsigned long flags; unsigned long desc; struct resource *parent, *sibling, *child; };
/* arch specific additions */ struct pdev_archdata archdata;
Documentation\driver-model\platform.txt
Platform Devices and Drivers
This pseudo-bus is used to connect devices on busses with minimal infrastructure like those used to integrate peripherals on many system-on-chip processors, or some “legacy” PC interconnects; as opposed to large formally specified ones like PCI or USB.
static void dra7xx_pcie_raise_legacy_irq(struct dra7xx_pcie *dra7xx) { dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_INTX_ASSERT, 0x1); mdelay(1); dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_INTX_DEASSERT, 0x1); }
static void dra7xx_pcie_raise_msi_irq(struct dra7xx_pcie *dra7xx, u8 interrupt_num) { u32 reg;
reg = (interrupt_num - 1) << MSI_VECTOR_SHIFT; reg |= MSI_REQ_GRANT; dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_MSI_XMT, reg);}