sparcspkr.c revision a2bd4fd17926d715a470fbe0ebe05128ba410984
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Driver for PC-speaker like devices found on various Sparc systems. 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (c) 2002 Vojtech Pavlik 5a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller * Copyright (c) 2002, 2006 David S. Miller (davem@davemloft.net) 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/config.h> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/input.h> 12f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov#include <linux/platform_device.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/ebus.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/isa.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18a2bd4fd17926d715a470fbe0ebe05128ba410984David S. MillerMODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); 1976b7cddfd576331761e945a508254abad11039e9Dmitry TorokhovMODULE_DESCRIPTION("Sparc Speaker beeper driver"); 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Millerstruct sparcspkr_state { 23a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller const char *name; 24a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller unsigned long iobase; 25a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); 26a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller spinlock_t lock; 27a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller struct input_dev *input_dev; 28a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller}; 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 32a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int count = 0; 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (type != EV_SND) 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (code) { 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SND_BELL: if (value) value = 1000; 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SND_TONE: break; 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: return -1; 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (value > 20 && value < 32767) 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = 1193182 / value; 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller spin_lock_irqsave(&state->lock, flags); 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* EBUS speaker only has on/off state, the frequency does not 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * appear to be programmable. 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 53a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller if (state->iobase & 0x2UL) 54a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller outb(!!count, state->iobase); 55f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov else 56a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller outl(!!count, state->iobase); 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 58a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller spin_unlock_irqrestore(&state->lock, flags); 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 65a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int count = 0; 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (type != EV_SND) 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (code) { 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SND_BELL: if (value) value = 1000; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SND_TONE: break; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: return -1; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (value > 20 && value < 32767) 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds count = 1193182 / value; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 81a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller spin_lock_irqsave(&state->lock, flags); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (count) { 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* enable counter 2 */ 85a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller outb(inb(state->iobase + 0x61) | 3, state->iobase + 0x61); 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* set command for counter 2, 2 byte write */ 87a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller outb(0xB6, state->iobase + 0x43); 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* select desired HZ */ 89a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller outb(count & 0xff, state->iobase + 0x42); 90a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller outb((count >> 8) & 0xff, state->iobase + 0x42); 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* disable counter 2 */ 93a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller outb(inb_p(state->iobase + 0x61) & 0xFC, state->iobase + 0x61); 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 96a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller spin_unlock_irqrestore(&state->lock, flags); 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 101a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Millerstatic int __devinit sparcspkr_probe(struct device *dev) 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 103a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller struct sparcspkr_state *state = dev_get_drvdata(dev); 104f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov struct input_dev *input_dev; 105f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov int error; 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 107f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov input_dev = input_allocate_device(); 108f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov if (!input_dev) 10976b7cddfd576331761e945a508254abad11039e9Dmitry Torokhov return -ENOMEM; 11076b7cddfd576331761e945a508254abad11039e9Dmitry Torokhov 111a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller input_dev->name = state->name; 112f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov input_dev->phys = "sparc/input0"; 113f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov input_dev->id.bustype = BUS_ISA; 114f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov input_dev->id.vendor = 0x001f; 115f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov input_dev->id.product = 0x0001; 116f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov input_dev->id.version = 0x0100; 117a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller input_dev->cdev.dev = dev; 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 119f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov input_dev->evbit[0] = BIT(EV_SND); 120f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 122a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller input_dev->event = state->event; 123f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 124f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov error = input_register_device(input_dev); 125f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov if (error) { 126f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov input_free_device(input_dev); 127f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov return error; 128f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov } 129f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 130a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller state->input_dev = input_dev; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 134f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 135a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Millerstatic int __devexit sparcspkr_remove(struct of_device *dev) 136f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov{ 137a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); 138a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller struct input_dev *input_dev = state->input_dev; 139f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 140f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov /* turn off the speaker */ 141a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller state->event(input_dev, EV_SND, SND_BELL, 0); 142a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller 143a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller input_unregister_device(input_dev); 144a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller 145a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller dev_set_drvdata(&dev->dev, NULL); 146a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller kfree(state); 147f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 148f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov return 0; 149f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov} 150f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 151a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Millerstatic int sparcspkr_shutdown(struct of_device *dev) 152f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov{ 153a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); 154a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller struct input_dev *input_dev = state->input_dev; 155a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller 156f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov /* turn off the speaker */ 157a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller state->event(input_dev, EV_SND, SND_BELL, 0); 158a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller 159a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller return 0; 160a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller} 161a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller 162a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Millerstatic int __devinit ebus_beep_probe(struct of_device *dev, const struct of_device_id *match) 163a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller{ 164a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller struct linux_ebus_device *edev = to_ebus_device(&dev->dev); 165a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller struct sparcspkr_state *state; 166a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller int err; 167a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller 168a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller state = kzalloc(sizeof(*state), GFP_KERNEL); 169a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller if (!state) 170a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller return -ENOMEM; 171a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller 172a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller state->name = "Sparc EBUS Speaker"; 173a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller state->iobase = edev->resource[0].start; 174a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller state->event = ebus_spkr_event; 175a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller spin_lock_init(&state->lock); 176a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller 177a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller dev_set_drvdata(&dev->dev, state); 178a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller 179a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller err = sparcspkr_probe(&dev->dev); 180a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller if (err) { 181a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller dev_set_drvdata(&dev->dev, NULL); 182a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller kfree(state); 183a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller } 184a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller 185a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller return 0; 186f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov} 187f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 188a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Millerstatic struct of_device_id ebus_beep_match[] = { 189a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller { 190a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller .name = "beep", 191f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov }, 192a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller {}, 193f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov}; 194f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 195a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Millerstatic struct of_platform_driver ebus_beep_driver = { 196a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller .name = "beep", 197a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller .match_table = ebus_beep_match, 198a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller .probe = ebus_beep_probe, 199a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller .remove = sparcspkr_remove, 200a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller .shutdown = sparcspkr_shutdown, 201a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller}; 202f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 203a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Millerstatic int __devinit isa_beep_probe(struct of_device *dev, const struct of_device_id *match) 204f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov{ 205a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller struct sparc_isa_device *idev = to_isa_device(&dev->dev); 206a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller struct sparcspkr_state *state; 207a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller int err; 208f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 209a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller state = kzalloc(sizeof(*state), GFP_KERNEL); 210a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller if (!state) 211a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller return -ENOMEM; 212f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 213a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller state->name = "Sparc ISA Speaker"; 214a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller state->iobase = idev->resource.start; 215a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller state->event = isa_spkr_event; 216a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller spin_lock_init(&state->lock); 217a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller 218a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller dev_set_drvdata(&dev->dev, state); 219f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 220a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller err = sparcspkr_probe(&dev->dev); 221a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller if (err) { 222a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller dev_set_drvdata(&dev->dev, NULL); 223a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller kfree(state); 224a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller } 225f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 226f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov return 0; 227a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller} 228f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 229a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Millerstatic struct of_device_id isa_beep_match[] = { 230a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller { 231a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller .name = "dma", 232a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller }, 233a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller {}, 234a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller}; 235f5b64078d75528f36b78d30e945bb1b05cb05f26Dmitry Torokhov 236a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Millerstatic struct of_platform_driver isa_beep_driver = { 237a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller .name = "beep", 238a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller .match_table = isa_beep_match, 239a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller .probe = isa_beep_probe, 240a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller .remove = sparcspkr_remove, 241a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller .shutdown = sparcspkr_shutdown, 242a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller}; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init sparcspkr_init(void) 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 246a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller int err = of_register_driver(&ebus_beep_driver, &ebus_bus_type); 247a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller 248a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller if (!err) { 249a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller err = of_register_driver(&isa_beep_driver, &isa_bus_type); 250a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller if (err) 251a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller of_unregister_driver(&ebus_beep_driver); 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 254a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller return err; 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit sparcspkr_exit(void) 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 259a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller of_unregister_driver(&ebus_beep_driver); 260a2bd4fd17926d715a470fbe0ebe05128ba410984David S. Miller of_unregister_driver(&isa_beep_driver); 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(sparcspkr_init); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(sparcspkr_exit); 265