Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh...
[linux-2.6] / arch / powerpc / platforms / pasemi / electra_ide.c
1 /*
2  * Copyright (C) 2007 PA Semi, Inc
3  *
4  * Maintained by: Olof Johansson <olof@lixom.net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18  */
19
20 #include <linux/platform_device.h>
21
22 #include <asm/prom.h>
23 #include <asm/system.h>
24
25 /* The electra IDE interface is incredibly simple: Just a device on the localbus
26  * with interrupts hooked up to one of the GPIOs. The device tree contains the
27  * address window and interrupt mappings already, and the pata_platform driver handles
28  * the rest. We just need to hook the two up.
29  */
30
31 #define MAX_IFS 4       /* really, we have only one */
32
33 static struct platform_device *pdevs[MAX_IFS];
34
35 static int __devinit electra_ide_init(void)
36 {
37         struct device_node *np;
38         struct resource r[3];
39         int ret = 0;
40         int i;
41
42         np = of_find_compatible_node(NULL, "ide", "electra-ide");
43         i = 0;
44
45         while (np && i < MAX_IFS) {
46                 memset(r, 0, sizeof(r));
47
48                 /* pata_platform wants two address ranges: one for the base registers,
49                  * another for the control (altstatus). It's located at offset 0x3f6 in
50                  * the window, but the device tree only has one large register window
51                  * that covers both ranges. So we need to split it up by hand here:
52                  */
53
54                 ret = of_address_to_resource(np, 0, &r[0]);
55                 if (ret)
56                         goto out;
57                 ret = of_address_to_resource(np, 0, &r[1]);
58                 if (ret)
59                         goto out;
60
61                 r[1].start += 0x3f6;
62                 r[0].end = r[1].start-1;
63
64                 r[2].start = irq_of_parse_and_map(np, 0);
65                 r[2].end = irq_of_parse_and_map(np, 0);
66                 r[2].flags = IORESOURCE_IRQ;
67
68                 pr_debug("registering platform device at 0x%lx/0x%lx, irq is %ld\n",
69                          r[0].start, r[1].start, r[2].start);
70                 pdevs[i] = platform_device_register_simple("pata_platform", i, r, 3);
71                 if (IS_ERR(pdevs[i])) {
72                         ret = PTR_ERR(pdevs[i]);
73                         pdevs[i] = NULL;
74                         goto out;
75                 }
76                 np = of_find_compatible_node(np, "ide", "electra-ide");
77         }
78 out:
79         return ret;
80 }
81 module_init(electra_ide_init);
82
83 static void __devexit electra_ide_exit(void)
84 {
85         int i;
86
87         for (i = 0; i < MAX_IFS; i++)
88                 if (pdevs[i])
89                         platform_device_unregister(pdevs[i]);
90 }
91 module_exit(electra_ide_exit);
92
93
94 MODULE_LICENSE("GPL");
95 MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
96 MODULE_DESCRIPTION("PA Semi Electra IDE driver");