3.0.35 platformデバイスリソースとデータ
14308 ワード
構造体platform_デバイスの定義(include/linux/platform_device.h)では、次のようになります.
platform_について説明しますDeviceのリソース、リソース自体は構造体resourceによって記述され、その定義(include/linux/ioport.h)は以下のように示されています.
通常、start、end、flagsの3つのフィールドに関心を持ち、リソースの開始値、終了値、タイプを表します.
タイプフィールドもioport.hに定義があり、IORESOURCEをサポートするIO, IORESOURCE_MEM, IORESOURCE_IRQ, IORESOURCE_DMAなど.
start,endの意味はflagsによって変更され、例えばflagsがIORESOURCE_である場合MEMの場合、start,endはそれぞれそのplatform_を表すデバイスが占めるメモリの
開始アドレスと終了アドレス;flagsがIORESOURCEである場合IRQの場合、start,endはそれぞれそのplatform_を表すデバイスが使用する割り込み番号の開始値と終了値.
resourceの定義は通常BSPのボードファイルで行われ、platform_を介して行われます.device_add_resources()は、リソースファイルをステージデバイスに登録し、具体的な設定
予備駆動でplatform_を通過get_resource()を使用して、次のように定義します.
例えばMY.IMx 6開発ボードのボードファイルには、ECSPI(arch/arm/plat-mxc/devices/platform-spi_imx.c)として次のresourceが定義されています.
imx_経由add_platform_device()はリソースファイルを追加し、その定義(arch/arm/plat-mxc/include/mach/devices-common.h)は以下の通りです.
imx_add_platform_device_dmamask()の定義(arch/arm/plat-mxc/devices.c)は以下の通りです.
最終的にplatform_が呼び出されましたdevice_add_resources()の定義(drivers/base/platform.c)は次のとおりです.
IMx 6のSPIドライバでは、次の2つのリソースが得られる.
具体的にはdrivers/spi/spi_imx.cのspi_imx_probe()メソッドで
platform_get_IRqの定義は以下の通りである.
デバイスは、BSPでリソースファイルを定義することができるほか、デバイスのハードウェア記述に割り込み、メモリ、DMAのほかに、いくつかのデータ情報を付加することができる.
いくつかの構成情報は、プレートにも依存し、ドライバ自体に直接配置するのは適切ではありません.そのため、platformはplatform_を提供します.dataのサポート.
デバイスドライバにplatformを導入する概念には、少なくとも次の2つの利点があります.
1)設備を一つのバスに接続させ、管理する
2)BSPと駆動を分離した.BSPではplatformデバイスとデバイスが使用するリソース、デバイスの具体的な情報を定義しますが、ドライバでは汎用APIで取得するだけです.
リソースとデータは、ボード関連コードと駆動コードの分離を実現し、より良い拡張性とプラットフォーム間で駆動する必要があります.
struct platform_device {
const char * name;
int id;
struct device dev;
u32 num_resources;
struct resource * resource;
const struct platform_device_id *id_entry;
/* MFD cell pointer */
struct mfd_cell *mfd_cell;
/* arch specific additions */
struct pdev_archdata archdata;
};
platform_について説明しますDeviceのリソース、リソース自体は構造体resourceによって記述され、その定義(include/linux/ioport.h)は以下のように示されています.
/*
* Resources are tree-like, allowing
* nesting etc..
*/
struct resource {
resource_size_t start;
resource_size_t end;
const char *name;
unsigned long flags;
struct resource *parent, *sibling, *child;
};
通常、start、end、flagsの3つのフィールドに関心を持ち、リソースの開始値、終了値、タイプを表します.
タイプフィールドもioport.hに定義があり、IORESOURCEをサポートするIO, IORESOURCE_MEM, IORESOURCE_IRQ, IORESOURCE_DMAなど.
start,endの意味はflagsによって変更され、例えばflagsがIORESOURCE_である場合MEMの場合、start,endはそれぞれそのplatform_を表すデバイスが占めるメモリの
開始アドレスと終了アドレス;flagsがIORESOURCEである場合IRQの場合、start,endはそれぞれそのplatform_を表すデバイスが使用する割り込み番号の開始値と終了値.
resourceの定義は通常BSPのボードファイルで行われ、platform_を介して行われます.device_add_resources()は、リソースファイルをステージデバイスに登録し、具体的な設定
予備駆動でplatform_を通過get_resource()を使用して、次のように定義します.
/**
* platform_get_resource - get a resource for a device
* @dev: platform device
* @type: resource type
* @num: resource index
*/
struct resource *platform_get_resource(struct platform_device *dev,
unsigned int type, unsigned int num)
{
int i;
for (i = 0; i < dev->num_resources; i++) {
struct resource *r = &dev->resource[i];
if (type == resource_type(r) && num-- == 0)
return r;
}
return NULL;
}
EXPORT_SYMBOL_GPL(platform_get_resource);
例えばMY.IMx 6開発ボードのボードファイルには、ECSPI(arch/arm/plat-mxc/devices/platform-spi_imx.c)として次のresourceが定義されています.
struct platform_device *__init imx_add_spi_imx(
const struct imx_spi_imx_data *data,
const struct spi_imx_master *pdata)
{
struct resource res[] = {
{
.start = data->iobase,
.end = data->iobase + data->iosize - 1,
.flags = IORESOURCE_MEM,
}, {
.start = data->irq,
.end = data->irq,
.flags = IORESOURCE_IRQ,
},
};
return imx_add_platform_device(data->devid, data->id,
res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
}
imx_経由add_platform_device()はリソースファイルを追加し、その定義(arch/arm/plat-mxc/include/mach/devices-common.h)は以下の通りです.
static inline struct platform_device *imx_add_platform_device(
const char *name, int id,
const struct resource *res, unsigned int num_resources,
const void *data, size_t size_data)
{
return imx_add_platform_device_dmamask(
name, id, res, num_resources, data, size_data, 0);
}
imx_add_platform_device_dmamask()の定義(arch/arm/plat-mxc/devices.c)は以下の通りです.
struct platform_device *__init imx_add_platform_device_dmamask(
const char *name, int id,
const struct resource *res, unsigned int num_resources,
const void *data, size_t size_data, u64 dmamask)
{
int ret = -ENOMEM;
struct platform_device *pdev;
pdev = platform_device_alloc(name, id);
if (!pdev)
goto err;
if (dmamask) {
/*
* This memory isn't freed when the device is put,
* I don't have a nice idea for that though. Conceptually
* dma_mask in struct device should not be a pointer.
* See http://thread.gmane.org/gmane.linux.kernel.pci/9081
*/
pdev->dev.dma_mask =
kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
if (!pdev->dev.dma_mask)
/* ret is still -ENOMEM; */
goto err;
*pdev->dev.dma_mask = dmamask;
pdev->dev.coherent_dma_mask = dmamask;
}
if (res) {
ret = platform_device_add_resources(pdev, res, num_resources);
if (ret)
goto err;
}
if (data) {
ret = platform_device_add_data(pdev, data, size_data);
if (ret)
goto err;
}
ret = platform_device_add(pdev);
if (ret) {
err:
if (dmamask)
kfree(pdev->dev.dma_mask);
platform_device_put(pdev);
return ERR_PTR(ret);
}
return pdev;
}
最終的にplatform_が呼び出されましたdevice_add_resources()の定義(drivers/base/platform.c)は次のとおりです.
/**
* platform_device_add_resources - add resources to a platform device
* @pdev: platform device allocated by platform_device_alloc to add resources to
* @res: set of resources that needs to be allocated for the device
* @num: number of resources
*
* Add a copy of the resources to the platform device. The memory
* associated with the resources will be freed when the platform device is
* released.
*/
int platform_device_add_resources(struct platform_device *pdev,
const struct resource *res, unsigned int num)
{
struct resource *r = NULL;
if (res) {
r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
if (!r)
return -ENOMEM;
}
kfree(pdev->resource);
pdev->resource = r;
pdev->num_resources = num;
return 0;
}
EXPORT_SYMBOL_GPL(platform_device_add_resources);
IMx 6のSPIドライバでは、次の2つのリソースが得られる.
具体的にはdrivers/spi/spi_imx.cのspi_imx_probe()メソッドで
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
spi_imx->irq = platform_get_irq(pdev, 0);
platform_get_IRqの定義は以下の通りである.
/**
* platform_get_irq - get an IRQ for a device
* @dev: platform device
* @num: IRQ number index
*/
int platform_get_irq(struct platform_device *dev, unsigned int num)
{
struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
return r ? r->start : -ENXIO;
}
EXPORT_SYMBOL_GPL(platform_get_irq);
デバイスは、BSPでリソースファイルを定義することができるほか、デバイスのハードウェア記述に割り込み、メモリ、DMAのほかに、いくつかのデータ情報を付加することができる.
いくつかの構成情報は、プレートにも依存し、ドライバ自体に直接配置するのは適切ではありません.そのため、platformはplatform_を提供します.dataのサポート.
デバイスドライバにplatformを導入する概念には、少なくとも次の2つの利点があります.
1)設備を一つのバスに接続させ、管理する
2)BSPと駆動を分離した.BSPではplatformデバイスとデバイスが使用するリソース、デバイスの具体的な情報を定義しますが、ドライバでは汎用APIで取得するだけです.
リソースとデータは、ボード関連コードと駆動コードの分離を実現し、より良い拡張性とプラットフォーム間で駆動する必要があります.