diff options
-rw-r--r-- | arch/powerpc/configs/pasemi_defconfig | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/Kconfig | 9 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/electra_ide.c | 96 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/idle.c | 5 | ||||
-rw-r--r-- | arch/powerpc/platforms/pasemi/setup.c | 12 | ||||
-rw-r--r-- | drivers/ata/Kconfig | 12 | ||||
-rw-r--r-- | drivers/ata/Makefile | 1 | ||||
-rw-r--r-- | drivers/ata/pata_of_platform.c | 114 | ||||
-rw-r--r-- | drivers/ata/pata_platform.c | 144 | ||||
-rw-r--r-- | include/linux/pata_platform.h | 9 |
11 files changed, 227 insertions, 180 deletions
diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index 9d21b083ae12..797f0dfebde2 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.24-rc6 | 3 | # Linux kernel version: 2.6.24-rc6 |
4 | # Fri Dec 28 11:01:53 2007 | 4 | # Tue Jan 15 10:26:10 2008 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | 7 | ||
@@ -152,7 +152,6 @@ CONFIG_PPC_PASEMI=y | |||
152 | CONFIG_PPC_PASEMI_IOMMU=y | 152 | CONFIG_PPC_PASEMI_IOMMU=y |
153 | # CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set | 153 | # CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set |
154 | CONFIG_PPC_PASEMI_MDIO=y | 154 | CONFIG_PPC_PASEMI_MDIO=y |
155 | CONFIG_ELECTRA_IDE=y | ||
156 | # CONFIG_PPC_CELLEB is not set | 155 | # CONFIG_PPC_CELLEB is not set |
157 | # CONFIG_PPC_PS3 is not set | 156 | # CONFIG_PPC_PS3 is not set |
158 | # CONFIG_PPC_CELL is not set | 157 | # CONFIG_PPC_CELL is not set |
@@ -663,6 +662,7 @@ CONFIG_PATA_PCMCIA=y | |||
663 | # CONFIG_PATA_VIA is not set | 662 | # CONFIG_PATA_VIA is not set |
664 | # CONFIG_PATA_WINBOND is not set | 663 | # CONFIG_PATA_WINBOND is not set |
665 | CONFIG_PATA_PLATFORM=y | 664 | CONFIG_PATA_PLATFORM=y |
665 | CONFIG_PATA_OF_PLATFORM=y | ||
666 | CONFIG_MD=y | 666 | CONFIG_MD=y |
667 | CONFIG_BLK_DEV_MD=y | 667 | CONFIG_BLK_DEV_MD=y |
668 | CONFIG_MD_LINEAR=y | 668 | CONFIG_MD_LINEAR=y |
diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig index b3458a181a15..348e0619e3e5 100644 --- a/arch/powerpc/platforms/pasemi/Kconfig +++ b/arch/powerpc/platforms/pasemi/Kconfig | |||
@@ -37,13 +37,4 @@ config PPC_PASEMI_MDIO | |||
37 | help | 37 | help |
38 | Driver for MDIO via GPIO on PWRficient platforms | 38 | Driver for MDIO via GPIO on PWRficient platforms |
39 | 39 | ||
40 | config ELECTRA_IDE | ||
41 | tristate "Electra IDE driver" | ||
42 | default y | ||
43 | depends on PPC_PASEMI && ATA | ||
44 | select PATA_PLATFORM | ||
45 | help | ||
46 | This includes driver support for the Electra on-board IDE | ||
47 | interface. | ||
48 | |||
49 | endmenu | 40 | endmenu |
diff --git a/arch/powerpc/platforms/pasemi/Makefile b/arch/powerpc/platforms/pasemi/Makefile index f47fcac7e581..2cd2a4f26a48 100644 --- a/arch/powerpc/platforms/pasemi/Makefile +++ b/arch/powerpc/platforms/pasemi/Makefile | |||
@@ -1,4 +1,3 @@ | |||
1 | obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o | 1 | obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o |
2 | obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o | 2 | obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o |
3 | obj-$(CONFIG_ELECTRA_IDE) += electra_ide.o | ||
4 | obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o | 3 | obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o |
diff --git a/arch/powerpc/platforms/pasemi/electra_ide.c b/arch/powerpc/platforms/pasemi/electra_ide.c deleted file mode 100644 index 12fb0c949263..000000000000 --- a/arch/powerpc/platforms/pasemi/electra_ide.c +++ /dev/null | |||
@@ -1,96 +0,0 @@ | |||
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"); | ||
diff --git a/arch/powerpc/platforms/pasemi/idle.c b/arch/powerpc/platforms/pasemi/idle.c index d8e1fcc78513..43911d8b0206 100644 --- a/arch/powerpc/platforms/pasemi/idle.c +++ b/arch/powerpc/platforms/pasemi/idle.c | |||
@@ -74,9 +74,6 @@ static int pasemi_system_reset_exception(struct pt_regs *regs) | |||
74 | 74 | ||
75 | static int __init pasemi_idle_init(void) | 75 | static int __init pasemi_idle_init(void) |
76 | { | 76 | { |
77 | if (!machine_is(pasemi)) | ||
78 | return -ENODEV; | ||
79 | |||
80 | #ifndef CONFIG_PPC_PASEMI_CPUFREQ | 77 | #ifndef CONFIG_PPC_PASEMI_CPUFREQ |
81 | printk(KERN_WARNING "No cpufreq driver, powersavings modes disabled\n"); | 78 | printk(KERN_WARNING "No cpufreq driver, powersavings modes disabled\n"); |
82 | current_mode = 0; | 79 | current_mode = 0; |
@@ -88,7 +85,7 @@ static int __init pasemi_idle_init(void) | |||
88 | 85 | ||
89 | return 0; | 86 | return 0; |
90 | } | 87 | } |
91 | late_initcall(pasemi_idle_init); | 88 | machine_late_initcall(pasemi, pasemi_idle_init); |
92 | 89 | ||
93 | static int __init idle_param(char *p) | 90 | static int __init idle_param(char *p) |
94 | { | 91 | { |
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index 1940e678878e..c64fb5bfb37e 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c | |||
@@ -135,9 +135,6 @@ static int __init pas_setup_mce_regs(void) | |||
135 | struct pci_dev *dev; | 135 | struct pci_dev *dev; |
136 | int reg; | 136 | int reg; |
137 | 137 | ||
138 | if (!machine_is(pasemi)) | ||
139 | return -ENODEV; | ||
140 | |||
141 | /* Remap various SoC status registers for use by the MCE handler */ | 138 | /* Remap various SoC status registers for use by the MCE handler */ |
142 | 139 | ||
143 | reg = 0; | 140 | reg = 0; |
@@ -181,7 +178,7 @@ static int __init pas_setup_mce_regs(void) | |||
181 | 178 | ||
182 | return 0; | 179 | return 0; |
183 | } | 180 | } |
184 | device_initcall(pas_setup_mce_regs); | 181 | machine_device_initcall(pasemi, pas_setup_mce_regs); |
185 | 182 | ||
186 | static __init void pas_init_IRQ(void) | 183 | static __init void pas_init_IRQ(void) |
187 | { | 184 | { |
@@ -264,7 +261,7 @@ static int pas_machine_check_handler(struct pt_regs *regs) | |||
264 | srr0 = regs->nip; | 261 | srr0 = regs->nip; |
265 | srr1 = regs->msr; | 262 | srr1 = regs->msr; |
266 | 263 | ||
267 | if (mpic_get_mcirq() == nmi_virq) { | 264 | if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) { |
268 | printk(KERN_ERR "NMI delivered\n"); | 265 | printk(KERN_ERR "NMI delivered\n"); |
269 | debugger(regs); | 266 | debugger(regs); |
270 | mpic_end_irq(nmi_virq); | 267 | mpic_end_irq(nmi_virq); |
@@ -405,9 +402,6 @@ static struct of_device_id pasemi_bus_ids[] = { | |||
405 | 402 | ||
406 | static int __init pasemi_publish_devices(void) | 403 | static int __init pasemi_publish_devices(void) |
407 | { | 404 | { |
408 | if (!machine_is(pasemi)) | ||
409 | return 0; | ||
410 | |||
411 | pasemi_pcmcia_init(); | 405 | pasemi_pcmcia_init(); |
412 | 406 | ||
413 | /* Publish OF platform devices for SDC and other non-PCI devices */ | 407 | /* Publish OF platform devices for SDC and other non-PCI devices */ |
@@ -415,7 +409,7 @@ static int __init pasemi_publish_devices(void) | |||
415 | 409 | ||
416 | return 0; | 410 | return 0; |
417 | } | 411 | } |
418 | device_initcall(pasemi_publish_devices); | 412 | machine_device_initcall(pasemi, pasemi_publish_devices); |
419 | 413 | ||
420 | 414 | ||
421 | /* | 415 | /* |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index ba63619ae5df..64b4964d57e7 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -607,13 +607,23 @@ config PATA_WINBOND_VLB | |||
607 | 607 | ||
608 | config PATA_PLATFORM | 608 | config PATA_PLATFORM |
609 | tristate "Generic platform device PATA support" | 609 | tristate "Generic platform device PATA support" |
610 | depends on EMBEDDED || ARCH_RPC | 610 | depends on EMBEDDED || ARCH_RPC || PPC |
611 | help | 611 | help |
612 | This option enables support for generic directly connected ATA | 612 | This option enables support for generic directly connected ATA |
613 | devices commonly found on embedded systems. | 613 | devices commonly found on embedded systems. |
614 | 614 | ||
615 | If unsure, say N. | 615 | If unsure, say N. |
616 | 616 | ||
617 | config PATA_OF_PLATFORM | ||
618 | tristate "OpenFirmware platform device PATA support" | ||
619 | depends on PATA_PLATFORM && PPC_OF | ||
620 | help | ||
621 | This option enables support for generic directly connected ATA | ||
622 | devices commonly found on embedded systems with OpenFirmware | ||
623 | bindings. | ||
624 | |||
625 | If unsure, say N. | ||
626 | |||
617 | config PATA_ICSIDE | 627 | config PATA_ICSIDE |
618 | tristate "Acorn ICS PATA support" | 628 | tristate "Acorn ICS PATA support" |
619 | depends on ARM && ARCH_ACORN | 629 | depends on ARM && ARCH_ACORN |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index b13feb2c5dae..ebcee64dd5e2 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -67,6 +67,7 @@ obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o | |||
67 | obj-$(CONFIG_PATA_SCC) += pata_scc.o | 67 | obj-$(CONFIG_PATA_SCC) += pata_scc.o |
68 | obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o | 68 | obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o |
69 | obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o | 69 | obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o |
70 | obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o | ||
70 | obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o | 71 | obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o |
71 | # Should be last but two libata driver | 72 | # Should be last but two libata driver |
72 | obj-$(CONFIG_PATA_ACPI) += pata_acpi.o | 73 | obj-$(CONFIG_PATA_ACPI) += pata_acpi.o |
diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c new file mode 100644 index 000000000000..938f48a807eb --- /dev/null +++ b/drivers/ata/pata_of_platform.c | |||
@@ -0,0 +1,114 @@ | |||
1 | /* | ||
2 | * OF-platform PATA driver | ||
3 | * | ||
4 | * Copyright (c) 2007 MontaVista Software, Inc. | ||
5 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/of_platform.h> | ||
15 | #include <linux/pata_platform.h> | ||
16 | |||
17 | static int __devinit pata_of_platform_probe(struct of_device *ofdev, | ||
18 | const struct of_device_id *match) | ||
19 | { | ||
20 | int ret; | ||
21 | struct device_node *dn = ofdev->node; | ||
22 | struct resource io_res; | ||
23 | struct resource ctl_res; | ||
24 | struct resource irq_res; | ||
25 | unsigned int reg_shift = 0; | ||
26 | int pio_mode = 0; | ||
27 | int pio_mask; | ||
28 | const u32 *prop; | ||
29 | |||
30 | ret = of_address_to_resource(dn, 0, &io_res); | ||
31 | if (ret) { | ||
32 | dev_err(&ofdev->dev, "can't get IO address from " | ||
33 | "device tree\n"); | ||
34 | return -EINVAL; | ||
35 | } | ||
36 | |||
37 | if (of_device_is_compatible(dn, "electra-ide")) { | ||
38 | /* Altstatus is really at offset 0x3f6 from the primary window | ||
39 | * on electra-ide. Adjust ctl_res and io_res accordingly. | ||
40 | */ | ||
41 | ctl_res = io_res; | ||
42 | ctl_res.start = ctl_res.start+0x3f6; | ||
43 | io_res.end = ctl_res.start-1; | ||
44 | } else { | ||
45 | ret = of_address_to_resource(dn, 1, &ctl_res); | ||
46 | if (ret) { | ||
47 | dev_err(&ofdev->dev, "can't get CTL address from " | ||
48 | "device tree\n"); | ||
49 | return -EINVAL; | ||
50 | } | ||
51 | } | ||
52 | |||
53 | ret = of_irq_to_resource(dn, 0, &irq_res); | ||
54 | if (ret == NO_IRQ) | ||
55 | irq_res.start = irq_res.end = -1; | ||
56 | else | ||
57 | irq_res.flags = 0; | ||
58 | |||
59 | prop = of_get_property(dn, "reg-shift", NULL); | ||
60 | if (prop) | ||
61 | reg_shift = *prop; | ||
62 | |||
63 | prop = of_get_property(dn, "pio-mode", NULL); | ||
64 | if (prop) { | ||
65 | pio_mode = *prop; | ||
66 | if (pio_mode > 6) { | ||
67 | dev_err(&ofdev->dev, "invalid pio-mode\n"); | ||
68 | return -EINVAL; | ||
69 | } | ||
70 | } else { | ||
71 | dev_info(&ofdev->dev, "pio-mode unspecified, assuming PIO0\n"); | ||
72 | } | ||
73 | |||
74 | pio_mask = 1 << pio_mode; | ||
75 | pio_mask |= (1 << pio_mode) - 1; | ||
76 | |||
77 | return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, &irq_res, | ||
78 | reg_shift, pio_mask); | ||
79 | } | ||
80 | |||
81 | static int __devexit pata_of_platform_remove(struct of_device *ofdev) | ||
82 | { | ||
83 | return __pata_platform_remove(&ofdev->dev); | ||
84 | } | ||
85 | |||
86 | static struct of_device_id pata_of_platform_match[] = { | ||
87 | { .compatible = "ata-generic", }, | ||
88 | { .compatible = "electra-ide", }, | ||
89 | {}, | ||
90 | }; | ||
91 | MODULE_DEVICE_TABLE(of, pata_of_platform_match); | ||
92 | |||
93 | static struct of_platform_driver pata_of_platform_driver = { | ||
94 | .name = "pata_of_platform", | ||
95 | .match_table = pata_of_platform_match, | ||
96 | .probe = pata_of_platform_probe, | ||
97 | .remove = __devexit_p(pata_of_platform_remove), | ||
98 | }; | ||
99 | |||
100 | static int __init pata_of_platform_init(void) | ||
101 | { | ||
102 | return of_register_platform_driver(&pata_of_platform_driver); | ||
103 | } | ||
104 | module_init(pata_of_platform_init); | ||
105 | |||
106 | static void __exit pata_of_platform_exit(void) | ||
107 | { | ||
108 | of_unregister_platform_driver(&pata_of_platform_driver); | ||
109 | } | ||
110 | module_exit(pata_of_platform_exit); | ||
111 | |||
112 | MODULE_DESCRIPTION("OF-platform PATA driver"); | ||
113 | MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>"); | ||
114 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index ac03a90a6168..224bb6c2030a 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c | |||
@@ -93,14 +93,9 @@ static struct ata_port_operations pata_platform_port_ops = { | |||
93 | }; | 93 | }; |
94 | 94 | ||
95 | static void pata_platform_setup_port(struct ata_ioports *ioaddr, | 95 | static void pata_platform_setup_port(struct ata_ioports *ioaddr, |
96 | struct pata_platform_info *info) | 96 | unsigned int shift) |
97 | { | 97 | { |
98 | unsigned int shift = 0; | ||
99 | |||
100 | /* Fixup the port shift for platforms that need it */ | 98 | /* Fixup the port shift for platforms that need it */ |
101 | if (info && info->ioport_shift) | ||
102 | shift = info->ioport_shift; | ||
103 | |||
104 | ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift); | 99 | ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift); |
105 | ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift); | 100 | ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift); |
106 | ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift); | 101 | ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift); |
@@ -114,8 +109,13 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr, | |||
114 | } | 109 | } |
115 | 110 | ||
116 | /** | 111 | /** |
117 | * pata_platform_probe - attach a platform interface | 112 | * __pata_platform_probe - attach a platform interface |
118 | * @pdev: platform device | 113 | * @dev: device |
114 | * @io_res: Resource representing I/O base | ||
115 | * @ctl_res: Resource representing CTL base | ||
116 | * @irq_res: Resource representing IRQ and its flags | ||
117 | * @ioport_shift: I/O port shift | ||
118 | * @__pio_mask: PIO mask | ||
119 | * | 119 | * |
120 | * Register a platform bus IDE interface. Such interfaces are PIO and we | 120 | * Register a platform bus IDE interface. Such interfaces are PIO and we |
121 | * assume do not support IRQ sharing. | 121 | * assume do not support IRQ sharing. |
@@ -135,42 +135,18 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr, | |||
135 | * | 135 | * |
136 | * If no IRQ resource is present, PIO polling mode is used instead. | 136 | * If no IRQ resource is present, PIO polling mode is used instead. |
137 | */ | 137 | */ |
138 | static int __devinit pata_platform_probe(struct platform_device *pdev) | 138 | int __devinit __pata_platform_probe(struct device *dev, |
139 | struct resource *io_res, | ||
140 | struct resource *ctl_res, | ||
141 | struct resource *irq_res, | ||
142 | unsigned int ioport_shift, | ||
143 | int __pio_mask) | ||
139 | { | 144 | { |
140 | struct resource *io_res, *ctl_res; | ||
141 | struct ata_host *host; | 145 | struct ata_host *host; |
142 | struct ata_port *ap; | 146 | struct ata_port *ap; |
143 | struct pata_platform_info *pp_info; | ||
144 | unsigned int mmio; | 147 | unsigned int mmio; |
145 | int irq; | 148 | int irq = 0; |
146 | 149 | int irq_flags = 0; | |
147 | /* | ||
148 | * Simple resource validation .. | ||
149 | */ | ||
150 | if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) { | ||
151 | dev_err(&pdev->dev, "invalid number of resources\n"); | ||
152 | return -EINVAL; | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * Get the I/O base first | ||
157 | */ | ||
158 | io_res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
159 | if (io_res == NULL) { | ||
160 | io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
161 | if (unlikely(io_res == NULL)) | ||
162 | return -EINVAL; | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Then the CTL base | ||
167 | */ | ||
168 | ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1); | ||
169 | if (ctl_res == NULL) { | ||
170 | ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
171 | if (unlikely(ctl_res == NULL)) | ||
172 | return -EINVAL; | ||
173 | } | ||
174 | 150 | ||
175 | /* | 151 | /* |
176 | * Check for MMIO | 152 | * Check for MMIO |
@@ -181,20 +157,21 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) | |||
181 | /* | 157 | /* |
182 | * And the IRQ | 158 | * And the IRQ |
183 | */ | 159 | */ |
184 | irq = platform_get_irq(pdev, 0); | 160 | if (irq_res && irq_res->start > 0) { |
185 | if (irq < 0) | 161 | irq = irq_res->start; |
186 | irq = 0; /* no irq */ | 162 | irq_flags = irq_res->flags; |
163 | } | ||
187 | 164 | ||
188 | /* | 165 | /* |
189 | * Now that that's out of the way, wire up the port.. | 166 | * Now that that's out of the way, wire up the port.. |
190 | */ | 167 | */ |
191 | host = ata_host_alloc(&pdev->dev, 1); | 168 | host = ata_host_alloc(dev, 1); |
192 | if (!host) | 169 | if (!host) |
193 | return -ENOMEM; | 170 | return -ENOMEM; |
194 | ap = host->ports[0]; | 171 | ap = host->ports[0]; |
195 | 172 | ||
196 | ap->ops = &pata_platform_port_ops; | 173 | ap->ops = &pata_platform_port_ops; |
197 | ap->pio_mask = pio_mask; | 174 | ap->pio_mask = __pio_mask; |
198 | ap->flags |= ATA_FLAG_SLAVE_POSS; | 175 | ap->flags |= ATA_FLAG_SLAVE_POSS; |
199 | 176 | ||
200 | /* | 177 | /* |
@@ -209,25 +186,24 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) | |||
209 | * Handle the MMIO case | 186 | * Handle the MMIO case |
210 | */ | 187 | */ |
211 | if (mmio) { | 188 | if (mmio) { |
212 | ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, io_res->start, | 189 | ap->ioaddr.cmd_addr = devm_ioremap(dev, io_res->start, |
213 | io_res->end - io_res->start + 1); | 190 | io_res->end - io_res->start + 1); |
214 | ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start, | 191 | ap->ioaddr.ctl_addr = devm_ioremap(dev, ctl_res->start, |
215 | ctl_res->end - ctl_res->start + 1); | 192 | ctl_res->end - ctl_res->start + 1); |
216 | } else { | 193 | } else { |
217 | ap->ioaddr.cmd_addr = devm_ioport_map(&pdev->dev, io_res->start, | 194 | ap->ioaddr.cmd_addr = devm_ioport_map(dev, io_res->start, |
218 | io_res->end - io_res->start + 1); | 195 | io_res->end - io_res->start + 1); |
219 | ap->ioaddr.ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start, | 196 | ap->ioaddr.ctl_addr = devm_ioport_map(dev, ctl_res->start, |
220 | ctl_res->end - ctl_res->start + 1); | 197 | ctl_res->end - ctl_res->start + 1); |
221 | } | 198 | } |
222 | if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) { | 199 | if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) { |
223 | dev_err(&pdev->dev, "failed to map IO/CTL base\n"); | 200 | dev_err(dev, "failed to map IO/CTL base\n"); |
224 | return -ENOMEM; | 201 | return -ENOMEM; |
225 | } | 202 | } |
226 | 203 | ||
227 | ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; | 204 | ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; |
228 | 205 | ||
229 | pp_info = pdev->dev.platform_data; | 206 | pata_platform_setup_port(&ap->ioaddr, ioport_shift); |
230 | pata_platform_setup_port(&ap->ioaddr, pp_info); | ||
231 | 207 | ||
232 | ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport", | 208 | ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport", |
233 | (unsigned long long)io_res->start, | 209 | (unsigned long long)io_res->start, |
@@ -235,26 +211,78 @@ static int __devinit pata_platform_probe(struct platform_device *pdev) | |||
235 | 211 | ||
236 | /* activate */ | 212 | /* activate */ |
237 | return ata_host_activate(host, irq, irq ? ata_interrupt : NULL, | 213 | return ata_host_activate(host, irq, irq ? ata_interrupt : NULL, |
238 | pp_info ? pp_info->irq_flags : 0, | 214 | irq_flags, &pata_platform_sht); |
239 | &pata_platform_sht); | ||
240 | } | 215 | } |
216 | EXPORT_SYMBOL_GPL(__pata_platform_probe); | ||
241 | 217 | ||
242 | /** | 218 | /** |
243 | * pata_platform_remove - unplug a platform interface | 219 | * __pata_platform_remove - unplug a platform interface |
244 | * @pdev: platform device | 220 | * @dev: device |
245 | * | 221 | * |
246 | * A platform bus ATA device has been unplugged. Perform the needed | 222 | * A platform bus ATA device has been unplugged. Perform the needed |
247 | * cleanup. Also called on module unload for any active devices. | 223 | * cleanup. Also called on module unload for any active devices. |
248 | */ | 224 | */ |
249 | static int __devexit pata_platform_remove(struct platform_device *pdev) | 225 | int __devexit __pata_platform_remove(struct device *dev) |
250 | { | 226 | { |
251 | struct device *dev = &pdev->dev; | ||
252 | struct ata_host *host = dev_get_drvdata(dev); | 227 | struct ata_host *host = dev_get_drvdata(dev); |
253 | 228 | ||
254 | ata_host_detach(host); | 229 | ata_host_detach(host); |
255 | 230 | ||
256 | return 0; | 231 | return 0; |
257 | } | 232 | } |
233 | EXPORT_SYMBOL_GPL(__pata_platform_remove); | ||
234 | |||
235 | static int __devinit pata_platform_probe(struct platform_device *pdev) | ||
236 | { | ||
237 | struct resource *io_res; | ||
238 | struct resource *ctl_res; | ||
239 | struct resource *irq_res; | ||
240 | struct pata_platform_info *pp_info = pdev->dev.platform_data; | ||
241 | |||
242 | /* | ||
243 | * Simple resource validation .. | ||
244 | */ | ||
245 | if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) { | ||
246 | dev_err(&pdev->dev, "invalid number of resources\n"); | ||
247 | return -EINVAL; | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | * Get the I/O base first | ||
252 | */ | ||
253 | io_res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
254 | if (io_res == NULL) { | ||
255 | io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
256 | if (unlikely(io_res == NULL)) | ||
257 | return -EINVAL; | ||
258 | } | ||
259 | |||
260 | /* | ||
261 | * Then the CTL base | ||
262 | */ | ||
263 | ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1); | ||
264 | if (ctl_res == NULL) { | ||
265 | ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
266 | if (unlikely(ctl_res == NULL)) | ||
267 | return -EINVAL; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * And the IRQ | ||
272 | */ | ||
273 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
274 | if (irq_res) | ||
275 | irq_res->flags = pp_info ? pp_info->irq_flags : 0; | ||
276 | |||
277 | return __pata_platform_probe(&pdev->dev, io_res, ctl_res, irq_res, | ||
278 | pp_info ? pp_info->ioport_shift : 0, | ||
279 | pio_mask); | ||
280 | } | ||
281 | |||
282 | static int __devexit pata_platform_remove(struct platform_device *pdev) | ||
283 | { | ||
284 | return __pata_platform_remove(&pdev->dev); | ||
285 | } | ||
258 | 286 | ||
259 | static struct platform_driver pata_platform_driver = { | 287 | static struct platform_driver pata_platform_driver = { |
260 | .probe = pata_platform_probe, | 288 | .probe = pata_platform_probe, |
diff --git a/include/linux/pata_platform.h b/include/linux/pata_platform.h index 5799e8d50623..6a7a92db294c 100644 --- a/include/linux/pata_platform.h +++ b/include/linux/pata_platform.h | |||
@@ -15,4 +15,13 @@ struct pata_platform_info { | |||
15 | unsigned int irq_flags; | 15 | unsigned int irq_flags; |
16 | }; | 16 | }; |
17 | 17 | ||
18 | extern int __devinit __pata_platform_probe(struct device *dev, | ||
19 | struct resource *io_res, | ||
20 | struct resource *ctl_res, | ||
21 | struct resource *irq_res, | ||
22 | unsigned int ioport_shift, | ||
23 | int __pio_mask); | ||
24 | |||
25 | extern int __devexit __pata_platform_remove(struct device *dev); | ||
26 | |||
18 | #endif /* __LINUX_PATA_PLATFORM_H */ | 27 | #endif /* __LINUX_PATA_PLATFORM_H */ |