1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/drivers/misc/xillybus_of.c
5 * Copyright 2011 Xillybus Ltd, http://xillybus.com
7 * Driver for the Xillybus FPGA/host framework using Open Firmware.
10 #include <linux/module.h>
11 #include <linux/device.h>
12 #include <linux/slab.h>
13 #include <linux/platform_device.h>
15 #include <linux/err.h>
18 MODULE_DESCRIPTION("Xillybus driver for Open Firmware");
19 MODULE_AUTHOR("Eli Billauer, Xillybus Ltd.");
20 MODULE_VERSION("1.06");
21 MODULE_ALIAS("xillybus_of");
22 MODULE_LICENSE("GPL v2");
24 static const char xillyname
[] = "xillybus_of";
26 /* Match table for of_platform binding */
27 static const struct of_device_id xillybus_of_match
[] = {
28 { .compatible
= "xillybus,xillybus-1.00.a", },
29 { .compatible
= "xlnx,xillybus-1.00.a", }, /* Deprecated */
33 MODULE_DEVICE_TABLE(of
, xillybus_of_match
);
35 static void xilly_dma_sync_single_for_cpu_of(struct xilly_endpoint
*ep
,
36 dma_addr_t dma_handle
,
40 dma_sync_single_for_cpu(ep
->dev
, dma_handle
, size
, direction
);
43 static void xilly_dma_sync_single_for_device_of(struct xilly_endpoint
*ep
,
44 dma_addr_t dma_handle
,
48 dma_sync_single_for_device(ep
->dev
, dma_handle
, size
, direction
);
51 static void xilly_dma_sync_single_nop(struct xilly_endpoint
*ep
,
52 dma_addr_t dma_handle
,
58 static void xilly_of_unmap(void *ptr
)
60 struct xilly_mapping
*data
= ptr
;
62 dma_unmap_single(data
->device
, data
->dma_addr
,
63 data
->size
, data
->direction
);
68 static int xilly_map_single_of(struct xilly_endpoint
*ep
,
72 dma_addr_t
*ret_dma_handle
76 struct xilly_mapping
*this;
78 this = kzalloc(sizeof(*this), GFP_KERNEL
);
82 addr
= dma_map_single(ep
->dev
, ptr
, size
, direction
);
84 if (dma_mapping_error(ep
->dev
, addr
)) {
89 this->device
= ep
->dev
;
90 this->dma_addr
= addr
;
92 this->direction
= direction
;
94 *ret_dma_handle
= addr
;
96 return devm_add_action_or_reset(ep
->dev
, xilly_of_unmap
, this);
99 static struct xilly_endpoint_hardware of_hw
= {
100 .owner
= THIS_MODULE
,
101 .hw_sync_sgl_for_cpu
= xilly_dma_sync_single_for_cpu_of
,
102 .hw_sync_sgl_for_device
= xilly_dma_sync_single_for_device_of
,
103 .map_single
= xilly_map_single_of
,
106 static struct xilly_endpoint_hardware of_hw_coherent
= {
107 .owner
= THIS_MODULE
,
108 .hw_sync_sgl_for_cpu
= xilly_dma_sync_single_nop
,
109 .hw_sync_sgl_for_device
= xilly_dma_sync_single_nop
,
110 .map_single
= xilly_map_single_of
,
113 static int xilly_drv_probe(struct platform_device
*op
)
115 struct device
*dev
= &op
->dev
;
116 struct xilly_endpoint
*endpoint
;
119 struct xilly_endpoint_hardware
*ephw
= &of_hw
;
121 if (of_property_read_bool(dev
->of_node
, "dma-coherent"))
122 ephw
= &of_hw_coherent
;
124 endpoint
= xillybus_init_endpoint(NULL
, dev
, ephw
);
129 dev_set_drvdata(dev
, endpoint
);
131 endpoint
->registers
= devm_platform_ioremap_resource(op
, 0);
132 if (IS_ERR(endpoint
->registers
))
133 return PTR_ERR(endpoint
->registers
);
135 irq
= platform_get_irq(op
, 0);
137 rc
= devm_request_irq(dev
, irq
, xillybus_isr
, 0, xillyname
, endpoint
);
140 dev_err(endpoint
->dev
,
141 "Failed to register IRQ handler. Aborting.\n");
145 return xillybus_endpoint_discovery(endpoint
);
148 static int xilly_drv_remove(struct platform_device
*op
)
150 struct device
*dev
= &op
->dev
;
151 struct xilly_endpoint
*endpoint
= dev_get_drvdata(dev
);
153 xillybus_endpoint_remove(endpoint
);
158 static struct platform_driver xillybus_platform_driver
= {
159 .probe
= xilly_drv_probe
,
160 .remove
= xilly_drv_remove
,
163 .of_match_table
= xillybus_of_match
,
167 module_platform_driver(xillybus_platform_driver
);