Root/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
30static const char *ring_tio_driver_name = "uio_ubicom32ring";
31
32/*
33 * The number of ring_tio's currently allocated, used for .id
34 */
35static 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 */
47void __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}
124

Archive Download this file



interactive