Commit 6b8c90f2 authored by David S. Miller's avatar David S. Miller

envctrl: Convert to pure OF driver.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 95d43905
/* $Id: envctrl.c,v 1.25 2002/01/15 09:01:26 davem Exp $ /* envctrl.c: Temperature and Fan monitoring on Machines providing it.
* envctrl.c: Temperature and Fan monitoring on Machines providing it.
* *
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 2000 Vinh Truong (vinh.truong@eng.sun.com) * Copyright (C) 2000 Vinh Truong (vinh.truong@eng.sun.com)
...@@ -28,12 +27,16 @@ ...@@ -28,12 +27,16 @@
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <asm/ebus.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/envctrl.h> #include <asm/envctrl.h>
#include <asm/io.h> #include <asm/io.h>
#define DRIVER_NAME "envctrl"
#define PFX DRIVER_NAME ": "
#define ENVCTRL_MINOR 162 #define ENVCTRL_MINOR 162
#define PCF8584_ADDRESS 0x55 #define PCF8584_ADDRESS 0x55
...@@ -193,7 +196,7 @@ static void envtrl_i2c_test_pin(void) ...@@ -193,7 +196,7 @@ static void envtrl_i2c_test_pin(void)
} }
if (limit <= 0) if (limit <= 0)
printk(KERN_INFO "envctrl: Pin status will not clear.\n"); printk(KERN_INFO PFX "Pin status will not clear.\n");
} }
/* Function Description: Test busy bit. /* Function Description: Test busy bit.
...@@ -211,7 +214,7 @@ static void envctrl_i2c_test_bb(void) ...@@ -211,7 +214,7 @@ static void envctrl_i2c_test_bb(void)
} }
if (limit <= 0) if (limit <= 0)
printk(KERN_INFO "envctrl: Busy bit will not clear.\n"); printk(KERN_INFO PFX "Busy bit will not clear.\n");
} }
/* Function Description: Send the address for a read access. /* Function Description: Send the address for a read access.
...@@ -858,11 +861,10 @@ static void envctrl_init_voltage_status(struct i2c_child_t *pchild) ...@@ -858,11 +861,10 @@ static void envctrl_init_voltage_status(struct i2c_child_t *pchild)
/* Function Description: Initialize i2c child device. /* Function Description: Initialize i2c child device.
* Return: None. * Return: None.
*/ */
static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, static void envctrl_init_i2c_child(struct device_node *dp,
struct i2c_child_t *pchild) struct i2c_child_t *pchild)
{ {
int len, i, tbls_size = 0; int len, i, tbls_size = 0;
struct device_node *dp = edev_child->prom_node;
const void *pval; const void *pval;
/* Get device address. */ /* Get device address. */
...@@ -882,12 +884,12 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child, ...@@ -882,12 +884,12 @@ static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child,
pchild->tables = kmalloc(tbls_size, GFP_KERNEL); pchild->tables = kmalloc(tbls_size, GFP_KERNEL);
if (pchild->tables == NULL){ if (pchild->tables == NULL){
printk("envctrl: Failed to allocate table.\n"); printk(KERN_ERR PFX "Failed to allocate table.\n");
return; return;
} }
pval = of_get_property(dp, "tables", &len); pval = of_get_property(dp, "tables", &len);
if (!pval || len <= 0) { if (!pval || len <= 0) {
printk("envctrl: Failed to get table.\n"); printk(KERN_ERR PFX "Failed to get table.\n");
return; return;
} }
memcpy(pchild->tables, pval, len); memcpy(pchild->tables, pval, len);
...@@ -993,14 +995,14 @@ static int kenvctrld(void *__unused) ...@@ -993,14 +995,14 @@ static int kenvctrld(void *__unused)
struct i2c_child_t *cputemp; struct i2c_child_t *cputemp;
if (NULL == (cputemp = envctrl_get_i2c_child(ENVCTRL_CPUTEMP_MON))) { if (NULL == (cputemp = envctrl_get_i2c_child(ENVCTRL_CPUTEMP_MON))) {
printk(KERN_ERR printk(KERN_ERR PFX
"envctrl: kenvctrld unable to monitor CPU temp-- exiting\n"); "kenvctrld unable to monitor CPU temp-- exiting\n");
return -ENODEV; return -ENODEV;
} }
poll_interval = 5000; /* TODO env_mon_interval */ poll_interval = 5000; /* TODO env_mon_interval */
printk(KERN_INFO "envctrl: %s starting...\n", current->comm); printk(KERN_INFO PFX "%s starting...\n", current->comm);
for (;;) { for (;;) {
msleep_interruptible(poll_interval); msleep_interruptible(poll_interval);
...@@ -1022,54 +1024,35 @@ static int kenvctrld(void *__unused) ...@@ -1022,54 +1024,35 @@ static int kenvctrld(void *__unused)
} }
} }
} }
printk(KERN_INFO "envctrl: %s exiting...\n", current->comm); printk(KERN_INFO PFX "%s exiting...\n", current->comm);
return 0; return 0;
} }
static int __init envctrl_init(void) static int __devinit envctrl_probe(struct of_device *op,
const struct of_device_id *match)
{ {
struct linux_ebus *ebus = NULL; struct device_node *dp;
struct linux_ebus_device *edev = NULL; int index, err;
struct linux_ebus_child *edev_child = NULL;
int err, i = 0;
for_each_ebus(ebus) {
for_each_ebusdev(edev, ebus) {
if (!strcmp(edev->prom_node->name, "bbc")) {
/* If we find a boot-bus controller node,
* then this envctrl driver is not for us.
*/
return -ENODEV;
}
}
}
/* Traverse through ebus and ebus device list for i2c device and if (i2c)
* adc and gpio nodes. return -EINVAL;
*/
for_each_ebus(ebus) { i2c = of_ioremap(&op->resource[0], 0, 0x2, DRIVER_NAME);
for_each_ebusdev(edev, ebus) { if (!i2c)
if (!strcmp(edev->prom_node->name, "i2c")) { return -ENOMEM;
i2c = ioremap(edev->resource[0].start, 0x2);
for_each_edevchild(edev, edev_child) { index = 0;
if (!strcmp("gpio", edev_child->prom_node->name)) { dp = op->node->child;
i2c_childlist[i].i2ctype = I2C_GPIO; while (dp) {
envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); if (!strcmp(dp->name, "gpio")) {
} i2c_childlist[index].i2ctype = I2C_GPIO;
if (!strcmp("adc", edev_child->prom_node->name)) { envctrl_init_i2c_child(dp, &(i2c_childlist[index++]));
i2c_childlist[i].i2ctype = I2C_ADC; } else if (!strcmp(dp->name, "adc")) {
envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++])); i2c_childlist[index].i2ctype = I2C_ADC;
} envctrl_init_i2c_child(dp, &(i2c_childlist[index++]));
}
goto done;
}
} }
}
done: dp = dp->sibling;
if (!edev) {
printk("envctrl: I2C device not found.\n");
return -ENODEV;
} }
/* Set device address. */ /* Set device address. */
...@@ -1087,7 +1070,7 @@ static int __init envctrl_init(void) ...@@ -1087,7 +1070,7 @@ static int __init envctrl_init(void)
/* Register the device as a minor miscellaneous device. */ /* Register the device as a minor miscellaneous device. */
err = misc_register(&envctrl_dev); err = misc_register(&envctrl_dev);
if (err) { if (err) {
printk("envctrl: Unable to get misc minor %d\n", printk(KERN_ERR PFX "Unable to get misc minor %d\n",
envctrl_dev.minor); envctrl_dev.minor);
goto out_iounmap; goto out_iounmap;
} }
...@@ -1096,12 +1079,12 @@ static int __init envctrl_init(void) ...@@ -1096,12 +1079,12 @@ static int __init envctrl_init(void)
* a next child device, so we decrement before reverse-traversal of * a next child device, so we decrement before reverse-traversal of
* child devices. * child devices.
*/ */
printk("envctrl: initialized "); printk(KERN_INFO PFX "Initialized ");
for (--i; i >= 0; --i) { for (--index; index >= 0; --index) {
printk("[%s 0x%lx]%s", printk("[%s 0x%lx]%s",
(I2C_ADC == i2c_childlist[i].i2ctype) ? ("adc") : (I2C_ADC == i2c_childlist[index].i2ctype) ? "adc" :
((I2C_GPIO == i2c_childlist[i].i2ctype) ? ("gpio") : ("unknown")), ((I2C_GPIO == i2c_childlist[index].i2ctype) ? "gpio" : "unknown"),
i2c_childlist[i].addr, (0 == i) ? ("\n") : (" ")); i2c_childlist[index].addr, (0 == index) ? "\n" : " ");
} }
kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld"); kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld");
...@@ -1115,26 +1098,54 @@ static int __init envctrl_init(void) ...@@ -1115,26 +1098,54 @@ static int __init envctrl_init(void)
out_deregister: out_deregister:
misc_deregister(&envctrl_dev); misc_deregister(&envctrl_dev);
out_iounmap: out_iounmap:
iounmap(i2c); of_iounmap(&op->resource[0], i2c, 0x2);
for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++) for (index = 0; index < ENVCTRL_MAX_CPU * 2; index++)
kfree(i2c_childlist[i].tables); kfree(i2c_childlist[index].tables);
return err; return err;
} }
static void __exit envctrl_cleanup(void) static int __devexit envctrl_remove(struct of_device *op)
{ {
int i; int index;
kthread_stop(kenvctrld_task); kthread_stop(kenvctrld_task);
iounmap(i2c); of_iounmap(&op->resource[0], i2c, 0x2);
misc_deregister(&envctrl_dev); misc_deregister(&envctrl_dev);
for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++) for (index = 0; index < ENVCTRL_MAX_CPU * 2; index++)
kfree(i2c_childlist[i].tables); kfree(i2c_childlist[index].tables);
return 0;
}
static struct of_device_id envctrl_match[] = {
{
.name = "i2c",
.compatible = "i2cpcf,8584",
},
{},
};
MODULE_DEVICE_TABLE(of, envctrl_match);
static struct of_platform_driver envctrl_driver = {
.name = DRIVER_NAME,
.match_table = envctrl_match,
.probe = envctrl_probe,
.remove = __devexit_p(envctrl_remove),
};
static int __init envctrl_init(void)
{
return of_register_driver(&envctrl_driver, &of_bus_type);
}
static void __exit envctrl_exit(void)
{
of_unregister_driver(&envctrl_driver);
} }
module_init(envctrl_init); module_init(envctrl_init);
module_exit(envctrl_cleanup); module_exit(envctrl_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment