Commit | Line | Data |
---|---|---|
2b40182a CF |
1 | /* |
2 | * Hisilicon Hi6220 ION Driver | |
3 | * | |
4 | * Copyright (c) 2015 Hisilicon Limited. | |
5 | * | |
6 | * Author: Chen Feng <puck.chen@hisilicon.com> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License version 2 as | |
10 | * published by the Free Software Foundation. | |
11 | */ | |
12 | ||
13 | #define pr_fmt(fmt) "Ion: " fmt | |
14 | ||
15 | #include <linux/err.h> | |
16 | #include <linux/platform_device.h> | |
17 | #include <linux/slab.h> | |
18 | #include <linux/of.h> | |
19 | #include <linux/mm.h> | |
20 | #include "../ion_priv.h" | |
21 | #include "../ion.h" | |
b6e336db | 22 | #include "../ion_of.h" |
2b40182a | 23 | |
b6e336db LA |
24 | struct hisi_ion_dev { |
25 | struct ion_heap **heaps; | |
26 | struct ion_device *idev; | |
27 | struct ion_platform_data *data; | |
2b40182a CF |
28 | }; |
29 | ||
b6e336db LA |
30 | static struct ion_of_heap hisi_heaps[] = { |
31 | PLATFORM_HEAP("hisilicon,sys_user", 0, | |
32 | ION_HEAP_TYPE_SYSTEM, "sys_user"), | |
33 | PLATFORM_HEAP("hisilicon,sys_contig", 1, | |
34 | ION_HEAP_TYPE_SYSTEM_CONTIG, "sys_contig"), | |
35 | PLATFORM_HEAP("hisilicon,cma", ION_HEAP_TYPE_DMA, ION_HEAP_TYPE_DMA, | |
36 | "cma"), | |
37 | {} | |
2b40182a CF |
38 | }; |
39 | ||
b6e336db | 40 | static int hi6220_ion_probe(struct platform_device *pdev) |
2b40182a | 41 | { |
b6e336db | 42 | struct hisi_ion_dev *ipdev; |
2b40182a CF |
43 | int i; |
44 | ||
b6e336db LA |
45 | ipdev = devm_kzalloc(&pdev->dev, sizeof(*ipdev), GFP_KERNEL); |
46 | if (!ipdev) | |
2b40182a CF |
47 | return -ENOMEM; |
48 | ||
b6e336db | 49 | platform_set_drvdata(pdev, ipdev); |
2b40182a | 50 | |
b6e336db LA |
51 | ipdev->idev = ion_device_create(NULL); |
52 | if (!ipdev->idev) | |
53 | return -ENOMEM; | |
2b40182a | 54 | |
b6e336db LA |
55 | ipdev->data = ion_parse_dt(pdev, hisi_heaps); |
56 | if (IS_ERR(ipdev->data)) | |
57 | return PTR_ERR(ipdev->data); | |
2b40182a | 58 | |
b6e336db LA |
59 | ipdev->heaps = devm_kzalloc(&pdev->dev, |
60 | sizeof(struct ion_heap)*ipdev->data->nr, | |
61 | GFP_KERNEL); | |
62 | if (!ipdev->heaps) { | |
63 | ion_destroy_platform_data(ipdev->data); | |
64 | return -ENOMEM; | |
2b40182a CF |
65 | } |
66 | ||
b6e336db LA |
67 | for (i = 0; i < ipdev->data->nr; i++) { |
68 | ipdev->heaps[i] = ion_heap_create(&ipdev->data->heaps[i]); | |
69 | if (!ipdev->heaps) { | |
70 | ion_destroy_platform_data(ipdev->data); | |
71 | return -ENOMEM; | |
2b40182a | 72 | } |
b6e336db | 73 | ion_device_add_heap(ipdev->idev, ipdev->heaps[i]); |
2b40182a | 74 | } |
b6e336db | 75 | return 0; |
2b40182a CF |
76 | } |
77 | ||
78 | static int hi6220_ion_remove(struct platform_device *pdev) | |
79 | { | |
b6e336db | 80 | struct hisi_ion_dev *ipdev; |
2b40182a CF |
81 | int i; |
82 | ||
b6e336db LA |
83 | ipdev = platform_get_drvdata(pdev); |
84 | ||
85 | for (i = 0; i < ipdev->data->nr; i++) { | |
86 | ion_heap_destroy(ipdev->heaps[i]); | |
2b40182a | 87 | } |
b6e336db LA |
88 | ion_destroy_platform_data(ipdev->data); |
89 | ion_device_destroy(ipdev->idev); | |
2b40182a CF |
90 | |
91 | return 0; | |
92 | } | |
93 | ||
94 | static const struct of_device_id hi6220_ion_match_table[] = { | |
95 | {.compatible = "hisilicon,hi6220-ion"}, | |
96 | {}, | |
97 | }; | |
98 | ||
99 | static struct platform_driver hi6220_ion_driver = { | |
100 | .probe = hi6220_ion_probe, | |
101 | .remove = hi6220_ion_remove, | |
102 | .driver = { | |
103 | .name = "ion-hi6220", | |
104 | .of_match_table = hi6220_ion_match_table, | |
105 | }, | |
106 | }; | |
107 | ||
108 | static int __init hi6220_ion_init(void) | |
109 | { | |
dd284733 | 110 | return platform_driver_register(&hi6220_ion_driver); |
2b40182a CF |
111 | } |
112 | ||
113 | subsys_initcall(hi6220_ion_init); |