*
* To do:
*
- * - /proc/adb to list the devices and infos
+ * - /sys/bus/adb to list the devices and infos
* - more /dev/adb to allow userland to receive the
* flow of auto-polling datas from a given device.
* - move bus probe to a kernel thread
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/fs.h>
-#include <linux/devfs_fs_kernel.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
+#include <linux/device.h>
+#include <linux/devfs_fs_kernel.h>
+
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#ifdef CONFIG_PPC
#include <asm/prom.h>
+#include <asm/machdep.h>
#endif
NULL
};
+static struct class *adb_dev_class;
+
struct adb_driver *adb_controller;
-struct notifier_block *adb_client_list = NULL;
+BLOCKING_NOTIFIER_HEAD(adb_client_list);
static int adb_got_sleep;
static int adb_inited;
static pid_t adb_probe_task_pid;
static int autopoll_devs;
int __adb_probe_sync;
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
static int adb_notify_sleep(struct pmu_sleep_notifier *self, int when);
static struct pmu_sleep_notifier adb_sleep_notifier = {
adb_notify_sleep,
* called.
*/
static DECLARE_MUTEX(adb_handler_sem);
-static rwlock_t adb_handler_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(adb_handler_lock);
#if 0
static void printADBreply(struct adb_request *req)
static __inline__ void adb_wait_ms(unsigned int ms)
{
if (current->pid && adb_probe_task_pid &&
- adb_probe_task_pid == current->pid) {
- set_task_state(current, TASK_UNINTERRUPTIBLE);
- schedule_timeout(1 + ms * HZ / 1000);
- } else
+ adb_probe_task_pid == current->pid)
+ msleep(ms);
+ else
mdelay(ms);
}
int i;
#ifdef CONFIG_PPC32
- if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
+ if (!machine_is(chrp) && !machine_is(powermac))
return 0;
#endif
#ifdef CONFIG_MAC
printk(KERN_WARNING "Warning: no ADB interface detected\n");
adb_controller = NULL;
} else {
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
pmu_register_sleep_notifier(&adb_sleep_notifier);
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
#ifdef CONFIG_PPC
if (machine_is_compatible("AAPL,PowerBook1998") ||
machine_is_compatible("PowerBook1,1"))
__initcall(adb_init);
-#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_PM
/*
* notify clients before sleep and reset bus afterwards
*/
/* Stop autopoll */
if (adb_controller->autopoll)
adb_controller->autopoll(0);
- ret = notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL);
+ ret = blocking_notifier_call_chain(&adb_client_list,
+ ADB_MSG_POWERDOWN, NULL);
if (ret & NOTIFY_STOP_MASK) {
up(&adb_probe_mutex);
return PBOOK_SLEEP_REFUSE;
}
return PBOOK_SLEEP_OK;
}
-#endif /* CONFIG_PMAC_PBOOK */
+#endif /* CONFIG_PM */
static int
do_adb_reset_bus(void)
if (adb_controller->autopoll)
adb_controller->autopoll(0);
- nret = notifier_call_chain(&adb_client_list, ADB_MSG_PRE_RESET, NULL);
+ nret = blocking_notifier_call_chain(&adb_client_list,
+ ADB_MSG_PRE_RESET, NULL);
if (nret & NOTIFY_STOP_MASK) {
if (adb_controller->autopoll)
adb_controller->autopoll(autopoll_devs);
}
up(&adb_handler_sem);
- nret = notifier_call_chain(&adb_client_list, ADB_MSG_POST_RESET, NULL);
+ nret = blocking_notifier_call_chain(&adb_client_list,
+ ADB_MSG_POST_RESET, NULL);
if (nret & NOTIFY_STOP_MASK)
return -EBUSY;
write_lock_irq(&adb_handler_lock);
}
ret = 0;
- adb_handler[index].handler = 0;
+ adb_handler[index].handler = NULL;
}
write_unlock_irq(&adb_handler_lock);
up(&adb_handler_sem);
static ssize_t adb_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
- int ret;
+ int ret = 0;
struct adbdev_state *state = file->private_data;
struct adb_request *req;
wait_queue_t wait = __WAITQUEUE_INITIALIZER(wait,current);
return -EINVAL;
if (count > sizeof(req->reply))
count = sizeof(req->reply);
- ret = verify_area(VERIFY_WRITE, buf, count);
- if (ret)
- return ret;
+ if (!access_ok(VERIFY_WRITE, buf, count))
+ return -EFAULT;
req = NULL;
spin_lock_irqsave(&state->lock, flags);
return -EINVAL;
if (adb_controller == NULL)
return -ENXIO;
- ret = verify_area(VERIFY_READ, buf, count);
- if (ret)
- return ret;
+ if (!access_ok(VERIFY_READ, buf, count))
+ return -EFAULT;
req = (struct adb_request *) kmalloc(sizeof(struct adb_request),
GFP_KERNEL);
}
static struct file_operations adb_fops = {
+ .owner = THIS_MODULE,
.llseek = no_llseek,
.read = adb_read,
.write = adb_write,
static void
adbdev_init(void)
{
- if (register_chrdev(ADB_MAJOR, "adb", &adb_fops))
+ if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) {
printk(KERN_ERR "adb: unable to get major %d\n", ADB_MAJOR);
- else
- devfs_mk_cdev(MKDEV(ADB_MAJOR, 0),
- S_IFCHR | S_IRUSR | S_IWUSR, "adb");
+ return;
+ }
+
+ devfs_mk_cdev(MKDEV(ADB_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR, "adb");
+
+ adb_dev_class = class_create(THIS_MODULE, "adb");
+ if (IS_ERR(adb_dev_class))
+ return;
+ class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
}