This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
devm_ioremap_resource [2018/07/31 10:29] rpjday [Let's talk about resources] |
devm_ioremap_resource [2018/07/31 11:59] rpjday [platform_get_resource()] |
||
---|---|---|---|
Line 1: | Line 1: | ||
===== Overview ===== | ===== Overview ===== | ||
- | Explain ''devm_ioremap_resource()'', with examples. Add some links. | + | Explain ''devm_ioremap_resource()'', with examples particularly related to memory regions. Add some links. |
- | ===== What's a "resource"? ===== | + | ===== struct resource ===== |
- | + | ||
- | ==== struct resource ==== | + | |
From ''include/linux/ioport.h'', a device can have a number of resources of different types: | From ''include/linux/ioport.h'', a device can have a number of resources of different types: | ||
Line 24: | Line 22: | ||
</code> | </code> | ||
- | + | In particular, one resource type is a memory range (''flags'' of ''IORESOURCE_MEM''): | |
- | A small sample of resource types from that same file (''IORESOURCE_MEM'' is the one representing physical memory that many drivers are interested in): | + | |
<code> | <code> | ||
Line 40: | Line 37: | ||
</code> | </code> | ||
+ | Here's a single example from ''arch/arm/mach-davinci/dm355.c'', defining an array of resources: | ||
+ | |||
+ | <code> | ||
+ | static struct resource edma_resources[] = { | ||
+ | { | ||
+ | .name = "edma3_cc", | ||
+ | .start = 0x01c00000, | ||
+ | .end = 0x01c00000 + SZ_64K - 1, | ||
+ | .flags = IORESOURCE_MEM, | ||
+ | }, | ||
+ | { | ||
+ | .name = "edma3_tc0", | ||
+ | .start = 0x01c10000, | ||
+ | .end = 0x01c10000 + SZ_1K - 1, | ||
+ | .flags = IORESOURCE_MEM, | ||
+ | }, | ||
+ | { | ||
+ | .name = "edma3_tc1", | ||
+ | .start = 0x01c10400, | ||
+ | .end = 0x01c10400 + SZ_1K - 1, | ||
+ | .flags = IORESOURCE_MEM, | ||
+ | }, | ||
+ | ... snip ... | ||
+ | </code> | ||
===== struct platform_device ===== | ===== struct platform_device ===== | ||
- | From ''include/linux/platform_device.h'': | + | From ''include/linux/platform_device.h'', showing how a ''platform_device'' can represent any number of resources: |
<code> | <code> | ||
Line 72: | Line 93: | ||
===== platform_get_resource() ===== | ===== platform_get_resource() ===== | ||
- | From ''drivers/base/platform.c'', given a platform device and a resource type, return that resource type or ''NULL'': | + | From ''drivers/base/platform.c'', given a ''struct platform_device *dev'' and a resource type, return that (numbered) resource type or ''NULL'': |
<code> | <code> | ||
Line 95: | Line 116: | ||
return NULL; | return NULL; | ||
} | } | ||
+ | </code> | ||
+ | |||
+ | You can also get a resource by an optional name: | ||
+ | |||
+ | <code> | ||
+ | /** | ||
+ | * platform_get_resource_byname - get a resource for a device by name | ||
+ | * @dev: platform device | ||
+ | * @type: resource type | ||
+ | * @name: resource name | ||
+ | */ | ||
+ | struct resource *platform_get_resource_byname(struct platform_device *dev, | ||
+ | unsigned int type, | ||
+ | const char *name) | ||
+ | { | ||
+ | int i; | ||
+ | |||
+ | for (i = 0; i < dev->num_resources; i++) { | ||
+ | struct resource *r = &dev->resource[i]; | ||
+ | |||
+ | if (unlikely(!r->name)) | ||
+ | continue; | ||
+ | |||
+ | if (type == resource_type(r) && !strcmp(r->name, name)) | ||
+ | return r; | ||
+ | } | ||
</code> | </code> | ||