/* * Hisilicon Hi6220 ION Driver * * Copyright (c) 2015 Hisilicon Limited. * * Author: Chen Feng * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ #define pr_fmt(fmt) "Ion: " fmt #include #include #include #include #include #include "../ion_priv.h" #include "../ion.h" #include "../ion_of.h" struct hisi_ion_dev { struct ion_heap **heaps; struct ion_device *idev; struct ion_platform_data *data; }; static struct ion_of_heap hisi_heaps[] = { PLATFORM_HEAP("hisilicon,sys_user", 0, ION_HEAP_TYPE_SYSTEM, "sys_user"), PLATFORM_HEAP("hisilicon,sys_contig", 1, ION_HEAP_TYPE_SYSTEM_CONTIG, "sys_contig"), PLATFORM_HEAP("hisilicon,cma", ION_HEAP_TYPE_DMA, ION_HEAP_TYPE_DMA, "cma"), {} }; static int hi6220_ion_probe(struct platform_device *pdev) { struct hisi_ion_dev *ipdev; int i; ipdev = devm_kzalloc(&pdev->dev, sizeof(*ipdev), GFP_KERNEL); if (!ipdev) return -ENOMEM; platform_set_drvdata(pdev, ipdev); ipdev->idev = ion_device_create(NULL); if (IS_ERR(ipdev->idev)) return PTR_ERR(ipdev->idev); ipdev->data = ion_parse_dt(pdev, hisi_heaps); if (IS_ERR(ipdev->data)) return PTR_ERR(ipdev->data); ipdev->heaps = devm_kzalloc(&pdev->dev, sizeof(struct ion_heap) * ipdev->data->nr, GFP_KERNEL); if (!ipdev->heaps) { ion_destroy_platform_data(ipdev->data); return -ENOMEM; } for (i = 0; i < ipdev->data->nr; i++) { ipdev->heaps[i] = ion_heap_create(&ipdev->data->heaps[i]); if (!ipdev->heaps) { ion_destroy_platform_data(ipdev->data); return -ENOMEM; } ion_device_add_heap(ipdev->idev, ipdev->heaps[i]); } return 0; } static int hi6220_ion_remove(struct platform_device *pdev) { struct hisi_ion_dev *ipdev; int i; ipdev = platform_get_drvdata(pdev); for (i = 0; i < ipdev->data->nr; i++) ion_heap_destroy(ipdev->heaps[i]); ion_destroy_platform_data(ipdev->data); ion_device_destroy(ipdev->idev); return 0; } static const struct of_device_id hi6220_ion_match_table[] = { {.compatible = "hisilicon,hi6220-ion"}, {}, }; static struct platform_driver hi6220_ion_driver = { .probe = hi6220_ion_probe, .remove = hi6220_ion_remove, .driver = { .name = "ion-hi6220", .of_match_table = hi6220_ion_match_table, }, }; static int __init hi6220_ion_init(void) { return platform_driver_register(&hi6220_ion_driver); } subsys_initcall(hi6220_ion_init);