2 * linux/drivers/misc/xillybus_of.c
4 * Copyright 2011 Xillybus Ltd, http://xillybus.com
6 * Driver for the Xillybus FPGA/host framework using Open Firmware.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the smems of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
13 #include <linux/module.h>
14 #include <linux/device.h>
15 #include <linux/slab.h>
16 #include <linux/platform_device.h>
18 #include <linux/of_irq.h>
19 #include <linux/of_address.h>
20 #include <linux/of_device.h>
21 #include <linux/of_platform.h>
22 #include <linux/err.h>
25 MODULE_DESCRIPTION("Xillybus driver for Open Firmware");
26 MODULE_AUTHOR("Eli Billauer, Xillybus Ltd.");
27 MODULE_VERSION("1.06");
28 MODULE_ALIAS("xillybus_of");
29 MODULE_LICENSE("GPL v2");
31 static const char xillyname
[] = "xillybus_of";
33 /* Match table for of_platform binding */
34 static const struct of_device_id xillybus_of_match
[] = {
35 { .compatible
= "xillybus,xillybus-1.00.a", },
36 { .compatible
= "xlnx,xillybus-1.00.a", }, /* Deprecated */
40 MODULE_DEVICE_TABLE(of
, xillybus_of_match
);
42 static void xilly_dma_sync_single_for_cpu_of(struct xilly_endpoint
*ep
,
43 dma_addr_t dma_handle
,
47 dma_sync_single_for_cpu(ep
->dev
, dma_handle
, size
, direction
);
50 static void xilly_dma_sync_single_for_device_of(struct xilly_endpoint
*ep
,
51 dma_addr_t dma_handle
,
55 dma_sync_single_for_device(ep
->dev
, dma_handle
, size
, direction
);
58 static void xilly_dma_sync_single_nop(struct xilly_endpoint
*ep
,
59 dma_addr_t dma_handle
,
65 static void xilly_of_unmap(void *ptr
)
67 struct xilly_mapping
*data
= ptr
;
69 dma_unmap_single(data
->device
, data
->dma_addr
,
70 data
->size
, data
->direction
);
75 static int xilly_map_single_of(struct xilly_endpoint
*ep
,
79 dma_addr_t
*ret_dma_handle
83 struct xilly_mapping
*this;
85 this = kzalloc(sizeof(*this), GFP_KERNEL
);
89 addr
= dma_map_single(ep
->dev
, ptr
, size
, direction
);
91 if (dma_mapping_error(ep
->dev
, addr
)) {
96 this->device
= ep
->dev
;
97 this->dma_addr
= addr
;
99 this->direction
= direction
;
101 *ret_dma_handle
= addr
;
103 return devm_add_action_or_reset(ep
->dev
, xilly_of_unmap
, this);
106 static struct xilly_endpoint_hardware of_hw
= {
107 .owner
= THIS_MODULE
,
108 .hw_sync_sgl_for_cpu
= xilly_dma_sync_single_for_cpu_of
,
109 .hw_sync_sgl_for_device
= xilly_dma_sync_single_for_device_of
,
110 .map_single
= xilly_map_single_of
,
113 static struct xilly_endpoint_hardware of_hw_coherent
= {
114 .owner
= THIS_MODULE
,
115 .hw_sync_sgl_for_cpu
= xilly_dma_sync_single_nop
,
116 .hw_sync_sgl_for_device
= xilly_dma_sync_single_nop
,
117 .map_single
= xilly_map_single_of
,
120 static int xilly_drv_probe(struct platform_device
*op
)
122 struct device
*dev
= &op
->dev
;
123 struct xilly_endpoint
*endpoint
;
127 struct xilly_endpoint_hardware
*ephw
= &of_hw
;
129 if (of_property_read_bool(dev
->of_node
, "dma-coherent"))
130 ephw
= &of_hw_coherent
;
132 endpoint
= xillybus_init_endpoint(NULL
, dev
, ephw
);
137 dev_set_drvdata(dev
, endpoint
);
139 rc
= of_address_to_resource(dev
->of_node
, 0, &res
);
140 endpoint
->registers
= devm_ioremap_resource(dev
, &res
);
142 if (IS_ERR(endpoint
->registers
))
143 return PTR_ERR(endpoint
->registers
);
145 irq
= irq_of_parse_and_map(dev
->of_node
, 0);
147 rc
= devm_request_irq(dev
, irq
, xillybus_isr
, 0, xillyname
, endpoint
);
150 dev_err(endpoint
->dev
,
151 "Failed to register IRQ handler. Aborting.\n");
155 return xillybus_endpoint_discovery(endpoint
);
158 static int xilly_drv_remove(struct platform_device
*op
)
160 struct device
*dev
= &op
->dev
;
161 struct xilly_endpoint
*endpoint
= dev_get_drvdata(dev
);
163 xillybus_endpoint_remove(endpoint
);
168 static struct platform_driver xillybus_platform_driver
= {
169 .probe
= xilly_drv_probe
,
170 .remove
= xilly_drv_remove
,
173 .of_match_table
= xillybus_of_match
,
177 module_platform_driver(xillybus_platform_driver
);