move new files out from platform support patch
[openwrt/openwrt.git] / target / linux / ubicom32 / files / arch / ubicom32 / mach-common / ring_tio.c
1 /*
2 * arch/ubicom32/mach-common/ring_tio.c
3 * Generic initialization for UIO Ubicom32 Ring
4 *
5 * (C) Copyright 2009, Ubicom, Inc.
6 *
7 * This file is part of the Ubicom32 Linux Kernel Port.
8 *
9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute
10 * it and/or modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation, either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with the Ubicom32 Linux Kernel Port. If not,
21 * see <http://www.gnu.org/licenses/>.
22 */
23
24 #include <linux/platform_device.h>
25 #include <linux/types.h>
26
27 #include <asm/devtree.h>
28 #include <asm/ring_tio.h>
29
30 static const char *ring_tio_driver_name = "uio_ubicom32ring";
31
32 /*
33 * The number of ring_tio's currently allocated, used for .id
34 */
35 static int __initdata ring_tio_count;
36
37 /*
38 * The maximum number of resources that the ring_tio will have.
39 * Currently 3, a register space, and up to 2 interrupts.
40 */
41 #define RING_TIO_MAX_RESOURCES 3
42
43 /*
44 * ring_tio_init
45 * Checks the device tree and instantiates the driver if found
46 */
47 void __init ring_tio_init(const char *node_name)
48 {
49 struct platform_device *pdev;
50 struct resource *res;
51 int resource_idx = 0;
52 struct ring_tio_node *ring_node;
53
54 /*
55 * Check the device tree for the ring_tio
56 */
57 ring_node = (struct ring_tio_node *)devtree_find_node(node_name);
58 if (!ring_node) {
59 printk(KERN_WARNING "Ring TIO '%s' not found\n", node_name);
60 return;
61 }
62
63 if (ring_node->version != RING_TIO_NODE_VERSION) {
64 printk(KERN_WARNING "ring_tio not compatible\n");
65 return;
66 }
67
68 /*
69 * Dynamically create the platform_device structure and resources
70 */
71 pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
72 if (!pdev) {
73 printk(KERN_WARNING "ring_tio could not alloc pdev\n");
74 return;
75 }
76
77 res = kzalloc(sizeof(struct resource) * RING_TIO_MAX_RESOURCES,
78 GFP_KERNEL);
79 if (!res) {
80 kfree(pdev);
81 printk(KERN_WARNING "ring_tio could not alloc res\n");
82 return;
83 }
84
85 pdev->name = ring_tio_driver_name;
86 pdev->id = ring_tio_count++;
87 pdev->resource = res;
88
89 /*
90 * Fill in the resources and platform data from devtree information
91 */
92 res[resource_idx].start = (u32_t)(ring_node->regs);
93 res[resource_idx].end = (u32_t)(ring_node->regs);
94 res[resource_idx].flags = IORESOURCE_MEM;
95 resource_idx++;
96
97 if (ring_node->dn.sendirq != 0xFF) {
98 res[resource_idx].start = ring_node->dn.sendirq;
99 res[resource_idx].flags = IORESOURCE_IRQ;
100 resource_idx++;
101 }
102
103 if (ring_node->dn.recvirq != 0xFF) {
104 res[resource_idx].start = ring_node->dn.recvirq;
105 res[resource_idx].flags = IORESOURCE_IRQ;
106 resource_idx++;
107 }
108 pdev->num_resources = resource_idx;
109
110 printk(KERN_INFO "RingTIO.%d '%s' found irq=%d/%d regs=%p pdev=%p/%p\n",
111 ring_tio_count - 1, node_name, ring_node->dn.sendirq,
112 ring_node->dn.recvirq, ring_node->regs, pdev, res);
113
114 /*
115 * Try to get the device registered
116 */
117 pdev->dev.platform_data = (void *)node_name;
118 if (platform_device_register(pdev) < 0) {
119 printk(KERN_WARNING "Ring failed to register\n");
120 kfree(pdev);
121 kfree(res);
122 }
123 }