diff options
| author | David S. Miller <davem@sunset.davemloft.net> | 2005-10-06 23:43:54 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2005-10-06 23:43:54 -0400 |
| commit | 2256c13b992b09f1f9563c26457aa048da2865df (patch) | |
| tree | a5a04b843b4c31c292e0570844b68c33fcfe9bc4 | |
| parent | edb4a3534adbaf90768d67da35f0bfeac4767db6 (diff) | |
[SPARC64]: Probe for power device on ISA bus too.
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | arch/sparc64/kernel/power.c | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/arch/sparc64/kernel/power.c b/arch/sparc64/kernel/power.c index 946cee0257ea..9e8362ea3104 100644 --- a/arch/sparc64/kernel/power.c +++ b/arch/sparc64/kernel/power.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | 17 | ||
| 18 | #include <asm/system.h> | 18 | #include <asm/system.h> |
| 19 | #include <asm/ebus.h> | 19 | #include <asm/ebus.h> |
| 20 | #include <asm/isa.h> | ||
| 20 | #include <asm/auxio.h> | 21 | #include <asm/auxio.h> |
| 21 | 22 | ||
| 22 | #include <linux/unistd.h> | 23 | #include <linux/unistd.h> |
| @@ -100,46 +101,83 @@ again: | |||
| 100 | return 0; | 101 | return 0; |
| 101 | } | 102 | } |
| 102 | 103 | ||
| 103 | static int __init has_button_interrupt(struct linux_ebus_device *edev) | 104 | static int __init has_button_interrupt(unsigned int irq, int prom_node) |
| 104 | { | 105 | { |
| 105 | if (edev->irqs[0] == PCI_IRQ_NONE) | 106 | if (irq == PCI_IRQ_NONE) |
| 106 | return 0; | 107 | return 0; |
| 107 | if (!prom_node_has_property(edev->prom_node, "button")) | 108 | if (!prom_node_has_property(prom_node, "button")) |
| 108 | return 0; | 109 | return 0; |
| 109 | 110 | ||
| 110 | return 1; | 111 | return 1; |
| 111 | } | 112 | } |
| 112 | 113 | ||
| 113 | void __init power_init(void) | 114 | static int __init power_probe_ebus(struct resource **resp, unsigned int *irq_p, int *prom_node_p) |
| 114 | { | 115 | { |
| 115 | struct linux_ebus *ebus; | 116 | struct linux_ebus *ebus; |
| 116 | struct linux_ebus_device *edev; | 117 | struct linux_ebus_device *edev; |
| 118 | |||
| 119 | for_each_ebus(ebus) { | ||
| 120 | for_each_ebusdev(edev, ebus) { | ||
| 121 | if (!strcmp(edev->prom_name, "power")) { | ||
| 122 | *resp = &edev->resource[0]; | ||
| 123 | *irq_p = edev->irqs[0]; | ||
| 124 | *prom_node_p = edev->prom_node; | ||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | } | ||
| 128 | } | ||
| 129 | return -ENODEV; | ||
| 130 | } | ||
| 131 | |||
| 132 | static int __init power_probe_isa(struct resource **resp, unsigned int *irq_p, int *prom_node_p) | ||
| 133 | { | ||
| 134 | struct sparc_isa_bridge *isa_bus; | ||
| 135 | struct sparc_isa_device *isa_dev; | ||
| 136 | |||
| 137 | for_each_isa(isa_bus) { | ||
| 138 | for_each_isadev(isa_dev, isa_bus) { | ||
| 139 | if (!strcmp(isa_dev->prom_name, "power")) { | ||
| 140 | *resp = &isa_dev->resource; | ||
| 141 | *irq_p = isa_dev->irq; | ||
| 142 | *prom_node_p = isa_dev->prom_node; | ||
| 143 | return 0; | ||
| 144 | } | ||
| 145 | } | ||
| 146 | } | ||
| 147 | return -ENODEV; | ||
| 148 | } | ||
| 149 | |||
| 150 | void __init power_init(void) | ||
| 151 | { | ||
| 152 | struct resource *res = NULL; | ||
| 153 | unsigned int irq; | ||
| 154 | int prom_node; | ||
| 117 | static int invoked; | 155 | static int invoked; |
| 118 | 156 | ||
| 119 | if (invoked) | 157 | if (invoked) |
| 120 | return; | 158 | return; |
| 121 | invoked = 1; | 159 | invoked = 1; |
| 122 | 160 | ||
| 123 | for_each_ebus(ebus) { | 161 | if (!power_probe_ebus(&res, &irq, &prom_node)) |
| 124 | for_each_ebusdev(edev, ebus) { | 162 | goto found; |
| 125 | if (!strcmp(edev->prom_name, "power")) | 163 | |
| 126 | goto found; | 164 | if (!power_probe_isa(&res, &irq, &prom_node)) |
| 127 | } | 165 | goto found; |
| 128 | } | 166 | |
| 129 | return; | 167 | return; |
| 130 | 168 | ||
| 131 | found: | 169 | found: |
| 132 | power_reg = ioremap(edev->resource[0].start, 0x4); | 170 | power_reg = ioremap(res->start, 0x4); |
| 133 | printk("power: Control reg at %p ... ", power_reg); | 171 | printk("power: Control reg at %p ... ", power_reg); |
| 134 | poweroff_method = machine_halt; /* able to use the standard halt */ | 172 | poweroff_method = machine_halt; /* able to use the standard halt */ |
| 135 | if (has_button_interrupt(edev)) { | 173 | if (has_button_interrupt(irq, prom_node)) { |
| 136 | if (kernel_thread(powerd, NULL, CLONE_FS) < 0) { | 174 | if (kernel_thread(powerd, NULL, CLONE_FS) < 0) { |
| 137 | printk("Failed to start power daemon.\n"); | 175 | printk("Failed to start power daemon.\n"); |
| 138 | return; | 176 | return; |
| 139 | } | 177 | } |
| 140 | printk("powerd running.\n"); | 178 | printk("powerd running.\n"); |
| 141 | 179 | ||
| 142 | if (request_irq(edev->irqs[0], | 180 | if (request_irq(irq, |
| 143 | power_handler, SA_SHIRQ, "power", NULL) < 0) | 181 | power_handler, SA_SHIRQ, "power", NULL) < 0) |
| 144 | printk("power: Error, cannot register IRQ handler.\n"); | 182 | printk("power: Error, cannot register IRQ handler.\n"); |
| 145 | } else { | 183 | } else { |
