From 7f3379de9cd91e52c40a48b8c01ebdb2d2eec5cf Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 18 Nov 2011 11:05:11 +0100 Subject: misc: ad525x_dpot: Add support for SPI module device table matching Passing device name via platform data, is a leftover from times where SPI module device table matching was not existent. * Add id_table and remove old mechanism. (To my knowledge no intree boards affected) * Miscellaneous other cleanup. Signed-off-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ad525x_dpot-i2c.c | 10 +---- drivers/misc/ad525x_dpot-spi.c | 97 +++++++++++++++++------------------------- drivers/misc/ad525x_dpot.c | 24 +++++------ drivers/misc/ad525x_dpot.h | 8 +--- 4 files changed, 53 insertions(+), 86 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index a39e0555df6..83adab69bfd 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 7f9a55afe05..822749e41fe 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 7cb911028d0..1d1d4261591 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -64,7 +64,7 @@ * Author: Chris Verges * * derived from ad5252.c - * Copyright (c) 2006 Michael Hennerich + * Copyright (c) 2006-2011 Michael Hennerich * * Licensed under the GPL-2 or later. */ @@ -76,8 +76,6 @@ #include #include -#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 , " "Michael Hennerich "); 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 a662f5987b6..3bea1d5e877 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 -- cgit v1.2.3-70-g09d2 From bfb88d6c91a2cf507ff7763ebec94d72b4c98b07 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 15 Dec 2011 10:38:20 -0600 Subject: drivers:misc: ti-st: protect registrations Concurrent access to UART2/combo-interface by multiple protocol drivers such as BT, FM and GPS caused issues during firmware download failure cases or cases when the firmware download took longer than usual. This was because of un-safe access to protos_registered & st_states. Protecting this will also make the registration complete callback un-safe for sleep. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_core.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/ti-st/st_core.c b/drivers/misc/ti-st/st_core.c index ba168a7d54d..2b62232c2c6 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 "); -- cgit v1.2.3-70-g09d2 From 18ccecf99aa22bd0938893614ce3dceca39d98e2 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 15 Dec 2011 10:38:21 -0600 Subject: drivers:misc: ti-st: flush UART upon fw failure Upon failure to read firmware version from chip or upon failure in responses to firmware download the UART needs to be flushed of its existing buffers so that the UIM can restart UART properly. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_kim.c | 54 ++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 30 deletions(-) (limited to 'drivers/misc') diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index 43ef8d162f2..bc8a5718c0d 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"); -- cgit v1.2.3-70-g09d2 From 933aae54bea7d032023a59e0b3261b612f8065e0 Mon Sep 17 00:00:00 2001 From: Pavan Savoy Date: Thu, 15 Dec 2011 10:38:22 -0600 Subject: drivers:misc: ti-st: DEBUG uart, baud rate mods To debug different UARTs at different baud-rates connected to the WiLink connectivity combo-chipset, this patch enables the debugging code so that upon boot different UARTs at different baud-rates can be tried out to verify the interface with WiLink. Signed-off-by: Pavan Savoy Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ti-st/st_kim.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers/misc') diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index bc8a5718c0d..a7a861ceee2 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -573,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) { @@ -599,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); -- cgit v1.2.3-70-g09d2 From f80ea66808b45d19abeb66db936b8f797a2628ff Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 17 Dec 2011 23:52:27 +0100 Subject: BMP085: Remove redundant semi-colon from return statement Just a single ";" will do nicely. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/misc/bmp085.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/bmp085.c b/drivers/misc/bmp085.c index 5f898cb706a..b29a2be2459 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; } /* -- cgit v1.2.3-70-g09d2 From 2a5ac6f7a9c0a24adcf68e0dd634afbe083191c1 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 17 Dec 2011 23:53:52 +0100 Subject: isl29020: Remove a redundant semi-colon from return statement One is enough. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/misc/isl29020.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/misc') diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index 307aada5fff..3d6cce663be 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, -- cgit v1.2.3-70-g09d2