diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-31 17:46:07 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-31 17:46:07 -0700 |
commit | 094803e0aab3fe75bbf8202a8f4b5280eaade375 (patch) | |
tree | 278528ca9245a767fcfcfa97d977bd5714c082fd /drivers | |
parent | 32087d4eeca14b82660dab288b1d659963b954bd (diff) | |
parent | d8805e633e054c816c47cb6e727c81f156d9253d (diff) |
Merge branch 'akpm' (Andrew's incoming)
Quoth Andrew:
- Most of MM. Still waiting for the poweroc guys to get off their
butts and review some threaded hugepages patches.
- alpha
- vfs bits
- drivers/misc
- a few core kerenl tweaks
- printk() features
- MAINTAINERS updates
- backlight merge
- leds merge
- various lib/ updates
- checkpatch updates
* akpm: (127 commits)
epoll: fix spurious lockdep warnings
checkpatch: add a --strict check for utf-8 in commit logs
kernel.h/checkpatch: mark strict_strto<foo> and simple_strto<foo> as obsolete
llist-return-whether-list-is-empty-before-adding-in-llist_add-fix
wireless: at76c50x: follow rename pack_hex_byte to hex_byte_pack
fat: follow rename pack_hex_byte() to hex_byte_pack()
security: follow rename pack_hex_byte() to hex_byte_pack()
kgdb: follow rename pack_hex_byte() to hex_byte_pack()
lib: rename pack_hex_byte() to hex_byte_pack()
lib/string.c: fix strim() semantics for strings that have only blanks
lib/idr.c: fix comment for ida_get_new_above()
lib/percpu_counter.c: enclose hotplug only variables in hotplug ifdef
lib/bitmap.c: quiet sparse noise about address space
lib/spinlock_debug.c: print owner on spinlock lockup
lib/kstrtox: common code between kstrto*() and simple_strto*() functions
drivers/leds/leds-lp5521.c: check if reset is successful
leds: turn the blink_timer off before starting to blink
leds: save the delay values after a successful call to blink_set()
drivers/leds/leds-gpio.c: use gpio_get_value_cansleep() when initializing
drivers/leds/leds-lm3530.c: add __devexit_p where needed
...
Diffstat (limited to 'drivers')
36 files changed, 738 insertions, 368 deletions
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index a61e7815a2a..6460487e41b 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -27,8 +27,7 @@ static struct class *hwmon_class; -static DEFINE_IDR(hwmon_idr); -static DEFINE_SPINLOCK(idr_lock); +static DEFINE_IDA(hwmon_ida); /** * hwmon_device_register - register w/ hwmon @@ -42,30 +41,17 @@ static DEFINE_SPINLOCK(idr_lock); struct device *hwmon_device_register(struct device *dev) { struct device *hwdev; - int id, err; - -again: - if (unlikely(idr_pre_get(&hwmon_idr, GFP_KERNEL) == 0)) - return ERR_PTR(-ENOMEM); - - spin_lock(&idr_lock); - err = idr_get_new(&hwmon_idr, NULL, &id); - spin_unlock(&idr_lock); + int id; - if (unlikely(err == -EAGAIN)) - goto again; - else if (unlikely(err)) - return ERR_PTR(err); + id = ida_simple_get(&hwmon_ida, 0, 0, GFP_KERNEL); + if (id < 0) + return ERR_PTR(id); - id = id & MAX_ID_MASK; hwdev = device_create(hwmon_class, dev, MKDEV(0, 0), NULL, HWMON_ID_FORMAT, id); - if (IS_ERR(hwdev)) { - spin_lock(&idr_lock); - idr_remove(&hwmon_idr, id); - spin_unlock(&idr_lock); - } + if (IS_ERR(hwdev)) + ida_simple_remove(&hwmon_ida, id); return hwdev; } @@ -81,9 +67,7 @@ void hwmon_device_unregister(struct device *dev) if (likely(sscanf(dev_name(dev), HWMON_ID_FORMAT, &id) == 1)) { device_unregister(dev); - spin_lock(&idr_lock); - idr_remove(&hwmon_idr, id); - spin_unlock(&idr_lock); + ida_simple_remove(&hwmon_ida, id); } else dev_dbg(dev->parent, "hwmon_device_unregister() failed: bad class ID!\n"); diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index c316294c48b..783d0c17b76 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c @@ -88,8 +88,7 @@ #define AEM_MIN_POWER_INTERVAL 200 #define UJ_PER_MJ 1000L -static DEFINE_IDR(aem_idr); -static DEFINE_SPINLOCK(aem_idr_lock); +static DEFINE_IDA(aem_ida); static struct platform_driver aem_driver = { .driver = { @@ -356,38 +355,6 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) complete(&data->read_complete); } -/* ID functions */ - -/* Obtain an id */ -static int aem_idr_get(int *id) -{ - int i, err; - -again: - if (unlikely(!idr_pre_get(&aem_idr, GFP_KERNEL))) - return -ENOMEM; - - spin_lock(&aem_idr_lock); - err = idr_get_new(&aem_idr, NULL, &i); - spin_unlock(&aem_idr_lock); - - if (unlikely(err == -EAGAIN)) - goto again; - else if (unlikely(err)) - return err; - - *id = i & MAX_ID_MASK; - return 0; -} - -/* Release an object ID */ -static void aem_idr_put(int id) -{ - spin_lock(&aem_idr_lock); - idr_remove(&aem_idr, id); - spin_unlock(&aem_idr_lock); -} - /* Sensor support functions */ /* Read a sensor value */ @@ -530,7 +497,7 @@ static void aem_delete(struct aem_data *data) ipmi_destroy_user(data->ipmi.user); platform_set_drvdata(data->pdev, NULL); platform_device_unregister(data->pdev); - aem_idr_put(data->id); + ida_simple_remove(&aem_ida, data->id); kfree(data); } @@ -587,7 +554,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; /* Create sub-device for this fw instance */ - if (aem_idr_get(&data->id)) + data->id = ida_simple_get(&aem_ida, 0, 0, GFP_KERNEL); + if (data->id < 0) goto id_err; data->pdev = platform_device_alloc(DRVNAME, data->id); @@ -638,7 +606,7 @@ ipmi_err: platform_set_drvdata(data->pdev, NULL); platform_device_unregister(data->pdev); dev_err: - aem_idr_put(data->id); + ida_simple_remove(&aem_ida, data->id); id_err: kfree(data); @@ -720,7 +688,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; /* Create sub-device for this fw instance */ - if (aem_idr_get(&data->id)) + data->id = ida_simple_get(&aem_ida, 0, 0, GFP_KERNEL); + if (data->id < 0) goto id_err; data->pdev = platform_device_alloc(DRVNAME, data->id); @@ -771,7 +740,7 @@ ipmi_err: platform_set_drvdata(data->pdev, NULL); platform_device_unregister(data->pdev); dev_err: - aem_idr_put(data->id); + ida_simple_remove(&aem_ida, data->id); id_err: kfree(data); diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index b645e558876..9155f91d66b 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -136,7 +136,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, down_write(¤t->mm->mmap_sem); - locked = npages + current->mm->locked_vm; + locked = npages + current->mm->pinned_vm; lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) { @@ -206,7 +206,7 @@ out: __ib_umem_release(context->device, umem, 0); kfree(umem); } else - current->mm->locked_vm = locked; + current->mm->pinned_vm = locked; up_write(¤t->mm->mmap_sem); if (vma_list) @@ -222,7 +222,7 @@ static void ib_umem_account(struct work_struct *work) struct ib_umem *umem = container_of(work, struct ib_umem, work); down_write(&umem->mm->mmap_sem); - umem->mm->locked_vm -= umem->diff; + umem->mm->pinned_vm -= umem->diff; up_write(&umem->mm->mmap_sem); mmput(umem->mm); kfree(umem); diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c index cfed5399f07..dc66c450691 100644 --- a/drivers/infiniband/hw/ipath/ipath_user_pages.c +++ b/drivers/infiniband/hw/ipath/ipath_user_pages.c @@ -79,7 +79,7 @@ static int __ipath_get_user_pages(unsigned long start_page, size_t num_pages, goto bail_release; } - current->mm->locked_vm += num_pages; + current->mm->pinned_vm += num_pages; ret = 0; goto bail; @@ -178,7 +178,7 @@ void ipath_release_user_pages(struct page **p, size_t num_pages) __ipath_release_user_pages(p, num_pages, 1); - current->mm->locked_vm -= num_pages; + current->mm->pinned_vm -= num_pages; up_write(¤t->mm->mmap_sem); } @@ -195,7 +195,7 @@ static void user_pages_account(struct work_struct *_work) container_of(_work, struct ipath_user_pages_work, work); down_write(&work->mm->mmap_sem); - work->mm->locked_vm -= work->num_pages; + work->mm->pinned_vm -= work->num_pages; up_write(&work->mm->mmap_sem); mmput(work->mm); kfree(work); diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c index 7689e49c13c..2bc1d2b9629 100644 --- a/drivers/infiniband/hw/qib/qib_user_pages.c +++ b/drivers/infiniband/hw/qib/qib_user_pages.c @@ -74,7 +74,7 @@ static int __qib_get_user_pages(unsigned long start_page, size_t num_pages, goto bail_release; } - current->mm->locked_vm += num_pages; + current->mm->pinned_vm += num_pages; ret = 0; goto bail; @@ -151,7 +151,7 @@ void qib_release_user_pages(struct page **p, size_t num_pages) __qib_release_user_pages(p, num_pages, 1); if (current->mm) { - current->mm->locked_vm -= num_pages; + current->mm->pinned_vm -= num_pages; up_write(¤t->mm->mmap_sem); } } diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c index 37e685eafd2..c4897e1075d 100644 --- a/drivers/isdn/hisax/callc.c +++ b/drivers/isdn/hisax/callc.c @@ -65,7 +65,7 @@ hisax_findcard(int driverid) return (struct IsdnCardState *) 0; } -static __attribute__((format(printf, 3, 4))) void +static __printf(3, 4) void link_debug(struct Channel *chanp, int direction, char *fmt, ...) { va_list args; @@ -1068,7 +1068,7 @@ init_d_st(struct Channel *chanp) return 0; } -static __attribute__((format(printf, 2, 3))) void +static __printf(2, 3) void callc_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 0a5c42a3f12..aff45a11a92 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h @@ -1287,9 +1287,9 @@ int jiftime(char *s, long mark); int HiSax_command(isdn_ctrl * ic); int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); -__attribute__((format(printf, 3, 4))) +__printf(3, 4) void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); -__attribute__((format(printf, 3, 0))) +__printf(3, 0) void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); void HiSax_reportcard(int cardnr, int sel); int QuickHex(char *txt, u_char * p, int cnt); diff --git a/drivers/isdn/hisax/isdnl1.h b/drivers/isdn/hisax/isdnl1.h index 425d86116f2..66ddcab19bb 100644 --- a/drivers/isdn/hisax/isdnl1.h +++ b/drivers/isdn/hisax/isdnl1.h @@ -21,7 +21,7 @@ #define B_XMTBUFREADY 1 #define B_ACKPENDING 2 -__attribute__((format(printf, 2, 3))) +__printf(2, 3) void debugl1(struct IsdnCardState *cs, char *fmt, ...); void DChannel_proc_xmt(struct IsdnCardState *cs); void DChannel_proc_rcv(struct IsdnCardState *cs); diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c index ad291f21b20..1c24e4457b6 100644 --- a/drivers/isdn/hisax/isdnl3.c +++ b/drivers/isdn/hisax/isdnl3.c @@ -66,7 +66,7 @@ static char *strL3Event[] = "EV_TIMEOUT", }; -static __attribute__((format(printf, 2, 3))) void +static __printf(2, 3) void l3m_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c index 44082637a09..db247b79e56 100644 --- a/drivers/isdn/hisax/st5481_d.c +++ b/drivers/isdn/hisax/st5481_d.c @@ -167,7 +167,7 @@ static struct FsmNode L1FnList[] __initdata = {ST_L1_F8, EV_IND_RSY, l1_ignore}, }; -static __attribute__((format(printf, 2, 3))) +static __printf(2, 3) void l1m_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; @@ -270,7 +270,7 @@ static char *strDoutEvent[] = "EV_DOUT_UNDERRUN", }; -static __attribute__((format(printf, 2, 3))) +static __printf(2, 3) void dout_debug(struct FsmInst *fi, char *fmt, ...) { va_list args; diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index dc7caaddecf..ff203a42186 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -375,6 +375,18 @@ config LEDS_ASIC3 cannot be used. This driver supports hardware blinking with an on+off period from 62ms to 125s. Say Y to enable LEDs on the HP iPAQ hx4700. +config LEDS_RENESAS_TPU + bool "LED support for Renesas TPU" + depends on LEDS_CLASS && HAVE_CLK && GENERIC_GPIO + help + This option enables build of the LED TPU platform driver, + suitable to drive any TPU channel on newer Renesas SoCs. + The driver controls the GPIO pin connected to the LED via + the GPIO framework and expects the LED to be connected to + a pin that can be driven in both GPIO mode and using TPU + pin function. The latter to support brightness control. + Brightness control is supported but hardware blinking is not. + config LEDS_TRIGGERS bool "LED Trigger support" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index a0a1b89d78a..e4f6bf56888 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o obj-$(CONFIG_LEDS_NS2) += leds-ns2.o obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o +obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o # LED SPI Drivers obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index dc3d3d83191..661b692573e 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -267,9 +267,14 @@ void led_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off) { + del_timer_sync(&led_cdev->blink_timer); + if (led_cdev->blink_set && - !led_cdev->blink_set(led_cdev, delay_on, delay_off)) + !led_cdev->blink_set(led_cdev, delay_on, delay_off)) { + led_cdev->blink_delay_on = *delay_on; + led_cdev->blink_delay_off = *delay_off; return; + } /* blink with 1 Hz as default if nothing specified */ if (!*delay_on && !*delay_off) diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 4bebae73334..6f1ff93d7ce 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -261,9 +261,12 @@ void led_trigger_register_simple(const char *name, struct led_trigger **tp) if (trigger) { trigger->name = name; err = led_trigger_register(trigger); - if (err < 0) + if (err < 0) { + kfree(trigger); + trigger = NULL; printk(KERN_WARNING "LED trigger %s failed to register" " (%d)\n", name, err); + } } else printk(KERN_WARNING "LED trigger %s failed to register" " (no memory)\n", name); diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 3d8bc327a68..504cc26c7e4 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -121,7 +121,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template, } led_dat->cdev.brightness_set = gpio_led_set; if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) - state = !!gpio_get_value(led_dat->gpio) ^ led_dat->active_low; + state = !!gpio_get_value_cansleep(led_dat->gpio) ^ led_dat->active_low; else state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c index 3dd7090a9a9..4dc510fdfa0 100644 --- a/drivers/leds/leds-lm3530.c +++ b/drivers/leds/leds-lm3530.c @@ -421,7 +421,6 @@ err_class_register: err_reg_init: regulator_put(drvdata->regulator); err_regulator_get: - i2c_set_clientdata(client, NULL); kfree(drvdata); err_out: return err; @@ -449,7 +448,7 @@ MODULE_DEVICE_TABLE(i2c, lm3530_id); static struct i2c_driver lm3530_i2c_driver = { .probe = lm3530_probe, - .remove = lm3530_remove, + .remove = __devexit_p(lm3530_remove), .id_table = lm3530_id, .driver = { .name = LM3530_NAME, diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c index 9fc122c81f0..cb641f1b334 100644 --- a/drivers/leds/leds-lp5521.c +++ b/drivers/leds/leds-lp5521.c @@ -97,6 +97,9 @@ /* Status */ #define LP5521_EXT_CLK_USED 0x08 +/* default R channel current register value */ +#define LP5521_REG_R_CURR_DEFAULT 0xAF + struct lp5521_engine { int id; u8 mode; @@ -175,14 +178,14 @@ static int lp5521_set_engine_mode(struct lp5521_engine *engine, u8 mode) mode = LP5521_CMD_DIRECT; ret = lp5521_read(client, LP5521_REG_OP_MODE, &engine_state); + if (ret < 0) + return ret; /* set mode only for this engine */ engine_state &= ~(engine->engine_mask); mode &= engine->engine_mask; engine_state |= mode; - ret |= lp5521_write(client, LP5521_REG_OP_MODE, engine_state); - - return ret; + return lp5521_write(client, LP5521_REG_OP_MODE, engine_state); } static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern) @@ -643,6 +646,7 @@ static int __devinit lp5521_probe(struct i2c_client *client, struct lp5521_chip *chip; struct lp5521_platform_data *pdata; int ret, i, led; + u8 buf; chip = kzalloc(sizeof(*chip), GFP_KERNEL); if (!chip) @@ -681,6 +685,20 @@ static int __devinit lp5521_probe(struct i2c_client *client, * Exact value is not available. 10 - 20ms * appears to be enough for reset. */ + + /* + * Make sure that the chip is reset by reading back the r channel + * current reg. This is dummy read is required on some platforms - + * otherwise further access to the R G B channels in the + * LP5521_REG_ENABLE register will not have any effect - strange! + */ + lp5521_read(client, LP5521_REG_R_CURRENT, &buf); + if (buf != LP5521_REG_R_CURR_DEFAULT) { + dev_err(&client->dev, "error in reseting chip\n"); + goto fail2; + } + usleep_range(10000, 20000); + ret = lp5521_detect(client); if (ret) { diff --git a/drivers/leds/leds-renesas-tpu.c b/drivers/leds/leds-renesas-tpu.c new file mode 100644 index 00000000000..3ee540eb127 --- /dev/null +++ b/drivers/leds/leds-renesas-tpu.c @@ -0,0 +1,357 @@ +/* + * LED control using Renesas TPU + * + * Copyright (C) 2011 Magnus Damm + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/spinlock.h> +#include <linux/printk.h> +#include <linux/ioport.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/leds.h> +#include <linux/platform_data/leds-renesas-tpu.h> +#include <linux/gpio.h> +#include <linux/err.h> +#include <linux/slab.h> +#include <linux/pm_runtime.h> +#include <linux/workqueue.h> + +enum r_tpu_pin { R_TPU_PIN_UNUSED, R_TPU_PIN_GPIO, R_TPU_PIN_GPIO_FN }; +enum r_tpu_timer { R_TPU_TIMER_UNUSED, R_TPU_TIMER_ON }; + +struct r_tpu_priv { + struct led_classdev ldev; + void __iomem *mapbase; + struct clk *clk; + struct platform_device *pdev; + enum r_tpu_pin pin_state; + enum r_tpu_timer timer_state; + unsigned long min_rate; + unsigned int refresh_rate; + struct work_struct work; + enum led_brightness new_brightness; +}; + +static DEFINE_SPINLOCK(r_tpu_lock); + +#define TSTR -1 /* Timer start register (shared register) */ +#define TCR 0 /* Timer control register (+0x00) */ +#define TMDR 1 /* Timer mode register (+0x04) */ +#define TIOR 2 /* Timer I/O control register (+0x08) */ +#define TIER 3 /* Timer interrupt enable register (+0x0c) */ +#define TSR 4 /* Timer status register (+0x10) */ +#define TCNT 5 /* Timer counter (+0x14) */ +#define TGRA 6 /* Timer general register A (+0x18) */ +#define TGRB 7 /* Timer general register B (+0x1c) */ +#define TGRC 8 /* Timer general register C (+0x20) */ +#define TGRD 9 /* Timer general register D (+0x24) */ + +static inline unsigned short r_tpu_read(struct r_tpu_priv *p, int reg_nr) +{ + struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; + void __iomem *base = p->mapbase; + unsigned long offs = reg_nr << 2; + + if (reg_nr == TSTR) + return ioread16(base - cfg->channel_offset); + + return ioread16(base + offs); +} + +static inline void r_tpu_write(struct r_tpu_priv *p, int reg_nr, + unsigned short value) +{ + struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; + void __iomem *base = p->mapbase; + unsigned long offs = reg_nr << 2; + + if (reg_nr == TSTR) { + iowrite16(value, base - cfg->channel_offset); + return; + } + + iowrite16(value, base + offs); +} + +static void r_tpu_start_stop_ch(struct r_tpu_priv *p, int start) +{ + struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; + unsigned long flags, value; + + /* start stop register shared by multiple timer channels */ + spin_lock_irqsave(&r_tpu_lock, flags); + value = r_tpu_read(p, TSTR); + + if (start) + value |= 1 << cfg->timer_bit; + else + value &= ~(1 << cfg->timer_bit); + + r_tpu_write(p, TSTR, value); + spin_unlock_irqrestore(&r_tpu_lock, flags); +} + +static int r_tpu_enable(struct r_tpu_priv *p, enum led_brightness brightness) +{ + struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; + int prescaler[] = { 1, 4, 16, 64 }; + int k, ret; + unsigned long rate, tmp; + + if (p->timer_state == R_TPU_TIMER_ON) + return 0; + + /* wake up device and enable clock */ + pm_runtime_get_sync(&p->pdev->dev); + ret = clk_enable(p->clk); + if (ret) { + dev_err(&p->pdev->dev, "cannot enable clock\n"); + return ret; + } + + /* make sure channel is disabled */ + r_tpu_start_stop_ch(p, 0); + + /* get clock rate after enabling it */ + rate = clk_get_rate(p->clk); + + /* pick the lowest acceptable rate */ + for (k = 0; k < ARRAY_SIZE(prescaler); k++) + if ((rate / prescaler[k]) < p->min_rate) + break; + + if (!k) { + dev_err(&p->pdev->dev, "clock rate mismatch\n"); + goto err0; + } + dev_dbg(&p->pdev->dev, "rate = %lu, prescaler %u\n", + rate, prescaler[k - 1]); + + /* clear TCNT on TGRB match, count on rising edge, set prescaler */ + r_tpu_write(p, TCR, 0x0040 | (k - 1)); + + /* output 0 until TGRA, output 1 until TGRB */ + r_tpu_write(p, TIOR, 0x0002); + + rate /= prescaler[k - 1] * p->refresh_rate; + r_tpu_write(p, TGRB, rate); + dev_dbg(&p->pdev->dev, "TRGB = 0x%04lx\n", rate); + + tmp = (cfg->max_brightness - brightness) * rate; + r_tpu_write(p, TGRA, tmp / cfg->max_brightness); + dev_dbg(&p->pdev->dev, "TRGA = 0x%04lx\n", tmp / cfg->max_brightness); + + /* PWM mode */ + r_tpu_write(p, TMDR, 0x0002); + + /* enable channel */ + r_tpu_start_stop_ch(p, 1); + + p->timer_state = R_TPU_TIMER_ON; + return 0; + err0: + clk_disable(p->clk); + pm_runtime_put_sync(&p->pdev->dev); + return -ENOTSUPP; +} + +static void r_tpu_disable(struct r_tpu_priv *p) +{ + if (p->timer_state == R_TPU_TIMER_UNUSED) + return; + + /* disable channel */ + r_tpu_start_stop_ch(p, 0); + + /* stop clock and mark device as idle */ + clk_disable(p->clk); + pm_runtime_put_sync(&p->pdev->dev); + + p->timer_state = R_TPU_TIMER_UNUSED; +} + +static void r_tpu_set_pin(struct r_tpu_priv *p, enum r_tpu_pin new_state, + enum led_brightness brightness) +{ + struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; + + if (p->pin_state == new_state) { + if (p->pin_state == R_TPU_PIN_GPIO) + gpio_set_value(cfg->pin_gpio, brightness); + return; + } + + if (p->pin_state == R_TPU_PIN_GPIO) + gpio_free(cfg->pin_gpio); + + if (p->pin_state == R_TPU_PIN_GPIO_FN) + gpio_free(cfg->pin_gpio_fn); + + if (new_state == R_TPU_PIN_GPIO) { + gpio_request(cfg->pin_gpio, cfg->name); + gpio_direction_output(cfg->pin_gpio, !!brightness); + } + if (new_state == R_TPU_PIN_GPIO_FN) + gpio_request(cfg->pin_gpio_fn, cfg->name); + + p->pin_state = new_state; +} + +static void r_tpu_work(struct work_struct *work) +{ + struct r_tpu_priv *p = container_of(work, struct r_tpu_priv, work); + enum led_brightness brightness = p->new_brightness; + + r_tpu_disable(p); + + /* off and maximum are handled as GPIO pins, in between PWM */ + if ((brightness == 0) || (brightness == p->ldev.max_brightness)) + r_tpu_set_pin(p, R_TPU_PIN_GPIO, brightness); + else { + r_tpu_set_pin(p, R_TPU_PIN_GPIO_FN, 0); + r_tpu_enable(p, brightness); + } +} + +static void r_tpu_set_brightness(struct led_classdev *ldev, + enum led_brightness brightness) +{ + struct r_tpu_priv *p = container_of(ldev, struct r_tpu_priv, ldev); + p->new_brightness = brightness; + schedule_work(&p->work); +} + +static int __devinit r_tpu_probe(struct platform_device *pdev) +{ + struct led_renesas_tpu_config *cfg = pdev->dev.platform_data; + struct r_tpu_priv *p; + struct resource *res; + int ret = -ENXIO; + + if (!cfg) { + dev_err(&pdev->dev, "missing platform data\n"); + goto err0; + } + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (p == NULL) { + dev_err(&pdev->dev, "failed to allocate driver data\n"); + ret = -ENOMEM; + goto err0; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "failed to get I/O memory\n"); + goto err1; + } + + /* map memory, let mapbase point to our channel */ + p->mapbase = ioremap_nocache(res->start, resource_size(res)); + if (p->mapbase == NULL) { + dev_err(&pdev->dev, "failed to remap I/O memory\n"); + goto err1; + } + + /* get hold of clock */ + p->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(p->clk)) { + dev_err(&pdev->dev, "cannot get clock\n"); + ret = PTR_ERR(p->clk); + goto err2; + } + + p->pdev = pdev; + p->pin_state = R_TPU_PIN_UNUSED; + p->timer_state = R_TPU_TIMER_UNUSED; + p->refresh_rate = cfg->refresh_rate ? cfg->refresh_rate : 100; + r_tpu_set_pin(p, R_TPU_PIN_GPIO, LED_OFF); + platform_set_drvdata(pdev, p); + + INIT_WORK(&p->work, r_tpu_work); + + p->ldev.name = cfg->name; + p->ldev.brightness = LED_OFF; + p->ldev.max_brightness = cfg->max_brightness; + p->ldev.brightness_set = r_tpu_set_brightness; + p->ldev.flags |= LED_CORE_SUSPENDRESUME; + ret = led_classdev_register(&pdev->dev, &p->ldev); + if (ret < 0) + goto err3; + + /* max_brightness may be updated by the LED core code */ + p->min_rate = p->ldev.max_brightness * p->refresh_rate; + + pm_runtime_enable(&pdev->dev); + return 0; + + err3: + r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF); + clk_put(p->clk); + err2: + iounmap(p->mapbase); + err1: + kfree(p); + err0: + return ret; +} + +static int __devexit r_tpu_remove(struct platform_device *pdev) +{ + struct r_tpu_priv *p = platform_get_drvdata(pdev); + + r_tpu_set_brightness(&p->ldev, LED_OFF); + led_classdev_unregister(&p->ldev); + cancel_work_sync(&p->work); + r_tpu_disable(p); + r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF); + + pm_runtime_disable(&pdev->dev); + clk_put(p->clk); + + iounmap(p->mapbase); + kfree(p); + return 0; +} + +static struct platform_driver r_tpu_device_driver = { + .probe = r_tpu_probe, + .remove = __devexit_p(r_tpu_remove), + .driver = { + .name = "leds-renesas-tpu", + } +}; + +static int __init r_tpu_init(void) +{ + return platform_driver_register(&r_tpu_device_driver); +} + +static void __exit r_tpu_exit(void) +{ + platform_driver_unregister(&r_tpu_device_driver); +} + +module_init(r_tpu_init); +module_exit(r_tpu_exit); + +MODULE_AUTHOR("Magnus Damm"); +MODULE_DESCRIPTION("Renesas TPU LED Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index 4ff73c21574..a39e0555df6 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -98,6 +98,7 @@ static const struct i2c_device_id ad_dpot_id[] = { {"ad5282", AD5282_ID}, {"adn2860", ADN2860_ID}, {"ad5273", AD5273_ID}, + {"ad5161", AD5161_ID}, {"ad5171", AD5171_ID}, {"ad5170", AD5170_ID}, {"ad5172", AD5172_ID}, diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c index 27dc0d21aaf..f6586d53e1a 100644 --- a/drivers/misc/fsa9480.c +++ b/drivers/misc/fsa9480.c @@ -400,7 +400,8 @@ static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw) return ret; } - device_init_wakeup(&client->dev, pdata->wakeup); + if (pdata) + device_init_wakeup(&client->dev, pdata->wakeup); } return 0; diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index 8b51cd62d06..29d12a70eb1 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c @@ -163,7 +163,7 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z) int i; if (lis3->blkread) { - if (lis3_dev.whoami == WAI_12B) { + if (lis3->whoami == WAI_12B) { u16 data[3]; lis3->blkread(lis3, OUTX_L, 6, (u8 *)data); for (i = 0; i < 3; i++) @@ -195,18 +195,30 @@ static int lis3_8_rates[2] = {100, 400}; static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000}; /* ODR is Output Data Rate */ -static int lis3lv02d_get_odr(void) +static int lis3lv02d_get_odr(struct lis3lv02d *lis3) { u8 ctrl; int shift; - lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); - ctrl &= lis3_dev.odr_mask; - shift = ffs(lis3_dev.odr_mask) - 1; - return lis3_dev.odrs[(ctrl >> shift)]; + lis3->read(lis3, CTRL_REG1, &ctrl); + ctrl &= lis3->odr_mask; + shift = ffs(lis3->odr_mask) - 1; + return lis3->odrs[(ctrl >> shift)]; } -static int lis3lv02d_set_odr(int rate) +static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3) +{ + int div = lis3lv02d_get_odr(lis3); + + if (WARN_ONCE(div == 0, "device returned spurious data")) + return -ENXIO; + + /* LIS3 power on delay is quite long */ + msleep(lis3->pwron_delay / div); + return 0; +} + +static int lis3lv02d_set_odr(struct lis3lv02d *lis3, int rate) { u8 ctrl; int i, len, shift; @@ -214,14 +226,14 @@ static int lis3lv02d_set_odr(int rate) if (!rate) return -EINVAL; - lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); - ctrl &= ~lis3_dev.odr_mask; - len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */ - shift = ffs(lis3_dev.odr_mask) - 1; + lis3->read(lis3, CTRL_REG1, &ctrl); + ctrl &= ~lis3->odr_mask; + len = 1 << hweight_long(lis3->odr_mask); /* # of possible values */ + shift = ffs(lis3->odr_mask) - 1; for (i = 0; i < len; i++) - if (lis3_dev.odrs[i] == rate) { - lis3_dev.write(&lis3_dev, CTRL_REG1, + if (lis3->odrs[i] == rate) { + lis3->write(lis3, CTRL_REG1, ctrl | (i << shift)); return 0; } @@ -240,12 +252,12 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) mutex_lock(&lis3->mutex); irq_cfg = lis3->irq_cfg; - if (lis3_dev.whoami == WAI_8B) { + if (lis3->whoami == WAI_8B) { lis3->data_ready_count[IRQ_LINE0] = 0; lis3->data_ready_count[IRQ_LINE1] = 0; /* Change interrupt cfg to data ready for selftest */ - atomic_inc(&lis3_dev.wake_thread); + atomic_inc(&lis3->wake_thread); lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY; lis3->read(lis3, CTRL_REG3, &ctrl_reg_data); lis3->write(lis3, CTRL_REG3, (ctrl_reg_data & @@ -253,12 +265,12 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) (LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY)); } - if (lis3_dev.whoami == WAI_3DC) { + if (lis3->whoami == WAI_3DC) { ctlreg = CTRL_REG4; selftest = CTRL4_ST0; } else { ctlreg = CTRL_REG1; - if (lis3_dev.whoami == WAI_12B) + if (lis3->whoami == WAI_12B) selftest = CTRL1_ST; else selftest = CTRL1_STP; @@ -266,7 +278,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) lis3->read(lis3, ctlreg, ®); lis3->write(lis3, ctlreg, (reg | selftest)); - msleep(lis3->pwron_delay / lis3lv02d_get_odr()); + ret = lis3lv02d_get_pwron_wait(lis3); + if (ret) + goto fail; /* Read directly to avoid axis remap */ x = lis3->read_data(lis3, OUTX); @@ -275,7 +289,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) /* back to normal settings */ lis3->write(lis3, ctlreg, reg); - msleep(lis3->pwron_delay / lis3lv02d_get_odr()); + ret = lis3lv02d_get_pwron_wait(lis3); + if (ret) + goto fail; results[0] = x - lis3->read_data(lis3, OUTX); results[1] = y - lis3->read_data(lis3, OUTY); @@ -283,9 +299,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) ret = 0; - if (lis3_dev.whoami == WAI_8B) { + if (lis3->whoami == WAI_8B) { /* Restore original interrupt configuration */ - atomic_dec(&lis3_dev.wake_thread); + atomic_dec(&lis3->wake_thread); lis3->write(lis3, CTRL_REG3, ctrl_reg_data); lis3->irq_cfg = irq_cfg; @@ -363,8 +379,9 @@ void lis3lv02d_poweroff(struct lis3lv02d *lis3) } EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); -void lis3lv02d_poweron(struct lis3lv02d *lis3) +int lis3lv02d_poweron(struct lis3lv02d *lis3) { + int err; u8 reg; lis3->init(lis3); @@ -384,35 +401,41 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3) lis3->write(lis3, CTRL_REG2, reg); } - /* LIS3 power on delay is quite long */ - msleep(lis3->pwron_delay / lis3lv02d_get_odr()); + err = lis3lv02d_get_pwron_wait(lis3); + if (err) + return err; if (lis3->reg_ctrl) lis3_context_restore(lis3); + + return 0; } EXPORT_SYMBOL_GPL(lis3lv02d_poweron); static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev) { + struct lis3lv02d *lis3 = pidev->private; int x, y, z; - mutex_lock(&lis3_dev.mutex); - lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); + mutex_lock(&lis3->mutex); + lis3lv02d_get_xyz(lis3, &x, &y, &z); input_report_abs(pidev->input, ABS_X, x); input_report_abs(pidev->input, ABS_Y, y); input_report_abs(pidev->input, ABS_Z, z); input_sync(pidev->input); - mutex_unlock(&lis3_dev.mutex); + mutex_unlock(&lis3->mutex); } static void lis3lv02d_joystick_open(struct input_polled_dev *pidev) { - if (lis3_dev.pm_dev) - pm_runtime_get_sync(lis3_dev.pm_dev); + struct lis3lv02d *lis3 = pidev->private; - if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev) - atomic_set(&lis3_dev.wake_thread, 1); + if (lis3->pm_dev) + pm_runtime_get_sync(lis3->pm_dev); + + if (lis3->pdata && lis3->whoami == WAI_8B && lis3->idev) + atomic_set(&lis3->wake_thread, 1); /* * Update coordinates for the case where poll interval is 0 and * the chip in running purely under interrupt control @@ -422,14 +445,18 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev) static void lis3lv02d_joystick_close(struct input_polled_dev *pidev) { - atomic_set(&lis3_dev.wake_thread, 0); - if (lis3_dev.pm_dev) - pm_runtime_put(lis3_dev.pm_dev); + struct lis3lv02d *lis3 = pidev->private; + + atomic_set(&lis3->wake_thread, 0); + if (lis3->pm_dev) + pm_runtime_put(lis3->pm_dev); } -static irqreturn_t lis302dl_interrupt(int irq, void *dummy) +static irqreturn_t lis302dl_interrupt(int irq, void *data) { - if (!test_bit(0, &lis3_dev.misc_opened)) + struct lis3lv02d *lis3 = data; + + if (!test_bit(0, &lis3->misc_opened)) goto out; /* @@ -437,12 +464,12 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy) * the lid is closed. This leads to interrupts as soon as a little move * is done. */ - atomic_inc(&lis3_dev.count); + atomic_inc(&lis3->count); - wake_up_interruptible(&lis3_dev.misc_wait); - kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); + wake_up_interruptible(&lis3->misc_wait); + kill_fasync(&lis3->async_queue, SIGIO, POLL_IN); out: - if (atomic_read(&lis3_dev.wake_thread)) + if (atomic_read(&lis3->wake_thread)) return IRQ_WAKE_THREAD; return IRQ_HANDLED; } @@ -514,28 +541,37 @@ static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data) static int lis3lv02d_misc_open(struct inode *inode, struct file *file) { - if (test_and_set_bit(0, &lis3_dev.misc_opened)) + struct lis3lv02d *lis3 = container_of(file->private_data, + struct lis3lv02d, miscdev); + + if (test_and_set_bit(0, &lis3->misc_opened)) return -EBUSY; /* already open */ - if (lis3_dev.pm_dev) - pm_runtime_get_sync(lis3_dev.pm_dev); + if (lis3->pm_dev) + pm_runtime_get_sync(lis3->pm_dev); - atomic_set(&lis3_dev.count, 0); + atomic_set(&lis3->count, 0); return 0; } static int lis3lv02d_misc_release(struct inode *inode, struct file *file) { - fasync_helper(-1, file, 0, &lis3_dev.async_queue); - clear_bit(0, &lis3_dev.misc_opened); /* release the device */ - if (lis3_dev.pm_dev) - pm_runtime_put(lis3_dev.pm_dev); + struct lis3lv02d *lis3 = container_of(file->private_data, + struct lis3lv02d, miscdev); + + fasync_helper(-1, file, 0, &lis3->async_queue); + clear_bit(0, &lis3->misc_opened); /* release the device */ + if (lis3->pm_dev) + pm_runtime_put(lis3->pm_dev); return 0; } static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { + struct lis3lv02d *lis3 = container_of(file->private_data, + struct lis3lv02d, miscdev); + DECLARE_WAITQUEUE(wait, current); u32 data; unsigned char byte_data; @@ -544,10 +580,10 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, if (count < 1) return -EINVAL; - add_wait_queue(&lis3_dev.misc_wait, &wait); + add_wait_queue(&lis3->misc_wait, &wait); while (true) { set_current_state(TASK_INTERRUPTIBLE); - data = atomic_xchg(&lis3_dev.count, 0); + data = atomic_xchg(&lis3->count, 0); if (data) break; @@ -577,22 +613,28 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, out: __set_current_state(TASK_RUNNING); - remove_wait_queue(&lis3_dev.misc_wait, &wait); + remove_wait_queue(&lis3->misc_wait, &wait); return retval; } static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait) { - poll_wait(file, &lis3_dev.misc_wait, wait); - if (atomic_read(&lis3_dev.count)) + struct lis3lv02d *lis3 = container_of(file->private_data, + struct lis3lv02d, miscdev); + + poll_wait(file, &lis3->misc_wait, wait); + if (atomic_read(&lis3->count)) return POLLIN | POLLRDNORM; return 0; } static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) { - return fasync_helper(fd, file, on, &lis3_dev.async_queue); + struct lis3lv02d *lis3 = container_of(file->private_data, + struct lis3lv02d, miscdev); + + return fasync_helper(fd, file, on, &lis3->async_queue); } static const struct file_operations lis3lv02d_misc_fops = { @@ -605,85 +647,80 @@ static const struct file_operations lis3lv02d_misc_fops = { .fasync = lis3lv02d_misc_fasync, }; -static struct miscdevice lis3lv02d_misc_device = { - .minor = MISC_DYNAMIC_MINOR, - .name = "freefall", - .fops = &lis3lv02d_misc_fops, -}; - -int lis3lv02d_joystick_enable(void) +int lis3lv02d_joystick_enable(struct lis3lv02d *lis3) { struct input_dev *input_dev; int err; int max_val, fuzz, flat; int btns[] = {BTN_X, BTN_Y, BTN_Z}; - if (lis3_dev.idev) + if (lis3->idev) return -EINVAL; - lis3_dev.idev = input_allocate_polled_device(); - if (!lis3_dev.idev) + lis3->idev = input_allocate_polled_device(); + if (!lis3->idev) return -ENOMEM; - lis3_dev.idev->poll = lis3lv02d_joystick_poll; - lis3_dev.idev->open = lis3lv02d_joystick_open; - lis3_dev.idev->close = lis3lv02d_joystick_close; - lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL; - lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN; - lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX; - input_dev = lis3_dev.idev->input; + lis3->idev->poll = lis3lv02d_joystick_poll; + lis3->idev->open = lis3lv02d_joystick_open; + lis3->idev->close = lis3lv02d_joystick_close; + lis3->idev->poll_interval = MDPS_POLL_INTERVAL; + lis3->idev->poll_interval_min = MDPS_POLL_MIN; + lis3->idev->poll_interval_max = MDPS_POLL_MAX; + lis3->idev->private = lis3; + input_dev = lis3->idev->input; input_dev->name = "ST LIS3LV02DL Accelerometer"; input_dev->phys = DRIVER_NAME "/input0"; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0; - input_dev->dev.parent = &lis3_dev.pdev->dev; + input_dev->dev.parent = &lis3->pdev->dev; set_bit(EV_ABS, input_dev->evbit); - max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY; - if (lis3_dev.whoami == WAI_12B) { + max_val = (lis3->mdps_max_val * lis3->scale) / LIS3_ACCURACY; + if (lis3->whoami == WAI_12B) { fuzz = LIS3_DEFAULT_FUZZ_12B; flat = LIS3_DEFAULT_FLAT_12B; } else { fuzz = LIS3_DEFAULT_FUZZ_8B; flat = LIS3_DEFAULT_FLAT_8B; } - fuzz = (fuzz * lis3_dev.scale) / LIS3_ACCURACY; - flat = (flat * lis3_dev.scale) / LIS3_ACCURACY; + fuzz = (fuzz * lis3->scale) / LIS3_ACCURACY; + flat = (flat * lis3->scale) / LIS3_ACCURACY; input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat); input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat); input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat); - lis3_dev.mapped_btns[0] = lis3lv02d_get_axis(abs(lis3_dev.ac.x), btns); - lis3_dev.mapped_btns[1] = lis3lv02d_get_axis(abs(lis3_dev.ac.y), btns); - lis3_dev.mapped_btns[2] = lis3lv02d_get_axis(abs(lis3_dev.ac.z), btns); + lis3->mapped_btns[0] = lis3lv02d_get_axis(abs(lis3->ac.x), btns); + lis3->mapped_btns[1] = lis3lv02d_get_axis(abs(lis3->ac.y), btns); + lis3->mapped_btns[2] = lis3lv02d_get_axis(abs(lis3->ac.z), btns); - err = input_register_polled_device(lis3_dev.idev); + err = input_register_polled_device(lis3->idev); if (err) { - input_free_polled_device(lis3_dev.idev); - lis3_dev.idev = NULL; + input_free_polled_device(lis3->idev); + lis3->idev = NULL; } return err; } EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable); -void lis3lv02d_joystick_disable(void) +void lis3lv02d_joystick_disable(struct lis3lv02d *lis3) { - if (lis3_dev.irq) - free_irq(lis3_dev.irq, &lis3_dev); - if (lis3_dev.pdata && lis3_dev.pdata->irq2) - free_irq(lis3_dev.pdata->irq2, &lis3_dev); + if (lis3->irq) + free_irq(lis3->irq, lis3); + if (lis3->pdata && lis3->pdata->irq2) + free_irq(lis3->pdata->irq2, lis3); - if (!lis3_dev.idev) + if (!lis3->idev) return; - if (lis3_dev.irq) - misc_deregister(&lis3lv02d_misc_device); - input_unregister_polled_device(lis3_dev.idev); - input_free_polled_device(lis3_dev.idev); - lis3_dev.idev = NULL; + if (lis3->irq) + misc_deregister(&lis3->miscdev); + input_unregister_polled_device(lis3->idev); + input_free_polled_device(lis3->idev); + lis3->idev = NULL; } EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); @@ -708,6 +745,7 @@ static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3) static ssize_t lis3lv02d_selftest_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct lis3lv02d *lis3 = dev_get_drvdata(dev); s16 values[3]; static const char ok[] = "OK"; @@ -715,8 +753,8 @@ static ssize_t lis3lv02d_selftest_show(struct device *dev, static const char irq[] = "FAIL_IRQ"; const char *res; - lis3lv02d_sysfs_poweron(&lis3_dev); - switch (lis3lv02d_selftest(&lis3_dev, values)) { + lis3lv02d_sysfs_poweron(lis3); + switch (lis3lv02d_selftest(lis3, values)) { case SELFTEST_FAIL: res = fail; break; @@ -735,33 +773,37 @@ static ssize_t lis3lv02d_selftest_show(struct device *dev, static ssize_t lis3lv02d_position_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct lis3lv02d *lis3 = dev_get_drvdata(dev); int x, y, z; - lis3lv02d_sysfs_poweron(&lis3_dev); - mutex_lock(&lis3_dev.mutex); - lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); - mutex_unlock(&lis3_dev.mutex); + lis3lv02d_sysfs_poweron(lis3); + mutex_lock(&lis3->mutex); + lis3lv02d_get_xyz(lis3, &x, &y, &z); + mutex_unlock(&lis3->mutex); return sprintf(buf, "(%d,%d,%d)\n", x, y, z); } static ssize_t lis3lv02d_rate_show(struct device *dev, struct device_attribute *attr, char *buf) { - lis3lv02d_sysfs_poweron(&lis3_dev); - return sprintf(buf, "%d\n", lis3lv02d_get_odr()); + struct lis3lv02d *lis3 = dev_get_drvdata(dev); + + lis3lv02d_sysfs_poweron(lis3); + return sprintf(buf, "%d\n", lis3lv02d_get_odr(lis3)); } static ssize_t lis3lv02d_rate_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + struct lis3lv02d *lis3 = dev_get_drvdata(dev); unsigned long rate; if (strict_strtoul(buf, 0, &rate)) return -EINVAL; - lis3lv02d_sysfs_poweron(&lis3_dev); - if (lis3lv02d_set_odr(rate)) + lis3lv02d_sysfs_poweron(lis3); + if (lis3lv02d_set_odr(lis3, rate)) return -EINVAL; return count; @@ -790,6 +832,7 @@ static int lis3lv02d_add_fs(struct lis3lv02d *lis3) if (IS_ERR(lis3->pdev)) return PTR_ERR(lis3->pdev); + platform_set_drvdata(lis3->pdev, lis3); return sysfs_create_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group); } @@ -803,7 +846,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3) /* SYSFS may have left chip running. Turn off if necessary */ if (!pm_runtime_suspended(lis3->pm_dev)) - lis3lv02d_poweroff(&lis3_dev); + lis3lv02d_poweroff(lis3); pm_runtime_disable(lis3->pm_dev); pm_runtime_set_suspended(lis3->pm_dev); @@ -813,24 +856,24 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3) } EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); -static void lis3lv02d_8b_configure(struct lis3lv02d *dev, +static void lis3lv02d_8b_configure(struct lis3lv02d *lis3, struct lis3lv02d_platform_data *p) { int err; int ctrl2 = p->hipass_ctrl; if (p->click_flags) { - dev->write(dev, CLICK_CFG, p->click_flags); - dev->write(dev, CLICK_TIMELIMIT, p->click_time_limit); - dev->write(dev, CLICK_LATENCY, p->click_latency); - dev->write(dev, CLICK_WINDOW, p->click_window); - dev->write(dev, CLICK_THSZ, p->click_thresh_z & 0xf); - dev->write(dev, CLICK_THSY_X, + lis3->write(lis3, CLICK_CFG, p->click_flags); + lis3->write(lis3, CLICK_TIMELIMIT, p->click_time_limit); + lis3->write(lis3, CLICK_LATENCY, p->click_latency); + lis3->write(lis3, CLICK_WINDOW, p->click_window); + lis3->write(lis3, CLICK_THSZ, p->click_thresh_z & 0xf); + lis3->write(lis3, CLICK_THSY_X, (p->click_thresh_x & 0xf) | (p->click_thresh_y << 4)); - if (dev->idev) { - struct input_dev *input_dev = lis3_dev.idev->input; + if (lis3->idev) { + struct input_dev *input_dev = lis3->idev->input; input_set_capability(input_dev, EV_KEY, BTN_X); input_set_capability(input_dev, EV_KEY, BTN_Y); input_set_capability(input_dev, EV_KEY, BTN_Z); @@ -838,22 +881,22 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, } if (p->wakeup_flags) { - dev->write(dev, FF_WU_CFG_1, p->wakeup_flags); - dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f); + lis3->write(lis3, FF_WU_CFG_1, p->wakeup_flags); + lis3->write(lis3, FF_WU_THS_1, p->wakeup_thresh & 0x7f); /* pdata value + 1 to keep this backward compatible*/ - dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1); + lis3->write(lis3, FF_WU_DURATION_1, p->duration1 + 1); ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/ } if (p->wakeup_flags2) { - dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2); - dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f); + lis3->write(lis3, FF_WU_CFG_2, p->wakeup_flags2); + lis3->write(lis3, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f); /* pdata value + 1 to keep this backward compatible*/ - dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1); + lis3->write(lis3, FF_WU_DURATION_2, p->duration2 + 1); ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/ } /* Configure hipass filters */ - dev->write(dev, CTRL_REG2, ctrl2); + lis3->write(lis3, CTRL_REG2, ctrl2); if (p->irq2) { err = request_threaded_irq(p->irq2, @@ -861,7 +904,7 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, lis302dl_interrupt_thread2_8b, IRQF_TRIGGER_RISING | IRQF_ONESHOT | (p->irq_flags2 & IRQF_TRIGGER_MASK), - DRIVER_NAME, &lis3_dev); + DRIVER_NAME, lis3); if (err < 0) pr_err("No second IRQ. Limited functionality\n"); } @@ -871,93 +914,97 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, * Initialise the accelerometer and the various subsystems. * Should be rather independent of the bus system. */ -int lis3lv02d_init_device(struct lis3lv02d *dev) +int lis3lv02d_init_device(struct lis3lv02d *lis3) { int err; irq_handler_t thread_fn; int irq_flags = 0; - dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I); + lis3->whoami = lis3lv02d_read_8(lis3, WHO_AM_I); - switch (dev->whoami) { + switch (lis3->whoami) { case WAI_12B: pr_info("12 bits sensor found\n"); - dev->read_data = lis3lv02d_read_12; - dev->mdps_max_val = 2048; - dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B; - dev->odrs = lis3_12_rates; - dev->odr_mask = CTRL1_DF0 | CTRL1_DF1; - dev->scale = LIS3_SENSITIVITY_12B; - dev->regs = lis3_wai12_regs; - dev->regs_size = ARRAY_SIZE(lis3_wai12_regs); + lis3->read_data = lis3lv02d_read_12; + lis3->mdps_max_val = 2048; + lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_12B; + lis3->odrs = lis3_12_rates; + lis3->odr_mask = CTRL1_DF0 | CTRL1_DF1; + lis3->scale = LIS3_SENSITIVITY_12B; + lis3->regs = lis3_wai12_regs; + lis3->regs_size = ARRAY_SIZE(lis3_wai12_regs); break; case WAI_8B: pr_info("8 bits sensor found\n"); - dev->read_data = lis3lv02d_read_8; - dev->mdps_max_val = 128; - dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; - dev->odrs = lis3_8_rates; - dev->odr_mask = CTRL1_DR; - dev->scale = LIS3_SENSITIVITY_8B; - dev->regs = lis3_wai8_regs; - dev->regs_size = ARRAY_SIZE(lis3_wai8_regs); + lis3->read_data = lis3lv02d_read_8; + lis3->mdps_max_val = 128; + lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; + lis3->odrs = lis3_8_rates; + lis3->odr_mask = CTRL1_DR; + lis3->scale = LIS3_SENSITIVITY_8B; + lis3->regs = lis3_wai8_regs; + lis3->regs_size = ARRAY_SIZE(lis3_wai8_regs); break; case WAI_3DC: pr_info("8 bits 3DC sensor found\n"); - dev->read_data = lis3lv02d_read_8; - dev->mdps_max_val = 128; - dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; - dev->odrs = lis3_3dc_rates; - dev->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3; - dev->scale = LIS3_SENSITIVITY_8B; + lis3->read_data = lis3lv02d_read_8; + lis3->mdps_max_val = 128; + lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; + lis3->odrs = lis3_3dc_rates; + lis3->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3; + lis3->scale = LIS3_SENSITIVITY_8B; break; default: - pr_err("unknown sensor type 0x%X\n", dev->whoami); + pr_err("unknown sensor type 0x%X\n", lis3->whoami); return -EINVAL; } - dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs), + lis3->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs), sizeof(lis3_wai12_regs)), GFP_KERNEL); - if (dev->reg_cache == NULL) { + if (lis3->reg_cache == NULL) { printk(KERN_ERR DRIVER_NAME "out of memory\n"); return -ENOMEM; } - mutex_init(&dev->mutex); - atomic_set(&dev->wake_thread, 0); + mutex_init(&lis3->mutex); + atomic_set(&lis3->wake_thread, 0); - lis3lv02d_add_fs(dev); - lis3lv02d_poweron(dev); + lis3lv02d_add_fs(lis3); + err = lis3lv02d_poweron(lis3); + if (err) { + lis3lv02d_remove_fs(lis3); + return err; + } - if (dev->pm_dev) { - pm_runtime_set_active(dev->pm_dev); - pm_runtime_enable(dev->pm_dev); + if (lis3->pm_dev) { + pm_runtime_set_active(lis3->pm_dev); + pm_runtime_enable(lis3->pm_dev); } - if (lis3lv02d_joystick_enable()) + if (lis3lv02d_joystick_enable(lis3)) pr_err("joystick initialization failed\n"); /* passing in platform specific data is purely optional and only * used by the SPI transport layer at the moment */ - if (dev->pdata) { - struct lis3lv02d_platform_data *p = dev->pdata; + if (lis3->pdata) { + struct lis3lv02d_platform_data *p = lis3->pdata; - if (dev->whoami == WAI_8B) - lis3lv02d_8b_configure(dev, p); + if (lis3->whoami == WAI_8B) + lis3lv02d_8b_configure(lis3, p); irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK; - dev->irq_cfg = p->irq_cfg; + lis3->irq_cfg = p->irq_cfg; if (p->irq_cfg) - dev->write(dev, CTRL_REG3, p->irq_cfg); + lis3->write(lis3, CTRL_REG3, p->irq_cfg); if (p->default_rate) - lis3lv02d_set_odr(p->default_rate); + lis3lv02d_set_odr(lis3, p->default_rate); } /* bail if we did not get an IRQ from the bus layer */ - if (!dev->irq) { + if (!lis3->irq) { pr_debug("No IRQ. Disabling /dev/freefall\n"); goto out; } @@ -973,23 +1020,27 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) * io-apic is not configurable (and generates a warning) but I keep it * in case of support for other hardware. */ - if (dev->pdata && dev->whoami == WAI_8B) + if (lis3->pdata && lis3->whoami == WAI_8B) thread_fn = lis302dl_interrupt_thread1_8b; else thread_fn = NULL; - err = request_threaded_irq(dev->irq, lis302dl_interrupt, + err = request_threaded_irq(lis3->irq, lis302dl_interrupt, thread_fn, IRQF_TRIGGER_RISING | IRQF_ONESHOT | irq_flags, - DRIVER_NAME, &lis3_dev); + DRIVER_NAME, lis3); if (err < 0) { pr_err("Cannot get IRQ\n"); goto out; } - if (misc_register(&lis3lv02d_misc_device)) + lis3->miscdev.minor = MISC_DYNAMIC_MINOR; + lis3->miscdev.name = "freefall"; + lis3->miscdev.fops = &lis3lv02d_misc_fops; + + if (misc_register(&lis3->miscdev)) pr_err("misc_register failed\n"); out: return 0; diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h index a1939589eb2..2b1482ad3f1 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.h +++ b/drivers/misc/lis3lv02d/lis3lv02d.h @@ -21,6 +21,7 @@ #include <linux/platform_device.h> #include <linux/input-polldev.h> #include <linux/regulator/consumer.h> +#include <linux/miscdevice.h> /* * This driver tries to support the "digital" accelerometer chips from @@ -273,6 +274,8 @@ struct lis3lv02d { struct fasync_struct *async_queue; /* queue for the misc device */ wait_queue_head_t misc_wait; /* Wait queue for the misc device */ unsigned long misc_opened; /* bit0: whether the device is open */ + struct miscdevice miscdev; + int data_ready_count[2]; atomic_t wake_thread; unsigned char irq_cfg; @@ -282,10 +285,10 @@ struct lis3lv02d { }; int lis3lv02d_init_device(struct lis3lv02d *lis3); -int lis3lv02d_joystick_enable(void); -void lis3lv02d_joystick_disable(void); +int lis3lv02d_joystick_enable(struct lis3lv02d *lis3); +void lis3lv02d_joystick_disable(struct lis3lv02d *lis3); void lis3lv02d_poweroff(struct lis3lv02d *lis3); -void lis3lv02d_poweron(struct lis3lv02d *lis3); +int lis3lv02d_poweron(struct lis3lv02d *lis3); int lis3lv02d_remove_fs(struct lis3lv02d *lis3); extern struct lis3lv02d lis3_dev; diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index b20dfb4522d..c02fea029dc 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c @@ -79,8 +79,7 @@ static int lis3_i2c_init(struct lis3lv02d *lis3) u8 reg; int ret; - if (lis3->reg_ctrl) - lis3_reg_ctrl(lis3, LIS3_REG_ON); + lis3_reg_ctrl(lis3, LIS3_REG_ON); lis3->read(lis3, WHO_AM_I, ®); if (reg != lis3->whoami) @@ -106,10 +105,6 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, struct lis3lv02d_platform_data *pdata = client->dev.platform_data; if (pdata) { - /* Regulator control is optional */ - if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL) - lis3_dev.reg_ctrl = lis3_reg_ctrl; - if ((pdata->driver_features & LIS3_USE_BLOCK_READ) && (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))) @@ -131,15 +126,13 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, goto fail; } - if (lis3_dev.reg_ctrl) { - lis3_dev.regulators[0].supply = reg_vdd; - lis3_dev.regulators[1].supply = reg_vdd_io; - ret = regulator_bulk_get(&client->dev, - ARRAY_SIZE(lis3_dev.regulators), - lis3_dev.regulators); - if (ret < 0) - goto fail; - } + lis3_dev.regulators[0].supply = reg_vdd; + lis3_dev.regulators[1].supply = reg_vdd_io; + ret = regulator_bulk_get(&client->dev, + ARRAY_SIZE(lis3_dev.regulators), + lis3_dev.regulators); + if (ret < 0) + goto fail; lis3_dev.pdata = pdata; lis3_dev.bus_priv = client; @@ -153,16 +146,19 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, i2c_set_clientdata(client, &lis3_dev); /* Provide power over the init call */ - if (lis3_dev.reg_ctrl) - lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON); + lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON); ret = lis3lv02d_init_device(&lis3_dev); - if (lis3_dev.reg_ctrl) - lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF); + lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF); - if (ret == 0) - return 0; + if (ret) + goto fail2; + return 0; + +fail2: + regulator_bulk_free(ARRAY_SIZE(lis3_dev.regulators), + lis3_dev.regulators); fail: if (pdata && pdata->release_resources) pdata->release_resources(); @@ -177,12 +173,11 @@ static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client) if (pdata && pdata->release_resources) pdata->release_resources(); - lis3lv02d_joystick_disable(); + lis3lv02d_joystick_disable(lis3); lis3lv02d_remove_fs(&lis3_dev); - if (lis3_dev.reg_ctrl) - regulator_bulk_free(ARRAY_SIZE(lis3->regulators), - lis3_dev.regulators); + regulator_bulk_free(ARRAY_SIZE(lis3->regulators), + lis3_dev.regulators); return 0; } diff --git a/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c index c1f8a8fbf69..b2c1be12d16 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_spi.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_spi.c @@ -83,7 +83,7 @@ static int __devinit lis302dl_spi_probe(struct spi_device *spi) static int __devexit lis302dl_spi_remove(struct spi_device *spi) { struct lis3lv02d *lis3 = spi_get_drvdata(spi); - lis3lv02d_joystick_disable(); + lis3lv02d_joystick_disable(lis3); lis3lv02d_poweroff(lis3); return lis3lv02d_remove_fs(&lis3_dev); diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index fca66165110..8fda331c65d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -581,8 +581,9 @@ extern const struct ethtool_ops mlx4_en_ethtool_ops; * printk / logging functions */ +__printf(3, 4) int en_print(const char *level, const struct mlx4_en_priv *priv, - const char *format, ...) __attribute__ ((format (printf, 3, 4))); + const char *format, ...); #define en_dbg(mlevel, priv, format, arg...) \ do { \ diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 39322d4121b..4045e5ab055 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c @@ -517,7 +517,7 @@ static char *hex2str(void *buf, size_t len) goto exit; while (len--) { - obuf = pack_hex_byte(obuf, *ibuf++); + obuf = hex_byte_pack(obuf, *ibuf++); *obuf++ = '-'; } obuf--; diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 908fdbc3e0e..0f9ee46cfc9 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -173,8 +173,7 @@ bool ath_hw_keyreset(struct ath_common *common, u16 entry); void ath_hw_cycle_counters_update(struct ath_common *common); int32_t ath_hw_get_listen_time(struct ath_common *common); -extern __attribute__((format (printf, 2, 3))) -void ath_printk(const char *level, const char *fmt, ...); +extern __printf(2, 3) void ath_printk(const char *level, const char *fmt, ...); #define _ath_printk(level, common, fmt, ...) \ do { \ @@ -258,7 +257,7 @@ do { \ #else -static inline __attribute__((format (printf, 3, 4))) +static inline __attribute__ ((format (printf, 3, 4))) void ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask, const char *fmt, ...) { diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index 7f37df3125f..0a3f916a1ef 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h @@ -141,10 +141,10 @@ ath5k_debug_printtxbuf(struct ath5k_hw *ah, struct ath5k_buf *bf); #include <linux/compiler.h> -static inline void __attribute__ ((format (printf, 3, 4))) +static inline __printf(3, 4) void ATH5K_DBG(struct ath5k_hw *ah, unsigned int m, const char *fmt, ...) {} -static inline void __attribute__ ((format (printf, 3, 4))) +static inline __printf(3, 4) void ATH5K_DBG_UNLIMIT(struct ath5k_hw *ah, unsigned int m, const char *fmt, ...) {} diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index 9288a3ce1e3..7b7675f70a1 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -44,8 +44,8 @@ enum ATH6K_DEBUG_MASK { }; extern unsigned int debug_mask; -extern int ath6kl_printk(const char *level, const char *fmt, ...) - __attribute__ ((format (printf, 2, 3))); +extern __printf(2, 3) +int ath6kl_printk(const char *level, const char *fmt, ...); #define ath6kl_info(fmt, ...) \ ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__) diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 447a2307c9d..37110dfd2c9 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -1011,14 +1011,10 @@ static inline bool b43_using_pio_transfers(struct b43_wldev *dev) } /* Message printing */ -void b43info(struct b43_wl *wl, const char *fmt, ...) - __attribute__ ((format(printf, 2, 3))); -void b43err(struct b43_wl *wl, const char *fmt, ...) - __attribute__ ((format(printf, 2, 3))); -void b43warn(struct b43_wl *wl, const char *fmt, ...) - __attribute__ ((format(printf, 2, 3))); -void b43dbg(struct b43_wl *wl, const char *fmt, ...) - __attribute__ ((format(printf, 2, 3))); +__printf(2, 3) void b43info(struct b43_wl *wl, const char *fmt, ...); +__printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...); +__printf(2, 3) void b43warn(struct b43_wl *wl, const char *fmt, ...); +__printf(2, 3) void b43dbg(struct b43_wl *wl, const char *fmt, ...); /* A WARN_ON variant that vanishes when b43 debugging is disabled. diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h index 12b51825158..1d4fc9db7f5 100644 --- a/drivers/net/wireless/b43legacy/b43legacy.h +++ b/drivers/net/wireless/b43legacy/b43legacy.h @@ -810,15 +810,15 @@ struct b43legacy_lopair *b43legacy_get_lopair(struct b43legacy_phy *phy, /* Message printing */ -void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...) - __attribute__((format(printf, 2, 3))); -void b43legacyerr(struct b43legacy_wl *wl, const char *fmt, ...) - __attribute__((format(printf, 2, 3))); -void b43legacywarn(struct b43legacy_wl *wl, const char *fmt, ...) - __attribute__((format(printf, 2, 3))); +__printf(2, 3) +void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...); +__printf(2, 3) +void b43legacyerr(struct b43legacy_wl *wl, const char *fmt, ...); +__printf(2, 3) +void b43legacywarn(struct b43legacy_wl *wl, const char *fmt, ...); #if B43legacy_DEBUG -void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...) - __attribute__((format(printf, 2, 3))); +__printf(2, 3) +void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...); #else /* DEBUG */ # define b43legacydbg(wl, fmt...) do { /* nothing */ } while (0) #endif /* DEBUG */ diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 64b454855f6..22b2dfa7314 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c @@ -210,6 +210,8 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { AXIS_DMI_MATCH("NC6715x", "HP Compaq 6715", y_inverted), AXIS_DMI_MATCH("NC693xx", "HP EliteBook 693", xy_rotated_right), AXIS_DMI_MATCH("NC693xx", "HP EliteBook 853", xy_swap), + AXIS_DMI_MATCH("NC854xx", "HP EliteBook 854", y_inverted), + AXIS_DMI_MATCH("NC273xx", "HP EliteBook 273", y_inverted), /* Intel-based HP Pavilion dv5 */ AXIS_DMI_MATCH2("HPDV5_I", PRODUCT_NAME, "HP Pavilion dv5", @@ -228,6 +230,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted), AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap), AXIS_DMI_MATCH("HPB532x", "HP ProBook 532", y_inverted), + AXIS_DMI_MATCH("HPB655x", "HP ProBook 655", xy_swap_inverted), AXIS_DMI_MATCH("Mini510x", "HP Mini 510", xy_rotated_left_usd), AXIS_DMI_MATCH("HPB63xx", "HP ProBook 63", xy_swap), AXIS_DMI_MATCH("HPB64xx", "HP ProBook 64", xy_swap), @@ -325,7 +328,7 @@ static int lis3lv02d_add(struct acpi_device *device) INIT_WORK(&hpled_led.work, delayed_set_status_worker); ret = led_classdev_register(NULL, &hpled_led.led_classdev); if (ret) { - lis3lv02d_joystick_disable(); + lis3lv02d_joystick_disable(&lis3_dev); lis3lv02d_poweroff(&lis3_dev); flush_work(&hpled_led.work); return ret; @@ -339,7 +342,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) if (!device) return -EINVAL; - lis3lv02d_joystick_disable(); + lis3lv02d_joystick_disable(&lis3_dev); lis3lv02d_poweroff(&lis3_dev); led_classdev_unregister(&hpled_led.led_classdev); @@ -359,8 +362,7 @@ static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) static int lis3lv02d_resume(struct acpi_device *device) { - lis3lv02d_poweron(&lis3_dev); - return 0; + return lis3lv02d_poweron(&lis3_dev); } #else #define lis3lv02d_suspend NULL diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h index 598fcb3599f..5cc42a655c8 100644 --- a/drivers/staging/iio/trigger.h +++ b/drivers/staging/iio/trigger.h @@ -115,8 +115,7 @@ void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time); irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private); -struct iio_trigger *iio_allocate_trigger(const char *fmt, ...) - __attribute__((format(printf, 1, 2))); +__printf(1, 2) struct iio_trigger *iio_allocate_trigger(const char *fmt, ...); void iio_free_trigger(struct iio_trigger *trig); #endif /* _IIO_TRIGGER_H_ */ diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c index 98e0304deea..6c68a6899e8 100644 --- a/drivers/video/backlight/adp8870_bl.c +++ b/drivers/video/backlight/adp8870_bl.c @@ -931,7 +931,6 @@ out: out1: backlight_device_unregister(bl); out2: - i2c_set_clientdata(client, NULL); kfree(data); return ret; @@ -951,7 +950,6 @@ static int __devexit adp8870_remove(struct i2c_client *client) &adp8870_bl_attr_group); backlight_device_unregister(data->bl); - i2c_set_clientdata(client, NULL); kfree(data); return 0; diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c index 8c6befd65a3..adb191466d6 100644 --- a/drivers/video/backlight/generic_bl.c +++ b/drivers/video/backlight/generic_bl.c @@ -56,7 +56,7 @@ static int genericbl_get_intensity(struct backlight_device *bd) * Called when the battery is low to limit the backlight intensity. * If limit==0 clear any limit, otherwise limit the intensity */ -void corgibl_limit_intensity(int limit) +void genericbl_limit_intensity(int limit) { struct backlight_device *bd = generic_backlight_device; @@ -68,7 +68,7 @@ void corgibl_limit_intensity(int limit) backlight_update_status(generic_backlight_device); mutex_unlock(&bd->ops_lock); } -EXPORT_SYMBOL(corgibl_limit_intensity); +EXPORT_SYMBOL(genericbl_limit_intensity); static const struct backlight_ops genericbl_ops = { .options = BL_CORE_SUSPENDRESUME, diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index 98ad3e5f7c8..3543f1b7d5f 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c @@ -52,15 +52,11 @@ static void l4f00242t03_lcd_init(struct spi_device *spi) dev_dbg(&spi->dev, "initializing LCD\n"); - if (priv->io_reg) { - regulator_set_voltage(priv->io_reg, 1800000, 1800000); - regulator_enable(priv->io_reg); - } + regulator_set_voltage(priv->io_reg, 1800000, 1800000); + regulator_enable(priv->io_reg); - if (priv->core_reg) { - regulator_set_voltage(priv->core_reg, 2800000, 2800000); - regulator_enable(priv->core_reg); - } + regulator_set_voltage(priv->core_reg, 2800000, 2800000); + regulator_enable(priv->core_reg); l4f00242t03_reset(pdata->reset_gpio); @@ -78,11 +74,8 @@ static void l4f00242t03_lcd_powerdown(struct spi_device *spi) gpio_set_value(pdata->data_enable_gpio, 0); - if (priv->io_reg) - regulator_disable(priv->io_reg); - - if (priv->core_reg) - regulator_disable(priv->core_reg); + regulator_disable(priv->io_reg); + regulator_disable(priv->core_reg); } static int l4f00242t03_lcd_power_get(struct lcd_device *ld) @@ -178,47 +171,34 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) priv->spi = spi; - ret = gpio_request(pdata->reset_gpio, "lcd l4f00242t03 reset"); + ret = gpio_request_one(pdata->reset_gpio, GPIOF_OUT_INIT_HIGH, + "lcd l4f00242t03 reset"); if (ret) { dev_err(&spi->dev, "Unable to get the lcd l4f00242t03 reset gpio.\n"); goto err; } - ret = gpio_direction_output(pdata->reset_gpio, 1); - if (ret) - goto err2; - - ret = gpio_request(pdata->data_enable_gpio, - "lcd l4f00242t03 data enable"); + ret = gpio_request_one(pdata->data_enable_gpio, GPIOF_OUT_INIT_LOW, + "lcd l4f00242t03 data enable"); if (ret) { dev_err(&spi->dev, "Unable to get the lcd l4f00242t03 data en gpio.\n"); goto err2; } - ret = gpio_direction_output(pdata->data_enable_gpio, 0); - if (ret) + priv->io_reg = regulator_get(&spi->dev, "vdd"); + if (IS_ERR(priv->io_reg)) { + dev_err(&spi->dev, "%s: Unable to get the IO regulator\n", + __func__); goto err3; - - if (pdata->io_supply) { - priv->io_reg = regulator_get(NULL, pdata->io_supply); - - if (IS_ERR(priv->io_reg)) { - pr_err("%s: Unable to get the IO regulator\n", - __func__); - goto err3; - } } - if (pdata->core_supply) { - priv->core_reg = regulator_get(NULL, pdata->core_supply); - - if (IS_ERR(priv->core_reg)) { - pr_err("%s: Unable to get the core regulator\n", - __func__); - goto err4; - } + priv->core_reg = regulator_get(&spi->dev, "vcore"); + if (IS_ERR(priv->core_reg)) { + dev_err(&spi->dev, "%s: Unable to get the core regulator\n", + __func__); + goto err4; } priv->ld = lcd_device_register("l4f00242t03", @@ -238,11 +218,9 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) return 0; err5: - if (priv->core_reg) - regulator_put(priv->core_reg); + regulator_put(priv->core_reg); err4: - if (priv->io_reg) - regulator_put(priv->io_reg); + regulator_put(priv->io_reg); err3: gpio_free(pdata->data_enable_gpio); err2: @@ -266,10 +244,8 @@ static int __devexit l4f00242t03_remove(struct spi_device *spi) gpio_free(pdata->data_enable_gpio); gpio_free(pdata->reset_gpio); - if (priv->io_reg) - regulator_put(priv->io_reg); - if (priv->core_reg) - regulator_put(priv->core_reg); + regulator_put(priv->io_reg); + regulator_put(priv->core_reg); kfree(priv); |