Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

powerpc/powermac: Make auto-loading of therm_pm72 possible

The therm_pm72 driver, used on the PowerMac G5 range, cannot be
auto-loaded, since the driver itself creates both the device node
and the driver instance.

Moving the device node creation to the platform setup code and
adding the necessary MODULE_DEVICE_TABLE() information allows the
driver to be automatically loaded by udev on any semi-modern
distribution.

It "fixes" a major source of problem on G5 machines where the
driver wasn't explicitely loaded by default, and the system
would automatically shutdown under load.

Tested on an Xserve G5.

Signed-off-by: Marc Zyngier <maz@misterjones.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

authored by

Marc Zyngier and committed by
Benjamin Herrenschmidt
98b14d6b 982cf004

+14 -25
+9
arch/powerpc/platforms/powermac/setup.c
··· 506 506 of_platform_device_create(np, "smu", NULL); 507 507 of_node_put(np); 508 508 } 509 + np = of_find_node_by_type(NULL, "fcu"); 510 + if (np == NULL) { 511 + /* Some machines have strangely broken device-tree */ 512 + np = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/fan@15e"); 513 + } 514 + if (np) { 515 + of_platform_device_create(np, "temperature", NULL); 516 + of_node_put(np); 517 + } 509 518 510 519 return 0; 511 520 }
+5 -25
drivers/macintosh/therm_pm72.c
··· 2213 2213 static int fcu_of_probe(struct platform_device* dev, const struct of_device_id *match) 2214 2214 { 2215 2215 state = state_detached; 2216 + of_dev = dev; 2217 + 2218 + dev_info(&dev->dev, "PowerMac G5 Thermal control driver %s\n", VERSION); 2216 2219 2217 2220 /* Lookup the fans in the device tree */ 2218 2221 fcu_lookup_fans(dev->dev.of_node); ··· 2238 2235 }, 2239 2236 {}, 2240 2237 }; 2238 + MODULE_DEVICE_TABLE(of, fcu_match); 2241 2239 2242 2240 static struct of_platform_driver fcu_of_platform_driver = 2243 2241 { ··· 2256 2252 */ 2257 2253 static int __init therm_pm72_init(void) 2258 2254 { 2259 - struct device_node *np; 2260 - 2261 2255 rackmac = of_machine_is_compatible("RackMac3,1"); 2262 2256 2263 2257 if (!of_machine_is_compatible("PowerMac7,2") && ··· 2263 2261 !rackmac) 2264 2262 return -ENODEV; 2265 2263 2266 - printk(KERN_INFO "PowerMac G5 Thermal control driver %s\n", VERSION); 2267 - 2268 - np = of_find_node_by_type(NULL, "fcu"); 2269 - if (np == NULL) { 2270 - /* Some machines have strangely broken device-tree */ 2271 - np = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/fan@15e"); 2272 - if (np == NULL) { 2273 - printk(KERN_ERR "Can't find FCU in device-tree !\n"); 2274 - return -ENODEV; 2275 - } 2276 - } 2277 - of_dev = of_platform_device_create(np, "temperature", NULL); 2278 - if (of_dev == NULL) { 2279 - printk(KERN_ERR "Can't register FCU platform device !\n"); 2280 - return -ENODEV; 2281 - } 2282 - 2283 - of_register_platform_driver(&fcu_of_platform_driver); 2284 - 2285 - return 0; 2264 + return of_register_platform_driver(&fcu_of_platform_driver); 2286 2265 } 2287 2266 2288 2267 static void __exit therm_pm72_exit(void) 2289 2268 { 2290 2269 of_unregister_platform_driver(&fcu_of_platform_driver); 2291 - 2292 - if (of_dev) 2293 - of_device_unregister(of_dev); 2294 2270 } 2295 2271 2296 2272 module_init(therm_pm72_init);