2 * AMD Secure Processor device driver
4 * Copyright (C) 2014,2018 Advanced Micro Devices, Inc.
6 * Author: Tom Lendacky <thomas.lendacky@amd.com>
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.
13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/device.h>
16 #include <linux/platform_device.h>
17 #include <linux/ioport.h>
18 #include <linux/dma-mapping.h>
19 #include <linux/kthread.h>
20 #include <linux/sched.h>
21 #include <linux/interrupt.h>
22 #include <linux/spinlock.h>
23 #include <linux/delay.h>
24 #include <linux/ccp.h>
26 #include <linux/of_address.h>
27 #include <linux/acpi.h>
33 unsigned int irq_count
;
36 static const struct sp_dev_vdata dev_vdata
[] = {
39 #ifdef CONFIG_CRYPTO_DEV_SP_CCP
40 .ccp_vdata
= &ccpv3_platform
,
46 static const struct acpi_device_id sp_acpi_match
[] = {
47 { "AMDI0C00", (kernel_ulong_t
)&dev_vdata
[0] },
50 MODULE_DEVICE_TABLE(acpi
, sp_acpi_match
);
54 static const struct of_device_id sp_of_match
[] = {
55 { .compatible
= "amd,ccp-seattle-v1a",
56 .data
= (const void *)&dev_vdata
[0] },
59 MODULE_DEVICE_TABLE(of
, sp_of_match
);
62 static struct sp_dev_vdata
*sp_get_of_version(struct platform_device
*pdev
)
65 const struct of_device_id
*match
;
67 match
= of_match_node(sp_of_match
, pdev
->dev
.of_node
);
68 if (match
&& match
->data
)
69 return (struct sp_dev_vdata
*)match
->data
;
74 static struct sp_dev_vdata
*sp_get_acpi_version(struct platform_device
*pdev
)
77 const struct acpi_device_id
*match
;
79 match
= acpi_match_device(sp_acpi_match
, &pdev
->dev
);
80 if (match
&& match
->driver_data
)
81 return (struct sp_dev_vdata
*)match
->driver_data
;
86 static int sp_get_irqs(struct sp_device
*sp
)
88 struct sp_platform
*sp_platform
= sp
->dev_specific
;
89 struct device
*dev
= sp
->dev
;
90 struct platform_device
*pdev
= to_platform_device(dev
);
91 unsigned int i
, count
;
94 for (i
= 0, count
= 0; i
< pdev
->num_resources
; i
++) {
95 struct resource
*res
= &pdev
->resource
[i
];
97 if (resource_type(res
) == IORESOURCE_IRQ
)
101 sp_platform
->irq_count
= count
;
103 ret
= platform_get_irq(pdev
, 0);
105 dev_notice(dev
, "unable to get IRQ (%d)\n", ret
);
113 ret
= platform_get_irq(pdev
, 1);
115 dev_notice(dev
, "unable to get IRQ (%d)\n", ret
);
125 static int sp_platform_probe(struct platform_device
*pdev
)
127 struct sp_device
*sp
;
128 struct sp_platform
*sp_platform
;
129 struct device
*dev
= &pdev
->dev
;
130 enum dev_dma_attr attr
;
131 struct resource
*ior
;
135 sp
= sp_alloc_struct(dev
);
139 sp_platform
= devm_kzalloc(dev
, sizeof(*sp_platform
), GFP_KERNEL
);
143 sp
->dev_specific
= sp_platform
;
144 sp
->dev_vdata
= pdev
->dev
.of_node
? sp_get_of_version(pdev
)
145 : sp_get_acpi_version(pdev
);
146 if (!sp
->dev_vdata
) {
148 dev_err(dev
, "missing driver data\n");
152 ior
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
153 sp
->io_map
= devm_ioremap_resource(dev
, ior
);
154 if (IS_ERR(sp
->io_map
)) {
155 ret
= PTR_ERR(sp
->io_map
);
159 attr
= device_get_dma_attr(dev
);
160 if (attr
== DEV_DMA_NOT_SUPPORTED
) {
161 dev_err(dev
, "DMA is not supported");
165 sp_platform
->coherent
= (attr
== DEV_DMA_COHERENT
);
166 if (sp_platform
->coherent
)
167 sp
->axcache
= CACHE_WB_NO_ALLOC
;
169 sp
->axcache
= CACHE_NONE
;
171 ret
= dma_set_mask_and_coherent(dev
, DMA_BIT_MASK(48));
173 dev_err(dev
, "dma_set_mask_and_coherent failed (%d)\n", ret
);
177 ret
= sp_get_irqs(sp
);
181 dev_set_drvdata(dev
, sp
);
187 dev_notice(dev
, "enabled\n");
192 dev_notice(dev
, "initialization failed\n");
196 static int sp_platform_remove(struct platform_device
*pdev
)
198 struct device
*dev
= &pdev
->dev
;
199 struct sp_device
*sp
= dev_get_drvdata(dev
);
203 dev_notice(dev
, "disabled\n");
209 static int sp_platform_suspend(struct platform_device
*pdev
,
212 struct device
*dev
= &pdev
->dev
;
213 struct sp_device
*sp
= dev_get_drvdata(dev
);
215 return sp_suspend(sp
, state
);
218 static int sp_platform_resume(struct platform_device
*pdev
)
220 struct device
*dev
= &pdev
->dev
;
221 struct sp_device
*sp
= dev_get_drvdata(dev
);
223 return sp_resume(sp
);
227 static struct platform_driver sp_platform_driver
= {
231 .acpi_match_table
= sp_acpi_match
,
234 .of_match_table
= sp_of_match
,
237 .probe
= sp_platform_probe
,
238 .remove
= sp_platform_remove
,
240 .suspend
= sp_platform_suspend
,
241 .resume
= sp_platform_resume
,
245 int sp_platform_init(void)
247 return platform_driver_register(&sp_platform_driver
);
250 void sp_platform_exit(void)
252 platform_driver_unregister(&sp_platform_driver
);