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/err.h>
21 MODULE_DESCRIPTION("Xillybus driver for Open Firmware");
22 MODULE_AUTHOR("Eli Billauer, Xillybus Ltd.");
23 MODULE_VERSION("1.06");
24 MODULE_ALIAS("xillybus_of");
25 MODULE_LICENSE("GPL v2");
27 static const char xillyname
[] = "xillybus_of";
29 /* Match table for of_platform binding */
30 static const struct of_device_id xillybus_of_match
[] = {
31 { .compatible
= "xillybus,xillybus-1.00.a", },
32 { .compatible
= "xlnx,xillybus-1.00.a", }, /* Deprecated */
36 MODULE_DEVICE_TABLE(of
, xillybus_of_match
);
38 static void xilly_dma_sync_single_for_cpu_of(struct xilly_endpoint
*ep
,
39 dma_addr_t dma_handle
,
43 dma_sync_single_for_cpu(ep
->dev
, dma_handle
, size
, direction
);
46 static void xilly_dma_sync_single_for_device_of(struct xilly_endpoint
*ep
,
47 dma_addr_t dma_handle
,
51 dma_sync_single_for_device(ep
->dev
, dma_handle
, size
, direction
);
54 static void xilly_dma_sync_single_nop(struct xilly_endpoint
*ep
,
55 dma_addr_t dma_handle
,
61 static void xilly_of_unmap(void *ptr
)
63 struct xilly_mapping
*data
= ptr
;
65 dma_unmap_single(data
->device
, data
->dma_addr
,
66 data
->size
, data
->direction
);
71 static int xilly_map_single_of(struct xilly_endpoint
*ep
,
75 dma_addr_t
*ret_dma_handle
79 struct xilly_mapping
*this;
81 this = kzalloc(sizeof(*this), GFP_KERNEL
);
85 addr
= dma_map_single(ep
->dev
, ptr
, size
, direction
);
87 if (dma_mapping_error(ep
->dev
, addr
)) {
92 this->device
= ep
->dev
;
93 this->dma_addr
= addr
;
95 this->direction
= direction
;
97 *ret_dma_handle
= addr
;
99 return devm_add_action_or_reset(ep
->dev
, xilly_of_unmap
, this);
102 static struct xilly_endpoint_hardware of_hw
= {
103 .owner
= THIS_MODULE
,
104 .hw_sync_sgl_for_cpu
= xilly_dma_sync_single_for_cpu_of
,
105 .hw_sync_sgl_for_device
= xilly_dma_sync_single_for_device_of
,
106 .map_single
= xilly_map_single_of
,
109 static struct xilly_endpoint_hardware of_hw_coherent
= {
110 .owner
= THIS_MODULE
,
111 .hw_sync_sgl_for_cpu
= xilly_dma_sync_single_nop
,
112 .hw_sync_sgl_for_device
= xilly_dma_sync_single_nop
,
113 .map_single
= xilly_map_single_of
,
116 static int xilly_drv_probe(struct platform_device
*op
)
118 struct device
*dev
= &op
->dev
;
119 struct xilly_endpoint
*endpoint
;
122 struct resource
*res
;
123 struct xilly_endpoint_hardware
*ephw
= &of_hw
;
125 if (of_property_read_bool(dev
->of_node
, "dma-coherent"))
126 ephw
= &of_hw_coherent
;
128 endpoint
= xillybus_init_endpoint(NULL
, dev
, ephw
);
133 dev_set_drvdata(dev
, endpoint
);
135 res
= platform_get_resource(op
, IORESOURCE_MEM
, 0);
136 endpoint
->registers
= devm_ioremap_resource(dev
, res
);
138 if (IS_ERR(endpoint
->registers
))
139 return PTR_ERR(endpoint
->registers
);
141 irq
= platform_get_irq(op
, 0);
143 rc
= devm_request_irq(dev
, irq
, xillybus_isr
, 0, xillyname
, endpoint
);
146 dev_err(endpoint
->dev
,
147 "Failed to register IRQ handler. Aborting.\n");
151 return xillybus_endpoint_discovery(endpoint
);
154 static int xilly_drv_remove(struct platform_device
*op
)
156 struct device
*dev
= &op
->dev
;
157 struct xilly_endpoint
*endpoint
= dev_get_drvdata(dev
);
159 xillybus_endpoint_remove(endpoint
);
164 static struct platform_driver xillybus_platform_driver
= {
165 .probe
= xilly_drv_probe
,
166 .remove
= xilly_drv_remove
,
169 .of_match_table
= xillybus_of_match
,
173 module_platform_driver(xillybus_platform_driver
);