diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-10 00:08:59 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-10 00:08:59 +0400 |
commit | 21a2cb565a74bf794d343ce22300c5f6c1568ae1 (patch) | |
tree | 5cf49d94bc8cc31a299417b8a362f0645b41c543 /drivers/misc | |
parent | c99516ca854770000c277b2680a15581c691e18c (diff) | |
parent | 2a5ac6f7a9c0a24adcf68e0dd634afbe083191c1 (diff) | |
download | linux-21a2cb565a74bf794d343ce22300c5f6c1568ae1.tar.xz |
Merge branch 'char-misc-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
* 'char-misc-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
isl29020: Remove a redundant semi-colon from return statement
BMP085: Remove redundant semi-colon from return statement
drivers:misc: ti-st: DEBUG uart, baud rate mods
drivers:misc: ti-st: flush UART upon fw failure
drivers:misc: ti-st: protect registrations
char_dev.c: fix up some whitespace errors
s390: tape_class.h: remove kobj_map.h inclusion
misc: ad525x_dpot: Add support for SPI module device table matching
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/ad525x_dpot-i2c.c | 10 | ||||
-rw-r--r-- | drivers/misc/ad525x_dpot-spi.c | 97 | ||||
-rw-r--r-- | drivers/misc/ad525x_dpot.c | 24 | ||||
-rw-r--r-- | drivers/misc/ad525x_dpot.h | 8 | ||||
-rw-r--r-- | drivers/misc/bmp085.c | 2 | ||||
-rw-r--r-- | drivers/misc/isl29020.c | 2 | ||||
-rw-r--r-- | drivers/misc/ti-st/st_core.c | 18 | ||||
-rw-r--r-- | drivers/misc/ti-st/st_kim.c | 84 |
8 files changed, 123 insertions, 122 deletions
diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index a39e0555df63..83adab69bfd4 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -1,7 +1,7 @@ /* * Driver for the Analog Devices digital potentiometers (I2C bus) * - * Copyright (C) 2010 Michael Hennerich, Analog Devices Inc. + * Copyright (C) 2010-2011 Michael Hennerich, Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -11,7 +11,6 @@ #include "ad525x_dpot.h" -/* ------------------------------------------------------------------------- */ /* I2C bus functions */ static int write_d8(void *client, u8 val) { @@ -60,18 +59,13 @@ static int __devinit ad_dpot_i2c_probe(struct i2c_client *client, .bops = &bops, }; - struct ad_dpot_id dpot_id = { - .name = (char *) &id->name, - .devid = id->driver_data, - }; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) { dev_err(&client->dev, "SMBUS Word Data not Supported\n"); return -EIO; } - return ad_dpot_probe(&client->dev, &bdata, &dpot_id); + return ad_dpot_probe(&client->dev, &bdata, id->driver_data, id->name); } static int __devexit ad_dpot_i2c_remove(struct i2c_client *client) diff --git a/drivers/misc/ad525x_dpot-spi.c b/drivers/misc/ad525x_dpot-spi.c index 7f9a55afe05d..822749e41fea 100644 --- a/drivers/misc/ad525x_dpot-spi.c +++ b/drivers/misc/ad525x_dpot-spi.c @@ -1,7 +1,7 @@ /* * Driver for the Analog Devices digital potentiometers (SPI bus) * - * Copyright (C) 2010 Michael Hennerich, Analog Devices Inc. + * Copyright (C) 2010-2011 Michael Hennerich, Analog Devices Inc. * * Licensed under the GPL-2 or later. */ @@ -11,40 +11,6 @@ #include "ad525x_dpot.h" -static const struct ad_dpot_id ad_dpot_spi_devlist[] = { - {.name = "ad5160", .devid = AD5160_ID}, - {.name = "ad5161", .devid = AD5161_ID}, - {.name = "ad5162", .devid = AD5162_ID}, - {.name = "ad5165", .devid = AD5165_ID}, - {.name = "ad5200", .devid = AD5200_ID}, - {.name = "ad5201", .devid = AD5201_ID}, - {.name = "ad5203", .devid = AD5203_ID}, - {.name = "ad5204", .devid = AD5204_ID}, - {.name = "ad5206", .devid = AD5206_ID}, - {.name = "ad5207", .devid = AD5207_ID}, - {.name = "ad5231", .devid = AD5231_ID}, - {.name = "ad5232", .devid = AD5232_ID}, - {.name = "ad5233", .devid = AD5233_ID}, - {.name = "ad5235", .devid = AD5235_ID}, - {.name = "ad5260", .devid = AD5260_ID}, - {.name = "ad5262", .devid = AD5262_ID}, - {.name = "ad5263", .devid = AD5263_ID}, - {.name = "ad5290", .devid = AD5290_ID}, - {.name = "ad5291", .devid = AD5291_ID}, - {.name = "ad5292", .devid = AD5292_ID}, - {.name = "ad5293", .devid = AD5293_ID}, - {.name = "ad7376", .devid = AD7376_ID}, - {.name = "ad8400", .devid = AD8400_ID}, - {.name = "ad8402", .devid = AD8402_ID}, - {.name = "ad8403", .devid = AD8403_ID}, - {.name = "adn2850", .devid = ADN2850_ID}, - {.name = "ad5270", .devid = AD5270_ID}, - {.name = "ad5271", .devid = AD5271_ID}, - {} -}; - -/* ------------------------------------------------------------------------- */ - /* SPI bus functions */ static int write8(void *client, u8 val) { @@ -109,36 +75,16 @@ static const struct ad_dpot_bus_ops bops = { .write_r8d8 = write16, .write_r8d16 = write24, }; - -static const struct ad_dpot_id *dpot_match_id(const struct ad_dpot_id *id, - char *name) -{ - while (id->name && id->name[0]) { - if (strcmp(name, id->name) == 0) - return id; - id++; - } - return NULL; -} - static int __devinit ad_dpot_spi_probe(struct spi_device *spi) { - char *name = spi->dev.platform_data; - const struct ad_dpot_id *dpot_id; - struct ad_dpot_bus_data bdata = { .client = spi, .bops = &bops, }; - dpot_id = dpot_match_id(ad_dpot_spi_devlist, name); - - if (dpot_id == NULL) { - dev_err(&spi->dev, "%s not in supported device list", name); - return -ENODEV; - } - - return ad_dpot_probe(&spi->dev, &bdata, dpot_id); + return ad_dpot_probe(&spi->dev, &bdata, + spi_get_device_id(spi)->driver_data, + spi_get_device_id(spi)->name); } static int __devexit ad_dpot_spi_remove(struct spi_device *spi) @@ -146,14 +92,47 @@ static int __devexit ad_dpot_spi_remove(struct spi_device *spi) return ad_dpot_remove(&spi->dev); } +static const struct spi_device_id ad_dpot_spi_id[] = { + {"ad5160", AD5160_ID}, + {"ad5161", AD5161_ID}, + {"ad5162", AD5162_ID}, + {"ad5165", AD5165_ID}, + {"ad5200", AD5200_ID}, + {"ad5201", AD5201_ID}, + {"ad5203", AD5203_ID}, + {"ad5204", AD5204_ID}, + {"ad5206", AD5206_ID}, + {"ad5207", AD5207_ID}, + {"ad5231", AD5231_ID}, + {"ad5232", AD5232_ID}, + {"ad5233", AD5233_ID}, + {"ad5235", AD5235_ID}, + {"ad5260", AD5260_ID}, + {"ad5262", AD5262_ID}, + {"ad5263", AD5263_ID}, + {"ad5290", AD5290_ID}, + {"ad5291", AD5291_ID}, + {"ad5292", AD5292_ID}, + {"ad5293", AD5293_ID}, + {"ad7376", AD7376_ID}, + {"ad8400", AD8400_ID}, + {"ad8402", AD8402_ID}, + {"ad8403", AD8403_ID}, + {"adn2850", ADN2850_ID}, + {"ad5270", AD5270_ID}, + {"ad5271", AD5271_ID}, + {} +}; +MODULE_DEVICE_TABLE(spi, ad_dpot_spi_id); + static struct spi_driver ad_dpot_spi_driver = { .driver = { .name = "ad_dpot", - .bus = &spi_bus_type, .owner = THIS_MODULE, }, .probe = ad_dpot_spi_probe, .remove = __devexit_p(ad_dpot_spi_remove), + .id_table = ad_dpot_spi_id, }; static int __init ad_dpot_spi_init(void) diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index 7cb911028d09..1d1d42615915 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -64,7 +64,7 @@ * Author: Chris Verges <chrisv@cyberswitching.com> * * derived from ad5252.c - * Copyright (c) 2006 Michael Hennerich <hennerich@blackfin.uclinux.org> + * Copyright (c) 2006-2011 Michael Hennerich <hennerich@blackfin.uclinux.org> * * Licensed under the GPL-2 or later. */ @@ -76,8 +76,6 @@ #include <linux/delay.h> #include <linux/slab.h> -#define DRIVER_VERSION "0.2" - #include "ad525x_dpot.h" /* @@ -687,8 +685,9 @@ inline void ad_dpot_remove_files(struct device *dev, } } -__devinit int ad_dpot_probe(struct device *dev, - struct ad_dpot_bus_data *bdata, const struct ad_dpot_id *id) +int __devinit ad_dpot_probe(struct device *dev, + struct ad_dpot_bus_data *bdata, unsigned long devid, + const char *name) { struct dpot_data *data; @@ -704,13 +703,13 @@ __devinit int ad_dpot_probe(struct device *dev, mutex_init(&data->update_lock); data->bdata = *bdata; - data->devid = id->devid; + data->devid = devid; - data->max_pos = 1 << DPOT_MAX_POS(data->devid); + data->max_pos = 1 << DPOT_MAX_POS(devid); data->rdac_mask = data->max_pos - 1; - data->feat = DPOT_FEAT(data->devid); - data->uid = DPOT_UID(data->devid); - data->wipers = DPOT_WIPERS(data->devid); + data->feat = DPOT_FEAT(devid); + data->uid = DPOT_UID(devid); + data->wipers = DPOT_WIPERS(devid); for (i = DPOT_RDAC0; i < MAX_RDACS; i++) if (data->wipers & (1 << i)) { @@ -731,7 +730,7 @@ __devinit int ad_dpot_probe(struct device *dev, } dev_info(dev, "%s %d-Position Digital Potentiometer registered\n", - id->name, data->max_pos); + name, data->max_pos); return 0; @@ -745,7 +744,7 @@ exit_free: dev_set_drvdata(dev, NULL); exit: dev_err(dev, "failed to create client for %s ID 0x%lX\n", - id->name, id->devid); + name, devid); return err; } EXPORT_SYMBOL(ad_dpot_probe); @@ -770,4 +769,3 @@ MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>, " "Michael Hennerich <hennerich@blackfin.uclinux.org>"); MODULE_DESCRIPTION("Digital potentiometer driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(DRIVER_VERSION); diff --git a/drivers/misc/ad525x_dpot.h b/drivers/misc/ad525x_dpot.h index 82b2cb77ae19..6bd1eba23bc0 100644 --- a/drivers/misc/ad525x_dpot.h +++ b/drivers/misc/ad525x_dpot.h @@ -208,12 +208,8 @@ struct ad_dpot_bus_data { const struct ad_dpot_bus_ops *bops; }; -struct ad_dpot_id { - char *name; - unsigned long devid; -}; - -int ad_dpot_probe(struct device *dev, struct ad_dpot_bus_data *bdata, const struct ad_dpot_id *id); +int ad_dpot_probe(struct device *dev, struct ad_dpot_bus_data *bdata, + unsigned long devid, const char *name); int ad_dpot_remove(struct device *dev); #endif diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c index 5f898cb706a6..b29a2be24591 100644 --- a/drivers/misc/bmp085.c +++ b/drivers/misc/bmp085.c @@ -216,7 +216,7 @@ static s32 bmp085_get_temperature(struct bmp085_data *data, int *temperature) *temperature = (x1+x2+8) >> 4; exit: - return status;; + return status; } /* diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index 307aada5fffe..3d6cce663bea 100644 --- a/drivers/misc/isl29020.c +++ b/drivers/misc/isl29020.c @@ -158,7 +158,7 @@ static int als_set_default_config(struct i2c_client *client) dev_err(&client->dev, "default write failed."); return retval; } - return 0;; + return 0; } static int isl29020_probe(struct i2c_client *client, diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index ba168a7d54d4..2b62232c2c6a 100644 --- a/drivers/misc/ti-st/st_core.c +++ b/drivers/misc/ti-st/st_core.c @@ -137,6 +137,8 @@ void st_send_frame(unsigned char chnl_id, struct st_data_s *st_gdata) * st_reg_complete - * to call registration complete callbacks * of all protocol stack drivers + * This function is being called with spin lock held, protocol drivers are + * only expected to complete their waits and do nothing more than that. */ void st_reg_complete(struct st_data_s *st_gdata, char err) { @@ -538,11 +540,12 @@ long st_register(struct st_proto_s *new_proto) set_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); st_recv = st_kim_recv; + /* enable the ST LL - to set default chip state */ + st_ll_enable(st_gdata); + /* release lock previously held - re-locked below */ spin_unlock_irqrestore(&st_gdata->lock, flags); - /* enable the ST LL - to set default chip state */ - st_ll_enable(st_gdata); /* this may take a while to complete * since it involves BT fw download */ @@ -553,10 +556,13 @@ long st_register(struct st_proto_s *new_proto) (test_bit(ST_REG_PENDING, &st_gdata->st_state))) { pr_err(" KIM failure complete callback "); st_reg_complete(st_gdata, err); + clear_bit(ST_REG_PENDING, &st_gdata->st_state); } return -EINVAL; } + spin_lock_irqsave(&st_gdata->lock, flags); + clear_bit(ST_REG_IN_PROGRESS, &st_gdata->st_state); st_recv = st_int_recv; @@ -576,10 +582,10 @@ long st_register(struct st_proto_s *new_proto) if (st_gdata->is_registered[new_proto->chnl_id] == true) { pr_err(" proto %d already registered ", new_proto->chnl_id); + spin_unlock_irqrestore(&st_gdata->lock, flags); return -EALREADY; } - spin_lock_irqsave(&st_gdata->lock, flags); add_channel_to_table(st_gdata, new_proto); st_gdata->protos_registered++; new_proto->write = st_write; @@ -619,7 +625,7 @@ long st_unregister(struct st_proto_s *proto) spin_lock_irqsave(&st_gdata->lock, flags); - if (st_gdata->list[proto->chnl_id] == NULL) { + if (st_gdata->is_registered[proto->chnl_id] == false) { pr_err(" chnl_id %d not registered", proto->chnl_id); spin_unlock_irqrestore(&st_gdata->lock, flags); return -EPROTONOSUPPORT; @@ -629,6 +635,10 @@ long st_unregister(struct st_proto_s *proto) remove_channel_from_table(st_gdata, proto); spin_unlock_irqrestore(&st_gdata->lock, flags); + /* paranoid check */ + if (st_gdata->protos_registered < ST_EMPTY) + st_gdata->protos_registered = ST_EMPTY; + if ((st_gdata->protos_registered == ST_EMPTY) && (!test_bit(ST_REG_PENDING, &st_gdata->st_state))) { pr_info(" all chnl_ids unregistered "); diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 43ef8d162f2d..a7a861ceee2d 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -469,37 +469,21 @@ long st_kim_start(void *kim_data) /* wait for ldisc to be installed */ err = wait_for_completion_timeout(&kim_gdata->ldisc_installed, msecs_to_jiffies(LDISC_TIME)); - if (!err) { /* timeout */ - pr_err("line disc installation timed out "); - kim_gdata->ldisc_install = 0; - pr_info("ldisc_install = 0"); - sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, - NULL, "install"); - /* the following wait is never going to be completed, - * since the ldisc was never installed, hence serving - * as a mdelay of LDISC_TIME msecs */ - err = wait_for_completion_timeout - (&kim_gdata->ldisc_installed, - msecs_to_jiffies(LDISC_TIME)); - err = -ETIMEDOUT; + if (!err) { + /* ldisc installation timeout, + * flush uart, power cycle BT_EN */ + pr_err("ldisc installation timeout"); + err = st_kim_stop(kim_gdata); continue; } else { /* ldisc installed now */ - pr_info(" line discipline installed "); + pr_info("line discipline installed"); err = download_firmware(kim_gdata); if (err != 0) { + /* ldisc installed but fw download failed, + * flush uart & power cycle BT_EN */ pr_err("download firmware failed"); - kim_gdata->ldisc_install = 0; - pr_info("ldisc_install = 0"); - sysfs_notify(&kim_gdata->kim_pdev->dev.kobj, - NULL, "install"); - /* this wait might be completed, though in the - * tty_close() since the ldisc is already - * installed */ - err = wait_for_completion_timeout - (&kim_gdata->ldisc_installed, - msecs_to_jiffies(LDISC_TIME)); - err = -EINVAL; + err = st_kim_stop(kim_gdata); continue; } else { /* on success don't retry */ break; @@ -510,8 +494,14 @@ long st_kim_start(void *kim_data) } /** - * st_kim_stop - called from ST Core, on the last un-registration - * toggle low the chip enable gpio + * st_kim_stop - stop communication with chip. + * This can be called from ST Core/KIM, on the- + * (a) last un-register when chip need not be powered there-after, + * (b) upon failure to either install ldisc or download firmware. + * The function is responsible to (a) notify UIM about un-installation, + * (b) flush UART if the ldisc was installed. + * (c) reset BT_EN - pull down nshutdown at the end. + * (d) invoke platform's chip disabling routine. */ long st_kim_stop(void *kim_data) { @@ -519,12 +509,16 @@ long st_kim_stop(void *kim_data) struct kim_data_s *kim_gdata = (struct kim_data_s *)kim_data; struct ti_st_plat_data *pdata = kim_gdata->kim_pdev->dev.platform_data; + struct tty_struct *tty = kim_gdata->core_data->tty; INIT_COMPLETION(kim_gdata->ldisc_installed); - /* Flush any pending characters in the driver and discipline. */ - tty_ldisc_flush(kim_gdata->core_data->tty); - tty_driver_flush_buffer(kim_gdata->core_data->tty); + if (tty) { /* can be called before ldisc is installed */ + /* Flush any pending characters in the driver and discipline. */ + tty_ldisc_flush(tty); + tty_driver_flush_buffer(tty); + tty->ops->flush_buffer(tty); + } /* send uninstall notification to UIM */ pr_info("ldisc_install = 0"); @@ -579,6 +573,28 @@ static ssize_t show_install(struct device *dev, return sprintf(buf, "%d\n", kim_data->ldisc_install); } +#ifdef DEBUG +static ssize_t store_dev_name(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct kim_data_s *kim_data = dev_get_drvdata(dev); + pr_debug("storing dev name >%s<", buf); + strncpy(kim_data->dev_name, buf, count); + pr_debug("stored dev name >%s<", kim_data->dev_name); + return count; +} + +static ssize_t store_baud_rate(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct kim_data_s *kim_data = dev_get_drvdata(dev); + pr_debug("storing baud rate >%s<", buf); + sscanf(buf, "%ld", &kim_data->baud_rate); + pr_debug("stored baud rate >%ld<", kim_data->baud_rate); + return count; +} +#endif /* if DEBUG */ + static ssize_t show_dev_name(struct device *dev, struct device_attribute *attr, char *buf) { @@ -605,10 +621,18 @@ static struct kobj_attribute ldisc_install = __ATTR(install, 0444, (void *)show_install, NULL); static struct kobj_attribute uart_dev_name = +#ifdef DEBUG /* TODO: move this to debug-fs if possible */ +__ATTR(dev_name, 0644, (void *)show_dev_name, (void *)store_dev_name); +#else __ATTR(dev_name, 0444, (void *)show_dev_name, NULL); +#endif static struct kobj_attribute uart_baud_rate = +#ifdef DEBUG /* TODO: move to debugfs */ +__ATTR(baud_rate, 0644, (void *)show_baud_rate, (void *)store_baud_rate); +#else __ATTR(baud_rate, 0444, (void *)show_baud_rate, NULL); +#endif static struct kobj_attribute uart_flow_cntrl = __ATTR(flow_cntrl, 0444, (void *)show_flow_cntrl, NULL); |