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 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 dma_addr_t
xilly_map_single_of(struct xilly_cleanup
*mem
,
66 struct xilly_endpoint
*ep
,
74 struct xilly_dma
*this;
76 this = kmalloc(sizeof(struct xilly_dma
), GFP_KERNEL
);
80 addr
= dma_map_single(ep
->dev
, ptr
, size
, direction
);
81 this->direction
= direction
;
83 if (dma_mapping_error(ep
->dev
, addr
)) {
88 this->dma_addr
= addr
;
92 list_add_tail(&this->node
, &mem
->to_unmap
);
97 static void xilly_unmap_single_of(struct xilly_dma
*entry
)
99 dma_unmap_single(entry
->dev
,
105 static struct xilly_endpoint_hardware of_hw
= {
106 .owner
= THIS_MODULE
,
107 .hw_sync_sgl_for_cpu
= xilly_dma_sync_single_for_cpu_of
,
108 .hw_sync_sgl_for_device
= xilly_dma_sync_single_for_device_of
,
109 .map_single
= xilly_map_single_of
,
110 .unmap_single
= xilly_unmap_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
,
118 .unmap_single
= xilly_unmap_single_of
121 static int xilly_drv_probe(struct platform_device
*op
)
123 struct device
*dev
= &op
->dev
;
124 struct xilly_endpoint
*endpoint
;
128 struct xilly_endpoint_hardware
*ephw
= &of_hw
;
130 if (of_property_read_bool(dev
->of_node
, "dma-coherent"))
131 ephw
= &of_hw_coherent
;
133 endpoint
= xillybus_init_endpoint(NULL
, dev
, ephw
);
138 dev_set_drvdata(dev
, endpoint
);
140 rc
= of_address_to_resource(dev
->of_node
, 0, &res
);
142 dev_warn(endpoint
->dev
,
143 "Failed to obtain device tree resource\n");
147 endpoint
->registers
= devm_ioremap_resource(dev
, &res
);
149 if (IS_ERR(endpoint
->registers
))
150 return PTR_ERR(endpoint
->registers
);
152 irq
= irq_of_parse_and_map(dev
->of_node
, 0);
154 rc
= devm_request_irq(dev
, irq
, xillybus_isr
, 0, xillyname
, endpoint
);
157 dev_err(endpoint
->dev
,
158 "Failed to register IRQ handler. Aborting.\n");
162 rc
= xillybus_endpoint_discovery(endpoint
);
167 xillybus_do_cleanup(&endpoint
->cleanup
, endpoint
);
172 static int xilly_drv_remove(struct platform_device
*op
)
174 struct device
*dev
= &op
->dev
;
175 struct xilly_endpoint
*endpoint
= dev_get_drvdata(dev
);
177 xillybus_endpoint_remove(endpoint
);
179 xillybus_do_cleanup(&endpoint
->cleanup
, endpoint
);
184 static struct platform_driver xillybus_platform_driver
= {
185 .probe
= xilly_drv_probe
,
186 .remove
= xilly_drv_remove
,
189 .owner
= THIS_MODULE
,
190 .of_match_table
= xillybus_of_match
,
194 module_platform_driver(xillybus_platform_driver
);