diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-31 20:46:07 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-31 20:46:07 -0400 |
| 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 a61e7815a2a9..6460487e41b5 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c | |||
| @@ -27,8 +27,7 @@ | |||
| 27 | 27 | ||
| 28 | static struct class *hwmon_class; | 28 | static struct class *hwmon_class; |
| 29 | 29 | ||
| 30 | static DEFINE_IDR(hwmon_idr); | 30 | static DEFINE_IDA(hwmon_ida); |
| 31 | static DEFINE_SPINLOCK(idr_lock); | ||
| 32 | 31 | ||
| 33 | /** | 32 | /** |
| 34 | * hwmon_device_register - register w/ hwmon | 33 | * hwmon_device_register - register w/ hwmon |
| @@ -42,30 +41,17 @@ static DEFINE_SPINLOCK(idr_lock); | |||
| 42 | struct device *hwmon_device_register(struct device *dev) | 41 | struct device *hwmon_device_register(struct device *dev) |
| 43 | { | 42 | { |
| 44 | struct device *hwdev; | 43 | struct device *hwdev; |
| 45 | int id, err; | 44 | int id; |
| 46 | |||
| 47 | again: | ||
| 48 | if (unlikely(idr_pre_get(&hwmon_idr, GFP_KERNEL) == 0)) | ||
| 49 | return ERR_PTR(-ENOMEM); | ||
| 50 | |||
| 51 | spin_lock(&idr_lock); | ||
| 52 | err = idr_get_new(&hwmon_idr, NULL, &id); | ||
| 53 | spin_unlock(&idr_lock); | ||
| 54 | 45 | ||
| 55 | if (unlikely(err == -EAGAIN)) | 46 | id = ida_simple_get(&hwmon_ida, 0, 0, GFP_KERNEL); |
| 56 | goto again; | 47 | if (id < 0) |
| 57 | else if (unlikely(err)) | 48 | return ERR_PTR(id); |
| 58 | return ERR_PTR(err); | ||
| 59 | 49 | ||
| 60 | id = id & MAX_ID_MASK; | ||
| 61 | hwdev = device_create(hwmon_class, dev, MKDEV(0, 0), NULL, | 50 | hwdev = device_create(hwmon_class, dev, MKDEV(0, 0), NULL, |
| 62 | HWMON_ID_FORMAT, id); | 51 | HWMON_ID_FORMAT, id); |
| 63 | 52 | ||
| 64 | if (IS_ERR(hwdev)) { | 53 | if (IS_ERR(hwdev)) |
| 65 | spin_lock(&idr_lock); | 54 | ida_simple_remove(&hwmon_ida, id); |
| 66 | idr_remove(&hwmon_idr, id); | ||
| 67 | spin_unlock(&idr_lock); | ||
| 68 | } | ||
| 69 | 55 | ||
| 70 | return hwdev; | 56 | return hwdev; |
| 71 | } | 57 | } |
| @@ -81,9 +67,7 @@ void hwmon_device_unregister(struct device *dev) | |||
| 81 | 67 | ||
| 82 | if (likely(sscanf(dev_name(dev), HWMON_ID_FORMAT, &id) == 1)) { | 68 | if (likely(sscanf(dev_name(dev), HWMON_ID_FORMAT, &id) == 1)) { |
| 83 | device_unregister(dev); | 69 | device_unregister(dev); |
| 84 | spin_lock(&idr_lock); | 70 | ida_simple_remove(&hwmon_ida, id); |
| 85 | idr_remove(&hwmon_idr, id); | ||
| 86 | spin_unlock(&idr_lock); | ||
| 87 | } else | 71 | } else |
| 88 | dev_dbg(dev->parent, | 72 | dev_dbg(dev->parent, |
| 89 | "hwmon_device_unregister() failed: bad class ID!\n"); | 73 | "hwmon_device_unregister() failed: bad class ID!\n"); |
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index c316294c48b4..783d0c17b762 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c | |||
| @@ -88,8 +88,7 @@ | |||
| 88 | #define AEM_MIN_POWER_INTERVAL 200 | 88 | #define AEM_MIN_POWER_INTERVAL 200 |
| 89 | #define UJ_PER_MJ 1000L | 89 | #define UJ_PER_MJ 1000L |
| 90 | 90 | ||
| 91 | static DEFINE_IDR(aem_idr); | 91 | static DEFINE_IDA(aem_ida); |
| 92 | static DEFINE_SPINLOCK(aem_idr_lock); | ||
| 93 | 92 | ||
| 94 | static struct platform_driver aem_driver = { | 93 | static struct platform_driver aem_driver = { |
| 95 | .driver = { | 94 | .driver = { |
| @@ -356,38 +355,6 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | |||
| 356 | complete(&data->read_complete); | 355 | complete(&data->read_complete); |
| 357 | } | 356 | } |
| 358 | 357 | ||
| 359 | /* ID functions */ | ||
| 360 | |||
| 361 | /* Obtain an id */ | ||
| 362 | static int aem_idr_get(int *id) | ||
| 363 | { | ||
| 364 | int i, err; | ||
| 365 | |||
| 366 | again: | ||
| 367 | if (unlikely(!idr_pre_get(&aem_idr, GFP_KERNEL))) | ||
| 368 | return -ENOMEM; | ||
| 369 | |||
| 370 | spin_lock(&aem_idr_lock); | ||
| 371 | err = idr_get_new(&aem_idr, NULL, &i); | ||
| 372 | spin_unlock(&aem_idr_lock); | ||
| 373 | |||
| 374 | if (unlikely(err == -EAGAIN)) | ||
| 375 | goto again; | ||
| 376 | else if (unlikely(err)) | ||
| 377 | return err; | ||
| 378 | |||
| 379 | *id = i & MAX_ID_MASK; | ||
| 380 | return 0; | ||
| 381 | } | ||
| 382 | |||
| 383 | /* Release an object ID */ | ||
| 384 | static void aem_idr_put(int id) | ||
| 385 | { | ||
| 386 | spin_lock(&aem_idr_lock); | ||
| 387 | idr_remove(&aem_idr, id); | ||
| 388 | spin_unlock(&aem_idr_lock); | ||
| 389 | } | ||
| 390 | |||
| 391 | /* Sensor support functions */ | 358 | /* Sensor support functions */ |
| 392 | 359 | ||
| 393 | /* Read a sensor value */ | 360 | /* Read a sensor value */ |
| @@ -530,7 +497,7 @@ static void aem_delete(struct aem_data *data) | |||
| 530 | ipmi_destroy_user(data->ipmi.user); | 497 | ipmi_destroy_user(data->ipmi.user); |
| 531 | platform_set_drvdata(data->pdev, NULL); | 498 | platform_set_drvdata(data->pdev, NULL); |
| 532 | platform_device_unregister(data->pdev); | 499 | platform_device_unregister(data->pdev); |
| 533 | aem_idr_put(data->id); | 500 | ida_simple_remove(&aem_ida, data->id); |
| 534 | kfree(data); | 501 | kfree(data); |
| 535 | } | 502 | } |
| 536 | 503 | ||
| @@ -587,7 +554,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) | |||
| 587 | data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; | 554 | data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; |
| 588 | 555 | ||
| 589 | /* Create sub-device for this fw instance */ | 556 | /* Create sub-device for this fw instance */ |
| 590 | if (aem_idr_get(&data->id)) | 557 | data->id = ida_simple_get(&aem_ida, 0, 0, GFP_KERNEL); |
| 558 | if (data->id < 0) | ||
| 591 | goto id_err; | 559 | goto id_err; |
| 592 | 560 | ||
| 593 | data->pdev = platform_device_alloc(DRVNAME, data->id); | 561 | data->pdev = platform_device_alloc(DRVNAME, data->id); |
| @@ -638,7 +606,7 @@ ipmi_err: | |||
| 638 | platform_set_drvdata(data->pdev, NULL); | 606 | platform_set_drvdata(data->pdev, NULL); |
| 639 | platform_device_unregister(data->pdev); | 607 | platform_device_unregister(data->pdev); |
| 640 | dev_err: | 608 | dev_err: |
| 641 | aem_idr_put(data->id); | 609 | ida_simple_remove(&aem_ida, data->id); |
| 642 | id_err: | 610 | id_err: |
| 643 | kfree(data); | 611 | kfree(data); |
| 644 | 612 | ||
| @@ -720,7 +688,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, | |||
| 720 | data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; | 688 | data->power_period[i] = AEM_DEFAULT_POWER_INTERVAL; |
| 721 | 689 | ||
| 722 | /* Create sub-device for this fw instance */ | 690 | /* Create sub-device for this fw instance */ |
| 723 | if (aem_idr_get(&data->id)) | 691 | data->id = ida_simple_get(&aem_ida, 0, 0, GFP_KERNEL); |
| 692 | if (data->id < 0) | ||
| 724 | goto id_err; | 693 | goto id_err; |
| 725 | 694 | ||
| 726 | data->pdev = platform_device_alloc(DRVNAME, data->id); | 695 | data->pdev = platform_device_alloc(DRVNAME, data->id); |
| @@ -771,7 +740,7 @@ ipmi_err: | |||
| 771 | platform_set_drvdata(data->pdev, NULL); | 740 | platform_set_drvdata(data->pdev, NULL); |
| 772 | platform_device_unregister(data->pdev); | 741 | platform_device_unregister(data->pdev); |
| 773 | dev_err: | 742 | dev_err: |
| 774 | aem_idr_put(data->id); | 743 | ida_simple_remove(&aem_ida, data->id); |
| 775 | id_err: | 744 | id_err: |
| 776 | kfree(data); | 745 | kfree(data); |
| 777 | 746 | ||
diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index b645e558876f..9155f91d66bf 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, | |||
| 136 | 136 | ||
| 137 | down_write(¤t->mm->mmap_sem); | 137 | down_write(¤t->mm->mmap_sem); |
| 138 | 138 | ||
| 139 | locked = npages + current->mm->locked_vm; | 139 | locked = npages + current->mm->pinned_vm; |
| 140 | lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; | 140 | lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; |
| 141 | 141 | ||
| 142 | if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) { | 142 | if ((locked > lock_limit) && !capable(CAP_IPC_LOCK)) { |
| @@ -206,7 +206,7 @@ out: | |||
| 206 | __ib_umem_release(context->device, umem, 0); | 206 | __ib_umem_release(context->device, umem, 0); |
| 207 | kfree(umem); | 207 | kfree(umem); |
| 208 | } else | 208 | } else |
| 209 | current->mm->locked_vm = locked; | 209 | current->mm->pinned_vm = locked; |
| 210 | 210 | ||
| 211 | up_write(¤t->mm->mmap_sem); | 211 | up_write(¤t->mm->mmap_sem); |
| 212 | if (vma_list) | 212 | if (vma_list) |
| @@ -222,7 +222,7 @@ static void ib_umem_account(struct work_struct *work) | |||
| 222 | struct ib_umem *umem = container_of(work, struct ib_umem, work); | 222 | struct ib_umem *umem = container_of(work, struct ib_umem, work); |
| 223 | 223 | ||
| 224 | down_write(&umem->mm->mmap_sem); | 224 | down_write(&umem->mm->mmap_sem); |
| 225 | umem->mm->locked_vm -= umem->diff; | 225 | umem->mm->pinned_vm -= umem->diff; |
| 226 | up_write(&umem->mm->mmap_sem); | 226 | up_write(&umem->mm->mmap_sem); |
| 227 | mmput(umem->mm); | 227 | mmput(umem->mm); |
| 228 | kfree(umem); | 228 | kfree(umem); |
diff --git a/drivers/infiniband/hw/ipath/ipath_user_pages.c b/drivers/infiniband/hw/ipath/ipath_user_pages.c index cfed5399f074..dc66c4506916 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, | |||
| 79 | goto bail_release; | 79 | goto bail_release; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | current->mm->locked_vm += num_pages; | 82 | current->mm->pinned_vm += num_pages; |
| 83 | 83 | ||
| 84 | ret = 0; | 84 | ret = 0; |
| 85 | goto bail; | 85 | goto bail; |
| @@ -178,7 +178,7 @@ void ipath_release_user_pages(struct page **p, size_t num_pages) | |||
| 178 | 178 | ||
| 179 | __ipath_release_user_pages(p, num_pages, 1); | 179 | __ipath_release_user_pages(p, num_pages, 1); |
| 180 | 180 | ||
| 181 | current->mm->locked_vm -= num_pages; | 181 | current->mm->pinned_vm -= num_pages; |
| 182 | 182 | ||
| 183 | up_write(¤t->mm->mmap_sem); | 183 | up_write(¤t->mm->mmap_sem); |
| 184 | } | 184 | } |
| @@ -195,7 +195,7 @@ static void user_pages_account(struct work_struct *_work) | |||
| 195 | container_of(_work, struct ipath_user_pages_work, work); | 195 | container_of(_work, struct ipath_user_pages_work, work); |
| 196 | 196 | ||
| 197 | down_write(&work->mm->mmap_sem); | 197 | down_write(&work->mm->mmap_sem); |
| 198 | work->mm->locked_vm -= work->num_pages; | 198 | work->mm->pinned_vm -= work->num_pages; |
| 199 | up_write(&work->mm->mmap_sem); | 199 | up_write(&work->mm->mmap_sem); |
| 200 | mmput(work->mm); | 200 | mmput(work->mm); |
| 201 | kfree(work); | 201 | kfree(work); |
diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c index 7689e49c13c9..2bc1d2b96298 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, | |||
| 74 | goto bail_release; | 74 | goto bail_release; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | current->mm->locked_vm += num_pages; | 77 | current->mm->pinned_vm += num_pages; |
| 78 | 78 | ||
| 79 | ret = 0; | 79 | ret = 0; |
| 80 | goto bail; | 80 | goto bail; |
| @@ -151,7 +151,7 @@ void qib_release_user_pages(struct page **p, size_t num_pages) | |||
| 151 | __qib_release_user_pages(p, num_pages, 1); | 151 | __qib_release_user_pages(p, num_pages, 1); |
| 152 | 152 | ||
| 153 | if (current->mm) { | 153 | if (current->mm) { |
| 154 | current->mm->locked_vm -= num_pages; | 154 | current->mm->pinned_vm -= num_pages; |
| 155 | up_write(¤t->mm->mmap_sem); | 155 | up_write(¤t->mm->mmap_sem); |
| 156 | } | 156 | } |
| 157 | } | 157 | } |
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c index 37e685eafd24..c4897e1075d8 100644 --- a/drivers/isdn/hisax/callc.c +++ b/drivers/isdn/hisax/callc.c | |||
| @@ -65,7 +65,7 @@ hisax_findcard(int driverid) | |||
| 65 | return (struct IsdnCardState *) 0; | 65 | return (struct IsdnCardState *) 0; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | static __attribute__((format(printf, 3, 4))) void | 68 | static __printf(3, 4) void |
| 69 | link_debug(struct Channel *chanp, int direction, char *fmt, ...) | 69 | link_debug(struct Channel *chanp, int direction, char *fmt, ...) |
| 70 | { | 70 | { |
| 71 | va_list args; | 71 | va_list args; |
| @@ -1068,7 +1068,7 @@ init_d_st(struct Channel *chanp) | |||
| 1068 | return 0; | 1068 | return 0; |
| 1069 | } | 1069 | } |
| 1070 | 1070 | ||
| 1071 | static __attribute__((format(printf, 2, 3))) void | 1071 | static __printf(2, 3) void |
| 1072 | callc_debug(struct FsmInst *fi, char *fmt, ...) | 1072 | callc_debug(struct FsmInst *fi, char *fmt, ...) |
| 1073 | { | 1073 | { |
| 1074 | va_list args; | 1074 | va_list args; |
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 0a5c42a3f125..aff45a11a92d 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h | |||
| @@ -1287,9 +1287,9 @@ int jiftime(char *s, long mark); | |||
| 1287 | 1287 | ||
| 1288 | int HiSax_command(isdn_ctrl * ic); | 1288 | int HiSax_command(isdn_ctrl * ic); |
| 1289 | int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); | 1289 | int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb); |
| 1290 | __attribute__((format(printf, 3, 4))) | 1290 | __printf(3, 4) |
| 1291 | void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); | 1291 | void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...); |
| 1292 | __attribute__((format(printf, 3, 0))) | 1292 | __printf(3, 0) |
| 1293 | void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); | 1293 | void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list args); |
| 1294 | void HiSax_reportcard(int cardnr, int sel); | 1294 | void HiSax_reportcard(int cardnr, int sel); |
| 1295 | int QuickHex(char *txt, u_char * p, int cnt); | 1295 | int QuickHex(char *txt, u_char * p, int cnt); |
diff --git a/drivers/isdn/hisax/isdnl1.h b/drivers/isdn/hisax/isdnl1.h index 425d86116f2b..66ddcab19bba 100644 --- a/drivers/isdn/hisax/isdnl1.h +++ b/drivers/isdn/hisax/isdnl1.h | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | #define B_XMTBUFREADY 1 | 21 | #define B_XMTBUFREADY 1 |
| 22 | #define B_ACKPENDING 2 | 22 | #define B_ACKPENDING 2 |
| 23 | 23 | ||
| 24 | __attribute__((format(printf, 2, 3))) | 24 | __printf(2, 3) |
| 25 | void debugl1(struct IsdnCardState *cs, char *fmt, ...); | 25 | void debugl1(struct IsdnCardState *cs, char *fmt, ...); |
| 26 | void DChannel_proc_xmt(struct IsdnCardState *cs); | 26 | void DChannel_proc_xmt(struct IsdnCardState *cs); |
| 27 | void DChannel_proc_rcv(struct IsdnCardState *cs); | 27 | void DChannel_proc_rcv(struct IsdnCardState *cs); |
diff --git a/drivers/isdn/hisax/isdnl3.c b/drivers/isdn/hisax/isdnl3.c index ad291f21b201..1c24e4457b6f 100644 --- a/drivers/isdn/hisax/isdnl3.c +++ b/drivers/isdn/hisax/isdnl3.c | |||
| @@ -66,7 +66,7 @@ static char *strL3Event[] = | |||
| 66 | "EV_TIMEOUT", | 66 | "EV_TIMEOUT", |
| 67 | }; | 67 | }; |
| 68 | 68 | ||
| 69 | static __attribute__((format(printf, 2, 3))) void | 69 | static __printf(2, 3) void |
| 70 | l3m_debug(struct FsmInst *fi, char *fmt, ...) | 70 | l3m_debug(struct FsmInst *fi, char *fmt, ...) |
| 71 | { | 71 | { |
| 72 | va_list args; | 72 | va_list args; |
diff --git a/drivers/isdn/hisax/st5481_d.c b/drivers/isdn/hisax/st5481_d.c index 44082637a09f..db247b79e561 100644 --- a/drivers/isdn/hisax/st5481_d.c +++ b/drivers/isdn/hisax/st5481_d.c | |||
| @@ -167,7 +167,7 @@ static struct FsmNode L1FnList[] __initdata = | |||
| 167 | {ST_L1_F8, EV_IND_RSY, l1_ignore}, | 167 | {ST_L1_F8, EV_IND_RSY, l1_ignore}, |
| 168 | }; | 168 | }; |
| 169 | 169 | ||
| 170 | static __attribute__((format(printf, 2, 3))) | 170 | static __printf(2, 3) |
| 171 | void l1m_debug(struct FsmInst *fi, char *fmt, ...) | 171 | void l1m_debug(struct FsmInst *fi, char *fmt, ...) |
| 172 | { | 172 | { |
| 173 | va_list args; | 173 | va_list args; |
| @@ -270,7 +270,7 @@ static char *strDoutEvent[] = | |||
| 270 | "EV_DOUT_UNDERRUN", | 270 | "EV_DOUT_UNDERRUN", |
| 271 | }; | 271 | }; |
| 272 | 272 | ||
| 273 | static __attribute__((format(printf, 2, 3))) | 273 | static __printf(2, 3) |
| 274 | void dout_debug(struct FsmInst *fi, char *fmt, ...) | 274 | void dout_debug(struct FsmInst *fi, char *fmt, ...) |
| 275 | { | 275 | { |
| 276 | va_list args; | 276 | va_list args; |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index dc7caaddecf4..ff203a421863 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
| @@ -375,6 +375,18 @@ config LEDS_ASIC3 | |||
| 375 | cannot be used. This driver supports hardware blinking with an on+off | 375 | cannot be used. This driver supports hardware blinking with an on+off |
| 376 | period from 62ms to 125s. Say Y to enable LEDs on the HP iPAQ hx4700. | 376 | period from 62ms to 125s. Say Y to enable LEDs on the HP iPAQ hx4700. |
| 377 | 377 | ||
| 378 | config LEDS_RENESAS_TPU | ||
| 379 | bool "LED support for Renesas TPU" | ||
| 380 | depends on LEDS_CLASS && HAVE_CLK && GENERIC_GPIO | ||
| 381 | help | ||
| 382 | This option enables build of the LED TPU platform driver, | ||
| 383 | suitable to drive any TPU channel on newer Renesas SoCs. | ||
| 384 | The driver controls the GPIO pin connected to the LED via | ||
| 385 | the GPIO framework and expects the LED to be connected to | ||
| 386 | a pin that can be driven in both GPIO mode and using TPU | ||
| 387 | pin function. The latter to support brightness control. | ||
| 388 | Brightness control is supported but hardware blinking is not. | ||
| 389 | |||
| 378 | config LEDS_TRIGGERS | 390 | config LEDS_TRIGGERS |
| 379 | bool "LED Trigger support" | 391 | bool "LED Trigger support" |
| 380 | depends on LEDS_CLASS | 392 | depends on LEDS_CLASS |
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index a0a1b89d78a8..e4f6bf568880 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
| @@ -42,6 +42,7 @@ obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o | |||
| 42 | obj-$(CONFIG_LEDS_NS2) += leds-ns2.o | 42 | obj-$(CONFIG_LEDS_NS2) += leds-ns2.o |
| 43 | obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o | 43 | obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o |
| 44 | obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o | 44 | obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o |
| 45 | obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o | ||
| 45 | 46 | ||
| 46 | # LED SPI Drivers | 47 | # LED SPI Drivers |
| 47 | obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o | 48 | obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o |
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index dc3d3d83191a..661b692573e7 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, | |||
| 267 | unsigned long *delay_on, | 267 | unsigned long *delay_on, |
| 268 | unsigned long *delay_off) | 268 | unsigned long *delay_off) |
| 269 | { | 269 | { |
| 270 | del_timer_sync(&led_cdev->blink_timer); | ||
| 271 | |||
| 270 | if (led_cdev->blink_set && | 272 | if (led_cdev->blink_set && |
| 271 | !led_cdev->blink_set(led_cdev, delay_on, delay_off)) | 273 | !led_cdev->blink_set(led_cdev, delay_on, delay_off)) { |
| 274 | led_cdev->blink_delay_on = *delay_on; | ||
| 275 | led_cdev->blink_delay_off = *delay_off; | ||
| 272 | return; | 276 | return; |
| 277 | } | ||
| 273 | 278 | ||
| 274 | /* blink with 1 Hz as default if nothing specified */ | 279 | /* blink with 1 Hz as default if nothing specified */ |
| 275 | if (!*delay_on && !*delay_off) | 280 | if (!*delay_on && !*delay_off) |
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 4bebae733349..6f1ff93d7cec 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) | |||
| 261 | if (trigger) { | 261 | if (trigger) { |
| 262 | trigger->name = name; | 262 | trigger->name = name; |
| 263 | err = led_trigger_register(trigger); | 263 | err = led_trigger_register(trigger); |
| 264 | if (err < 0) | 264 | if (err < 0) { |
| 265 | kfree(trigger); | ||
| 266 | trigger = NULL; | ||
| 265 | printk(KERN_WARNING "LED trigger %s failed to register" | 267 | printk(KERN_WARNING "LED trigger %s failed to register" |
| 266 | " (%d)\n", name, err); | 268 | " (%d)\n", name, err); |
| 269 | } | ||
| 267 | } else | 270 | } else |
| 268 | printk(KERN_WARNING "LED trigger %s failed to register" | 271 | printk(KERN_WARNING "LED trigger %s failed to register" |
| 269 | " (no memory)\n", name); | 272 | " (no memory)\n", name); |
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 3d8bc327a68d..504cc26c7e4b 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, | |||
| 121 | } | 121 | } |
| 122 | led_dat->cdev.brightness_set = gpio_led_set; | 122 | led_dat->cdev.brightness_set = gpio_led_set; |
| 123 | if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) | 123 | if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) |
| 124 | state = !!gpio_get_value(led_dat->gpio) ^ led_dat->active_low; | 124 | state = !!gpio_get_value_cansleep(led_dat->gpio) ^ led_dat->active_low; |
| 125 | else | 125 | else |
| 126 | state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); | 126 | state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); |
| 127 | led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; | 127 | led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; |
diff --git a/drivers/leds/leds-lm3530.c b/drivers/leds/leds-lm3530.c index 3dd7090a9a9b..4dc510fdfa06 100644 --- a/drivers/leds/leds-lm3530.c +++ b/drivers/leds/leds-lm3530.c | |||
| @@ -421,7 +421,6 @@ err_class_register: | |||
| 421 | err_reg_init: | 421 | err_reg_init: |
| 422 | regulator_put(drvdata->regulator); | 422 | regulator_put(drvdata->regulator); |
| 423 | err_regulator_get: | 423 | err_regulator_get: |
| 424 | i2c_set_clientdata(client, NULL); | ||
| 425 | kfree(drvdata); | 424 | kfree(drvdata); |
| 426 | err_out: | 425 | err_out: |
| 427 | return err; | 426 | return err; |
| @@ -449,7 +448,7 @@ MODULE_DEVICE_TABLE(i2c, lm3530_id); | |||
| 449 | 448 | ||
| 450 | static struct i2c_driver lm3530_i2c_driver = { | 449 | static struct i2c_driver lm3530_i2c_driver = { |
| 451 | .probe = lm3530_probe, | 450 | .probe = lm3530_probe, |
| 452 | .remove = lm3530_remove, | 451 | .remove = __devexit_p(lm3530_remove), |
| 453 | .id_table = lm3530_id, | 452 | .id_table = lm3530_id, |
| 454 | .driver = { | 453 | .driver = { |
| 455 | .name = LM3530_NAME, | 454 | .name = LM3530_NAME, |
diff --git a/drivers/leds/leds-lp5521.c b/drivers/leds/leds-lp5521.c index 9fc122c81f06..cb641f1b3342 100644 --- a/drivers/leds/leds-lp5521.c +++ b/drivers/leds/leds-lp5521.c | |||
| @@ -97,6 +97,9 @@ | |||
| 97 | /* Status */ | 97 | /* Status */ |
| 98 | #define LP5521_EXT_CLK_USED 0x08 | 98 | #define LP5521_EXT_CLK_USED 0x08 |
| 99 | 99 | ||
| 100 | /* default R channel current register value */ | ||
| 101 | #define LP5521_REG_R_CURR_DEFAULT 0xAF | ||
| 102 | |||
| 100 | struct lp5521_engine { | 103 | struct lp5521_engine { |
| 101 | int id; | 104 | int id; |
| 102 | u8 mode; | 105 | u8 mode; |
| @@ -175,14 +178,14 @@ static int lp5521_set_engine_mode(struct lp5521_engine *engine, u8 mode) | |||
| 175 | mode = LP5521_CMD_DIRECT; | 178 | mode = LP5521_CMD_DIRECT; |
| 176 | 179 | ||
| 177 | ret = lp5521_read(client, LP5521_REG_OP_MODE, &engine_state); | 180 | ret = lp5521_read(client, LP5521_REG_OP_MODE, &engine_state); |
| 181 | if (ret < 0) | ||
| 182 | return ret; | ||
| 178 | 183 | ||
| 179 | /* set mode only for this engine */ | 184 | /* set mode only for this engine */ |
| 180 | engine_state &= ~(engine->engine_mask); | 185 | engine_state &= ~(engine->engine_mask); |
| 181 | mode &= engine->engine_mask; | 186 | mode &= engine->engine_mask; |
| 182 | engine_state |= mode; | 187 | engine_state |= mode; |
| 183 | ret |= lp5521_write(client, LP5521_REG_OP_MODE, engine_state); | 188 | return lp5521_write(client, LP5521_REG_OP_MODE, engine_state); |
| 184 | |||
| 185 | return ret; | ||
| 186 | } | 189 | } |
| 187 | 190 | ||
| 188 | static int lp5521_load_program(struct lp5521_engine *eng, const u8 *pattern) | 191 | 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, | |||
| 643 | struct lp5521_chip *chip; | 646 | struct lp5521_chip *chip; |
| 644 | struct lp5521_platform_data *pdata; | 647 | struct lp5521_platform_data *pdata; |
| 645 | int ret, i, led; | 648 | int ret, i, led; |
| 649 | u8 buf; | ||
| 646 | 650 | ||
| 647 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 651 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
| 648 | if (!chip) | 652 | if (!chip) |
| @@ -681,6 +685,20 @@ static int __devinit lp5521_probe(struct i2c_client *client, | |||
| 681 | * Exact value is not available. 10 - 20ms | 685 | * Exact value is not available. 10 - 20ms |
| 682 | * appears to be enough for reset. | 686 | * appears to be enough for reset. |
| 683 | */ | 687 | */ |
| 688 | |||
| 689 | /* | ||
| 690 | * Make sure that the chip is reset by reading back the r channel | ||
| 691 | * current reg. This is dummy read is required on some platforms - | ||
| 692 | * otherwise further access to the R G B channels in the | ||
| 693 | * LP5521_REG_ENABLE register will not have any effect - strange! | ||
| 694 | */ | ||
| 695 | lp5521_read(client, LP5521_REG_R_CURRENT, &buf); | ||
| 696 | if (buf != LP5521_REG_R_CURR_DEFAULT) { | ||
| 697 | dev_err(&client->dev, "error in reseting chip\n"); | ||
| 698 | goto fail2; | ||
| 699 | } | ||
| 700 | usleep_range(10000, 20000); | ||
| 701 | |||
| 684 | ret = lp5521_detect(client); | 702 | ret = lp5521_detect(client); |
| 685 | 703 | ||
| 686 | if (ret) { | 704 | if (ret) { |
diff --git a/drivers/leds/leds-renesas-tpu.c b/drivers/leds/leds-renesas-tpu.c new file mode 100644 index 000000000000..3ee540eb127e --- /dev/null +++ b/drivers/leds/leds-renesas-tpu.c | |||
| @@ -0,0 +1,357 @@ | |||
| 1 | /* | ||
| 2 | * LED control using Renesas TPU | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 Magnus Damm | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/init.h> | ||
| 22 | #include <linux/platform_device.h> | ||
| 23 | #include <linux/spinlock.h> | ||
| 24 | #include <linux/printk.h> | ||
| 25 | #include <linux/ioport.h> | ||
| 26 | #include <linux/io.h> | ||
| 27 | #include <linux/clk.h> | ||
| 28 | #include <linux/leds.h> | ||
| 29 | #include <linux/platform_data/leds-renesas-tpu.h> | ||
| 30 | #include <linux/gpio.h> | ||
| 31 | #include <linux/err.h> | ||
| 32 | #include <linux/slab.h> | ||
| 33 | #include <linux/pm_runtime.h> | ||
| 34 | #include <linux/workqueue.h> | ||
| 35 | |||
| 36 | enum r_tpu_pin { R_TPU_PIN_UNUSED, R_TPU_PIN_GPIO, R_TPU_PIN_GPIO_FN }; | ||
| 37 | enum r_tpu_timer { R_TPU_TIMER_UNUSED, R_TPU_TIMER_ON }; | ||
| 38 | |||
| 39 | struct r_tpu_priv { | ||
| 40 | struct led_classdev ldev; | ||
| 41 | void __iomem *mapbase; | ||
| 42 | struct clk *clk; | ||
| 43 | struct platform_device *pdev; | ||
| 44 | enum r_tpu_pin pin_state; | ||
| 45 | enum r_tpu_timer timer_state; | ||
| 46 | unsigned long min_rate; | ||
| 47 | unsigned int refresh_rate; | ||
| 48 | struct work_struct work; | ||
| 49 | enum led_brightness new_brightness; | ||
| 50 | }; | ||
| 51 | |||
| 52 | static DEFINE_SPINLOCK(r_tpu_lock); | ||
| 53 | |||
| 54 | #define TSTR -1 /* Timer start register (shared register) */ | ||
| 55 | #define TCR 0 /* Timer control register (+0x00) */ | ||
| 56 | #define TMDR 1 /* Timer mode register (+0x04) */ | ||
| 57 | #define TIOR 2 /* Timer I/O control register (+0x08) */ | ||
| 58 | #define TIER 3 /* Timer interrupt enable register (+0x0c) */ | ||
| 59 | #define TSR 4 /* Timer status register (+0x10) */ | ||
| 60 | #define TCNT 5 /* Timer counter (+0x14) */ | ||
| 61 | #define TGRA 6 /* Timer general register A (+0x18) */ | ||
| 62 | #define TGRB 7 /* Timer general register B (+0x1c) */ | ||
| 63 | #define TGRC 8 /* Timer general register C (+0x20) */ | ||
| 64 | #define TGRD 9 /* Timer general register D (+0x24) */ | ||
| 65 | |||
| 66 | static inline unsigned short r_tpu_read(struct r_tpu_priv *p, int reg_nr) | ||
| 67 | { | ||
| 68 | struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; | ||
| 69 | void __iomem *base = p->mapbase; | ||
| 70 | unsigned long offs = reg_nr << 2; | ||
| 71 | |||
| 72 | if (reg_nr == TSTR) | ||
| 73 | return ioread16(base - cfg->channel_offset); | ||
| 74 | |||
| 75 | return ioread16(base + offs); | ||
| 76 | } | ||
| 77 | |||
| 78 | static inline void r_tpu_write(struct r_tpu_priv *p, int reg_nr, | ||
| 79 | unsigned short value) | ||
| 80 | { | ||
| 81 | struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; | ||
| 82 | void __iomem *base = p->mapbase; | ||
| 83 | unsigned long offs = reg_nr << 2; | ||
| 84 | |||
| 85 | if (reg_nr == TSTR) { | ||
| 86 | iowrite16(value, base - cfg->channel_offset); | ||
| 87 | return; | ||
| 88 | } | ||
| 89 | |||
| 90 | iowrite16(value, base + offs); | ||
| 91 | } | ||
| 92 | |||
| 93 | static void r_tpu_start_stop_ch(struct r_tpu_priv *p, int start) | ||
| 94 | { | ||
| 95 | struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; | ||
| 96 | unsigned long flags, value; | ||
| 97 | |||
| 98 | /* start stop register shared by multiple timer channels */ | ||
| 99 | spin_lock_irqsave(&r_tpu_lock, flags); | ||
| 100 | value = r_tpu_read(p, TSTR); | ||
| 101 | |||
| 102 | if (start) | ||
| 103 | value |= 1 << cfg->timer_bit; | ||
| 104 | else | ||
| 105 | value &= ~(1 << cfg->timer_bit); | ||
| 106 | |||
| 107 | r_tpu_write(p, TSTR, value); | ||
| 108 | spin_unlock_irqrestore(&r_tpu_lock, flags); | ||
| 109 | } | ||
| 110 | |||
| 111 | static int r_tpu_enable(struct r_tpu_priv *p, enum led_brightness brightness) | ||
| 112 | { | ||
| 113 | struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; | ||
| 114 | int prescaler[] = { 1, 4, 16, 64 }; | ||
| 115 | int k, ret; | ||
| 116 | unsigned long rate, tmp; | ||
| 117 | |||
| 118 | if (p->timer_state == R_TPU_TIMER_ON) | ||
| 119 | return 0; | ||
| 120 | |||
| 121 | /* wake up device and enable clock */ | ||
| 122 | pm_runtime_get_sync(&p->pdev->dev); | ||
| 123 | ret = clk_enable(p->clk); | ||
| 124 | if (ret) { | ||
| 125 | dev_err(&p->pdev->dev, "cannot enable clock\n"); | ||
| 126 | return ret; | ||
| 127 | } | ||
| 128 | |||
| 129 | /* make sure channel is disabled */ | ||
| 130 | r_tpu_start_stop_ch(p, 0); | ||
| 131 | |||
| 132 | /* get clock rate after enabling it */ | ||
| 133 | rate = clk_get_rate(p->clk); | ||
| 134 | |||
| 135 | /* pick the lowest acceptable rate */ | ||
| 136 | for (k = 0; k < ARRAY_SIZE(prescaler); k++) | ||
| 137 | if ((rate / prescaler[k]) < p->min_rate) | ||
| 138 | break; | ||
| 139 | |||
| 140 | if (!k) { | ||
| 141 | dev_err(&p->pdev->dev, "clock rate mismatch\n"); | ||
| 142 | goto err0; | ||
| 143 | } | ||
| 144 | dev_dbg(&p->pdev->dev, "rate = %lu, prescaler %u\n", | ||
| 145 | rate, prescaler[k - 1]); | ||
| 146 | |||
| 147 | /* clear TCNT on TGRB match, count on rising edge, set prescaler */ | ||
| 148 | r_tpu_write(p, TCR, 0x0040 | (k - 1)); | ||
| 149 | |||
| 150 | /* output 0 until TGRA, output 1 until TGRB */ | ||
| 151 | r_tpu_write(p, TIOR, 0x0002); | ||
| 152 | |||
| 153 | rate /= prescaler[k - 1] * p->refresh_rate; | ||
| 154 | r_tpu_write(p, TGRB, rate); | ||
| 155 | dev_dbg(&p->pdev->dev, "TRGB = 0x%04lx\n", rate); | ||
| 156 | |||
| 157 | tmp = (cfg->max_brightness - brightness) * rate; | ||
| 158 | r_tpu_write(p, TGRA, tmp / cfg->max_brightness); | ||
| 159 | dev_dbg(&p->pdev->dev, "TRGA = 0x%04lx\n", tmp / cfg->max_brightness); | ||
| 160 | |||
| 161 | /* PWM mode */ | ||
| 162 | r_tpu_write(p, TMDR, 0x0002); | ||
| 163 | |||
| 164 | /* enable channel */ | ||
| 165 | r_tpu_start_stop_ch(p, 1); | ||
| 166 | |||
| 167 | p->timer_state = R_TPU_TIMER_ON; | ||
| 168 | return 0; | ||
| 169 | err0: | ||
| 170 | clk_disable(p->clk); | ||
| 171 | pm_runtime_put_sync(&p->pdev->dev); | ||
| 172 | return -ENOTSUPP; | ||
| 173 | } | ||
| 174 | |||
| 175 | static void r_tpu_disable(struct r_tpu_priv *p) | ||
| 176 | { | ||
| 177 | if (p->timer_state == R_TPU_TIMER_UNUSED) | ||
| 178 | return; | ||
| 179 | |||
| 180 | /* disable channel */ | ||
| 181 | r_tpu_start_stop_ch(p, 0); | ||
| 182 | |||
| 183 | /* stop clock and mark device as idle */ | ||
| 184 | clk_disable(p->clk); | ||
| 185 | pm_runtime_put_sync(&p->pdev->dev); | ||
| 186 | |||
| 187 | p->timer_state = R_TPU_TIMER_UNUSED; | ||
| 188 | } | ||
| 189 | |||
| 190 | static void r_tpu_set_pin(struct r_tpu_priv *p, enum r_tpu_pin new_state, | ||
| 191 | enum led_brightness brightness) | ||
| 192 | { | ||
| 193 | struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; | ||
| 194 | |||
| 195 | if (p->pin_state == new_state) { | ||
| 196 | if (p->pin_state == R_TPU_PIN_GPIO) | ||
| 197 | gpio_set_value(cfg->pin_gpio, brightness); | ||
| 198 | return; | ||
| 199 | } | ||
| 200 | |||
| 201 | if (p->pin_state == R_TPU_PIN_GPIO) | ||
| 202 | gpio_free(cfg->pin_gpio); | ||
| 203 | |||
| 204 | if (p->pin_state == R_TPU_PIN_GPIO_FN) | ||
| 205 | gpio_free(cfg->pin_gpio_fn); | ||
| 206 | |||
| 207 | if (new_state == R_TPU_PIN_GPIO) { | ||
| 208 | gpio_request(cfg->pin_gpio, cfg->name); | ||
| 209 | gpio_direction_output(cfg->pin_gpio, !!brightness); | ||
| 210 | } | ||
| 211 | if (new_state == R_TPU_PIN_GPIO_FN) | ||
| 212 | gpio_request(cfg->pin_gpio_fn, cfg->name); | ||
| 213 | |||
| 214 | p->pin_state = new_state; | ||
| 215 | } | ||
| 216 | |||
| 217 | static void r_tpu_work(struct work_struct *work) | ||
| 218 | { | ||
| 219 | struct r_tpu_priv *p = container_of(work, struct r_tpu_priv, work); | ||
| 220 | enum led_brightness brightness = p->new_brightness; | ||
| 221 | |||
| 222 | r_tpu_disable(p); | ||
| 223 | |||
| 224 | /* off and maximum are handled as GPIO pins, in between PWM */ | ||
| 225 | if ((brightness == 0) || (brightness == p->ldev.max_brightness)) | ||
| 226 | r_tpu_set_pin(p, R_TPU_PIN_GPIO, brightness); | ||
| 227 | else { | ||
| 228 | r_tpu_set_pin(p, R_TPU_PIN_GPIO_FN, 0); | ||
| 229 | r_tpu_enable(p, brightness); | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 233 | static void r_tpu_set_brightness(struct led_classdev *ldev, | ||
| 234 | enum led_brightness brightness) | ||
| 235 | { | ||
| 236 | struct r_tpu_priv *p = container_of(ldev, struct r_tpu_priv, ldev); | ||
| 237 | p->new_brightness = brightness; | ||
| 238 | schedule_work(&p->work); | ||
| 239 | } | ||
| 240 | |||
| 241 | static int __devinit r_tpu_probe(struct platform_device *pdev) | ||
| 242 | { | ||
| 243 | struct led_renesas_tpu_config *cfg = pdev->dev.platform_data; | ||
| 244 | struct r_tpu_priv *p; | ||
| 245 | struct resource *res; | ||
| 246 | int ret = -ENXIO; | ||
| 247 | |||
| 248 | if (!cfg) { | ||
| 249 | dev_err(&pdev->dev, "missing platform data\n"); | ||
| 250 | goto err0; | ||
| 251 | } | ||
| 252 | |||
| 253 | p = kzalloc(sizeof(*p), GFP_KERNEL); | ||
| 254 | if (p == NULL) { | ||
| 255 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | ||
| 256 | ret = -ENOMEM; | ||
| 257 | goto err0; | ||
| 258 | } | ||
| 259 | |||
| 260 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 261 | if (!res) { | ||
| 262 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | ||
| 263 | goto err1; | ||
| 264 | } | ||
| 265 | |||
| 266 | /* map memory, let mapbase point to our channel */ | ||
| 267 | p->mapbase = ioremap_nocache(res->start, resource_size(res)); | ||
| 268 | if (p->mapbase == NULL) { | ||
| 269 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
| 270 | goto err1; | ||
| 271 | } | ||
| 272 | |||
| 273 | /* get hold of clock */ | ||
| 274 | p->clk = clk_get(&pdev->dev, NULL); | ||
| 275 | if (IS_ERR(p->clk)) { | ||
| 276 | dev_err(&pdev->dev, "cannot get clock\n"); | ||
| 277 | ret = PTR_ERR(p->clk); | ||
| 278 | goto err2; | ||
| 279 | } | ||
| 280 | |||
| 281 | p->pdev = pdev; | ||
| 282 | p->pin_state = R_TPU_PIN_UNUSED; | ||
| 283 | p->timer_state = R_TPU_TIMER_UNUSED; | ||
| 284 | p->refresh_rate = cfg->refresh_rate ? cfg->refresh_rate : 100; | ||
| 285 | r_tpu_set_pin(p, R_TPU_PIN_GPIO, LED_OFF); | ||
| 286 | platform_set_drvdata(pdev, p); | ||
| 287 | |||
| 288 | INIT_WORK(&p->work, r_tpu_work); | ||
| 289 | |||
| 290 | p->ldev.name = cfg->name; | ||
| 291 | p->ldev.brightness = LED_OFF; | ||
| 292 | p->ldev.max_brightness = cfg->max_brightness; | ||
| 293 | p->ldev.brightness_set = r_tpu_set_brightness; | ||
| 294 | p->ldev.flags |= LED_CORE_SUSPENDRESUME; | ||
| 295 | ret = led_classdev_register(&pdev->dev, &p->ldev); | ||
| 296 | if (ret < 0) | ||
| 297 | goto err3; | ||
| 298 | |||
| 299 | /* max_brightness may be updated by the LED core code */ | ||
| 300 | p->min_rate = p->ldev.max_brightness * p->refresh_rate; | ||
| 301 | |||
| 302 | pm_runtime_enable(&pdev->dev); | ||
| 303 | return 0; | ||
| 304 | |||
| 305 | err3: | ||
| 306 | r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF); | ||
| 307 | clk_put(p->clk); | ||
| 308 | err2: | ||
| 309 | iounmap(p->mapbase); | ||
| 310 | err1: | ||
| 311 | kfree(p); | ||
| 312 | err0: | ||
| 313 | return ret; | ||
| 314 | } | ||
| 315 | |||
| 316 | static int __devexit r_tpu_remove(struct platform_device *pdev) | ||
| 317 | { | ||
| 318 | struct r_tpu_priv *p = platform_get_drvdata(pdev); | ||
| 319 | |||
| 320 | r_tpu_set_brightness(&p->ldev, LED_OFF); | ||
| 321 | led_classdev_unregister(&p->ldev); | ||
| 322 | cancel_work_sync(&p->work); | ||
| 323 | r_tpu_disable(p); | ||
| 324 | r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF); | ||
| 325 | |||
| 326 | pm_runtime_disable(&pdev->dev); | ||
| 327 | clk_put(p->clk); | ||
| 328 | |||
| 329 | iounmap(p->mapbase); | ||
| 330 | kfree(p); | ||
| 331 | return 0; | ||
| 332 | } | ||
| 333 | |||
| 334 | static struct platform_driver r_tpu_device_driver = { | ||
| 335 | .probe = r_tpu_probe, | ||
| 336 | .remove = __devexit_p(r_tpu_remove), | ||
| 337 | .driver = { | ||
| 338 | .name = "leds-renesas-tpu", | ||
| 339 | } | ||
| 340 | }; | ||
| 341 | |||
| 342 | static int __init r_tpu_init(void) | ||
| 343 | { | ||
| 344 | return platform_driver_register(&r_tpu_device_driver); | ||
| 345 | } | ||
| 346 | |||
| 347 | static void __exit r_tpu_exit(void) | ||
| 348 | { | ||
| 349 | platform_driver_unregister(&r_tpu_device_driver); | ||
| 350 | } | ||
| 351 | |||
| 352 | module_init(r_tpu_init); | ||
| 353 | module_exit(r_tpu_exit); | ||
| 354 | |||
| 355 | MODULE_AUTHOR("Magnus Damm"); | ||
| 356 | MODULE_DESCRIPTION("Renesas TPU LED Driver"); | ||
| 357 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index 4ff73c215746..a39e0555df63 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[] = { | |||
| 98 | {"ad5282", AD5282_ID}, | 98 | {"ad5282", AD5282_ID}, |
| 99 | {"adn2860", ADN2860_ID}, | 99 | {"adn2860", ADN2860_ID}, |
| 100 | {"ad5273", AD5273_ID}, | 100 | {"ad5273", AD5273_ID}, |
| 101 | {"ad5161", AD5161_ID}, | ||
| 101 | {"ad5171", AD5171_ID}, | 102 | {"ad5171", AD5171_ID}, |
| 102 | {"ad5170", AD5170_ID}, | 103 | {"ad5170", AD5170_ID}, |
| 103 | {"ad5172", AD5172_ID}, | 104 | {"ad5172", AD5172_ID}, |
diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c index 27dc0d21aafa..f6586d53e1a3 100644 --- a/drivers/misc/fsa9480.c +++ b/drivers/misc/fsa9480.c | |||
| @@ -400,7 +400,8 @@ static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw) | |||
| 400 | return ret; | 400 | return ret; |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | device_init_wakeup(&client->dev, pdata->wakeup); | 403 | if (pdata) |
| 404 | device_init_wakeup(&client->dev, pdata->wakeup); | ||
| 404 | } | 405 | } |
| 405 | 406 | ||
| 406 | return 0; | 407 | return 0; |
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index 8b51cd62d067..29d12a70eb1b 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) | |||
| 163 | int i; | 163 | int i; |
| 164 | 164 | ||
| 165 | if (lis3->blkread) { | 165 | if (lis3->blkread) { |
| 166 | if (lis3_dev.whoami == WAI_12B) { | 166 | if (lis3->whoami == WAI_12B) { |
| 167 | u16 data[3]; | 167 | u16 data[3]; |
| 168 | lis3->blkread(lis3, OUTX_L, 6, (u8 *)data); | 168 | lis3->blkread(lis3, OUTX_L, 6, (u8 *)data); |
| 169 | for (i = 0; i < 3; i++) | 169 | for (i = 0; i < 3; i++) |
| @@ -195,18 +195,30 @@ static int lis3_8_rates[2] = {100, 400}; | |||
| 195 | static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000}; | 195 | static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000}; |
| 196 | 196 | ||
| 197 | /* ODR is Output Data Rate */ | 197 | /* ODR is Output Data Rate */ |
| 198 | static int lis3lv02d_get_odr(void) | 198 | static int lis3lv02d_get_odr(struct lis3lv02d *lis3) |
| 199 | { | 199 | { |
| 200 | u8 ctrl; | 200 | u8 ctrl; |
| 201 | int shift; | 201 | int shift; |
| 202 | 202 | ||
| 203 | lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); | 203 | lis3->read(lis3, CTRL_REG1, &ctrl); |
| 204 | ctrl &= lis3_dev.odr_mask; | 204 | ctrl &= lis3->odr_mask; |
| 205 | shift = ffs(lis3_dev.odr_mask) - 1; | 205 | shift = ffs(lis3->odr_mask) - 1; |
| 206 | return lis3_dev.odrs[(ctrl >> shift)]; | 206 | return lis3->odrs[(ctrl >> shift)]; |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | static int lis3lv02d_set_odr(int rate) | 209 | static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3) |
| 210 | { | ||
| 211 | int div = lis3lv02d_get_odr(lis3); | ||
| 212 | |||
| 213 | if (WARN_ONCE(div == 0, "device returned spurious data")) | ||
| 214 | return -ENXIO; | ||
| 215 | |||
| 216 | /* LIS3 power on delay is quite long */ | ||
| 217 | msleep(lis3->pwron_delay / div); | ||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 221 | static int lis3lv02d_set_odr(struct lis3lv02d *lis3, int rate) | ||
| 210 | { | 222 | { |
| 211 | u8 ctrl; | 223 | u8 ctrl; |
| 212 | int i, len, shift; | 224 | int i, len, shift; |
| @@ -214,14 +226,14 @@ static int lis3lv02d_set_odr(int rate) | |||
| 214 | if (!rate) | 226 | if (!rate) |
| 215 | return -EINVAL; | 227 | return -EINVAL; |
| 216 | 228 | ||
| 217 | lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); | 229 | lis3->read(lis3, CTRL_REG1, &ctrl); |
| 218 | ctrl &= ~lis3_dev.odr_mask; | 230 | ctrl &= ~lis3->odr_mask; |
| 219 | len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */ | 231 | len = 1 << hweight_long(lis3->odr_mask); /* # of possible values */ |
| 220 | shift = ffs(lis3_dev.odr_mask) - 1; | 232 | shift = ffs(lis3->odr_mask) - 1; |
| 221 | 233 | ||
| 222 | for (i = 0; i < len; i++) | 234 | for (i = 0; i < len; i++) |
| 223 | if (lis3_dev.odrs[i] == rate) { | 235 | if (lis3->odrs[i] == rate) { |
| 224 | lis3_dev.write(&lis3_dev, CTRL_REG1, | 236 | lis3->write(lis3, CTRL_REG1, |
| 225 | ctrl | (i << shift)); | 237 | ctrl | (i << shift)); |
| 226 | return 0; | 238 | return 0; |
| 227 | } | 239 | } |
| @@ -240,12 +252,12 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | |||
| 240 | mutex_lock(&lis3->mutex); | 252 | mutex_lock(&lis3->mutex); |
| 241 | 253 | ||
| 242 | irq_cfg = lis3->irq_cfg; | 254 | irq_cfg = lis3->irq_cfg; |
| 243 | if (lis3_dev.whoami == WAI_8B) { | 255 | if (lis3->whoami == WAI_8B) { |
| 244 | lis3->data_ready_count[IRQ_LINE0] = 0; | 256 | lis3->data_ready_count[IRQ_LINE0] = 0; |
| 245 | lis3->data_ready_count[IRQ_LINE1] = 0; | 257 | lis3->data_ready_count[IRQ_LINE1] = 0; |
| 246 | 258 | ||
| 247 | /* Change interrupt cfg to data ready for selftest */ | 259 | /* Change interrupt cfg to data ready for selftest */ |
| 248 | atomic_inc(&lis3_dev.wake_thread); | 260 | atomic_inc(&lis3->wake_thread); |
| 249 | lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY; | 261 | lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY; |
| 250 | lis3->read(lis3, CTRL_REG3, &ctrl_reg_data); | 262 | lis3->read(lis3, CTRL_REG3, &ctrl_reg_data); |
| 251 | lis3->write(lis3, CTRL_REG3, (ctrl_reg_data & | 263 | lis3->write(lis3, CTRL_REG3, (ctrl_reg_data & |
| @@ -253,12 +265,12 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | |||
| 253 | (LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY)); | 265 | (LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY)); |
| 254 | } | 266 | } |
| 255 | 267 | ||
| 256 | if (lis3_dev.whoami == WAI_3DC) { | 268 | if (lis3->whoami == WAI_3DC) { |
| 257 | ctlreg = CTRL_REG4; | 269 | ctlreg = CTRL_REG4; |
| 258 | selftest = CTRL4_ST0; | 270 | selftest = CTRL4_ST0; |
| 259 | } else { | 271 | } else { |
| 260 | ctlreg = CTRL_REG1; | 272 | ctlreg = CTRL_REG1; |
| 261 | if (lis3_dev.whoami == WAI_12B) | 273 | if (lis3->whoami == WAI_12B) |
| 262 | selftest = CTRL1_ST; | 274 | selftest = CTRL1_ST; |
| 263 | else | 275 | else |
| 264 | selftest = CTRL1_STP; | 276 | selftest = CTRL1_STP; |
| @@ -266,7 +278,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | |||
| 266 | 278 | ||
| 267 | lis3->read(lis3, ctlreg, ®); | 279 | lis3->read(lis3, ctlreg, ®); |
| 268 | lis3->write(lis3, ctlreg, (reg | selftest)); | 280 | lis3->write(lis3, ctlreg, (reg | selftest)); |
| 269 | msleep(lis3->pwron_delay / lis3lv02d_get_odr()); | 281 | ret = lis3lv02d_get_pwron_wait(lis3); |
| 282 | if (ret) | ||
| 283 | goto fail; | ||
| 270 | 284 | ||
| 271 | /* Read directly to avoid axis remap */ | 285 | /* Read directly to avoid axis remap */ |
| 272 | x = lis3->read_data(lis3, OUTX); | 286 | x = lis3->read_data(lis3, OUTX); |
| @@ -275,7 +289,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | |||
| 275 | 289 | ||
| 276 | /* back to normal settings */ | 290 | /* back to normal settings */ |
| 277 | lis3->write(lis3, ctlreg, reg); | 291 | lis3->write(lis3, ctlreg, reg); |
| 278 | msleep(lis3->pwron_delay / lis3lv02d_get_odr()); | 292 | ret = lis3lv02d_get_pwron_wait(lis3); |
| 293 | if (ret) | ||
| 294 | goto fail; | ||
| 279 | 295 | ||
| 280 | results[0] = x - lis3->read_data(lis3, OUTX); | 296 | results[0] = x - lis3->read_data(lis3, OUTX); |
| 281 | results[1] = y - lis3->read_data(lis3, OUTY); | 297 | results[1] = y - lis3->read_data(lis3, OUTY); |
| @@ -283,9 +299,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | |||
| 283 | 299 | ||
| 284 | ret = 0; | 300 | ret = 0; |
| 285 | 301 | ||
| 286 | if (lis3_dev.whoami == WAI_8B) { | 302 | if (lis3->whoami == WAI_8B) { |
| 287 | /* Restore original interrupt configuration */ | 303 | /* Restore original interrupt configuration */ |
| 288 | atomic_dec(&lis3_dev.wake_thread); | 304 | atomic_dec(&lis3->wake_thread); |
| 289 | lis3->write(lis3, CTRL_REG3, ctrl_reg_data); | 305 | lis3->write(lis3, CTRL_REG3, ctrl_reg_data); |
| 290 | lis3->irq_cfg = irq_cfg; | 306 | lis3->irq_cfg = irq_cfg; |
| 291 | 307 | ||
| @@ -363,8 +379,9 @@ void lis3lv02d_poweroff(struct lis3lv02d *lis3) | |||
| 363 | } | 379 | } |
| 364 | EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); | 380 | EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); |
| 365 | 381 | ||
| 366 | void lis3lv02d_poweron(struct lis3lv02d *lis3) | 382 | int lis3lv02d_poweron(struct lis3lv02d *lis3) |
| 367 | { | 383 | { |
| 384 | int err; | ||
| 368 | u8 reg; | 385 | u8 reg; |
| 369 | 386 | ||
| 370 | lis3->init(lis3); | 387 | lis3->init(lis3); |
| @@ -384,35 +401,41 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3) | |||
| 384 | lis3->write(lis3, CTRL_REG2, reg); | 401 | lis3->write(lis3, CTRL_REG2, reg); |
| 385 | } | 402 | } |
| 386 | 403 | ||
| 387 | /* LIS3 power on delay is quite long */ | 404 | err = lis3lv02d_get_pwron_wait(lis3); |
| 388 | msleep(lis3->pwron_delay / lis3lv02d_get_odr()); | 405 | if (err) |
| 406 | return err; | ||
| 389 | 407 | ||
| 390 | if (lis3->reg_ctrl) | 408 | if (lis3->reg_ctrl) |
| 391 | lis3_context_restore(lis3); | 409 | lis3_context_restore(lis3); |
| 410 | |||
| 411 | return 0; | ||
| 392 | } | 412 | } |
| 393 | EXPORT_SYMBOL_GPL(lis3lv02d_poweron); | 413 | EXPORT_SYMBOL_GPL(lis3lv02d_poweron); |
| 394 | 414 | ||
| 395 | 415 | ||
| 396 | static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev) | 416 | static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev) |
| 397 | { | 417 | { |
| 418 | struct lis3lv02d *lis3 = pidev->private; | ||
| 398 | int x, y, z; | 419 | int x, y, z; |
| 399 | 420 | ||
| 400 | mutex_lock(&lis3_dev.mutex); | 421 | mutex_lock(&lis3->mutex); |
| 401 | lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); | 422 | lis3lv02d_get_xyz(lis3, &x, &y, &z); |
| 402 | input_report_abs(pidev->input, ABS_X, x); | 423 | input_report_abs(pidev->input, ABS_X, x); |
| 403 | input_report_abs(pidev->input, ABS_Y, y); | 424 | input_report_abs(pidev->input, ABS_Y, y); |
| 404 | input_report_abs(pidev->input, ABS_Z, z); | 425 | input_report_abs(pidev->input, ABS_Z, z); |
| 405 | input_sync(pidev->input); | 426 | input_sync(pidev->input); |
| 406 | mutex_unlock(&lis3_dev.mutex); | 427 | mutex_unlock(&lis3->mutex); |
| 407 | } | 428 | } |
| 408 | 429 | ||
| 409 | static void lis3lv02d_joystick_open(struct input_polled_dev *pidev) | 430 | static void lis3lv02d_joystick_open(struct input_polled_dev *pidev) |
| 410 | { | 431 | { |
| 411 | if (lis3_dev.pm_dev) | 432 | struct lis3lv02d *lis3 = pidev->private; |
| 412 | pm_runtime_get_sync(lis3_dev.pm_dev); | ||
| 413 | 433 | ||
| 414 | if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev) | 434 | if (lis3->pm_dev) |
| 415 | atomic_set(&lis3_dev.wake_thread, 1); | 435 | pm_runtime_get_sync(lis3->pm_dev); |
| 436 | |||
| 437 | if (lis3->pdata && lis3->whoami == WAI_8B && lis3->idev) | ||
| 438 | atomic_set(&lis3->wake_thread, 1); | ||
| 416 | /* | 439 | /* |
| 417 | * Update coordinates for the case where poll interval is 0 and | 440 | * Update coordinates for the case where poll interval is 0 and |
| 418 | * the chip in running purely under interrupt control | 441 | * the chip in running purely under interrupt control |
| @@ -422,14 +445,18 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev) | |||
| 422 | 445 | ||
| 423 | static void lis3lv02d_joystick_close(struct input_polled_dev *pidev) | 446 | static void lis3lv02d_joystick_close(struct input_polled_dev *pidev) |
| 424 | { | 447 | { |
| 425 | atomic_set(&lis3_dev.wake_thread, 0); | 448 | struct lis3lv02d *lis3 = pidev->private; |
| 426 | if (lis3_dev.pm_dev) | 449 | |
| 427 | pm_runtime_put(lis3_dev.pm_dev); | 450 | atomic_set(&lis3->wake_thread, 0); |
| 451 | if (lis3->pm_dev) | ||
| 452 | pm_runtime_put(lis3->pm_dev); | ||
| 428 | } | 453 | } |
| 429 | 454 | ||
| 430 | static irqreturn_t lis302dl_interrupt(int irq, void *dummy) | 455 | static irqreturn_t lis302dl_interrupt(int irq, void *data) |
| 431 | { | 456 | { |
| 432 | if (!test_bit(0, &lis3_dev.misc_opened)) | 457 | struct lis3lv02d *lis3 = data; |
| 458 | |||
| 459 | if (!test_bit(0, &lis3->misc_opened)) | ||
| 433 | goto out; | 460 | goto out; |
| 434 | 461 | ||
| 435 | /* | 462 | /* |
| @@ -437,12 +464,12 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy) | |||
| 437 | * the lid is closed. This leads to interrupts as soon as a little move | 464 | * the lid is closed. This leads to interrupts as soon as a little move |
| 438 | * is done. | 465 | * is done. |
| 439 | */ | 466 | */ |
| 440 | atomic_inc(&lis3_dev.count); | 467 | atomic_inc(&lis3->count); |
| 441 | 468 | ||
| 442 | wake_up_interruptible(&lis3_dev.misc_wait); | 469 | wake_up_interruptible(&lis3->misc_wait); |
| 443 | kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); | 470 | kill_fasync(&lis3->async_queue, SIGIO, POLL_IN); |
| 444 | out: | 471 | out: |
| 445 | if (atomic_read(&lis3_dev.wake_thread)) | 472 | if (atomic_read(&lis3->wake_thread)) |
| 446 | return IRQ_WAKE_THREAD; | 473 | return IRQ_WAKE_THREAD; |
| 447 | return IRQ_HANDLED; | 474 | return IRQ_HANDLED; |
| 448 | } | 475 | } |
| @@ -514,28 +541,37 @@ static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data) | |||
| 514 | 541 | ||
| 515 | static int lis3lv02d_misc_open(struct inode *inode, struct file *file) | 542 | static int lis3lv02d_misc_open(struct inode *inode, struct file *file) |
| 516 | { | 543 | { |
| 517 | if (test_and_set_bit(0, &lis3_dev.misc_opened)) | 544 | struct lis3lv02d *lis3 = container_of(file->private_data, |
| 545 | struct lis3lv02d, miscdev); | ||
| 546 | |||
| 547 | if (test_and_set_bit(0, &lis3->misc_opened)) | ||
| 518 | return -EBUSY; /* already open */ | 548 | return -EBUSY; /* already open */ |
| 519 | 549 | ||
| 520 | if (lis3_dev.pm_dev) | 550 | if (lis3->pm_dev) |
| 521 | pm_runtime_get_sync(lis3_dev.pm_dev); | 551 | pm_runtime_get_sync(lis3->pm_dev); |
| 522 | 552 | ||
| 523 | atomic_set(&lis3_dev.count, 0); | 553 | atomic_set(&lis3->count, 0); |
| 524 | return 0; | 554 | return 0; |
| 525 | } | 555 | } |
| 526 | 556 | ||
| 527 | static int lis3lv02d_misc_release(struct inode *inode, struct file *file) | 557 | static int lis3lv02d_misc_release(struct inode *inode, struct file *file) |
| 528 | { | 558 | { |
| 529 | fasync_helper(-1, file, 0, &lis3_dev.async_queue); | 559 | struct lis3lv02d *lis3 = container_of(file->private_data, |
| 530 | clear_bit(0, &lis3_dev.misc_opened); /* release the device */ | 560 | struct lis3lv02d, miscdev); |
| 531 | if (lis3_dev.pm_dev) | 561 | |
| 532 | pm_runtime_put(lis3_dev.pm_dev); | 562 | fasync_helper(-1, file, 0, &lis3->async_queue); |
| 563 | clear_bit(0, &lis3->misc_opened); /* release the device */ | ||
| 564 | if (lis3->pm_dev) | ||
| 565 | pm_runtime_put(lis3->pm_dev); | ||
| 533 | return 0; | 566 | return 0; |
| 534 | } | 567 | } |
| 535 | 568 | ||
| 536 | static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, | 569 | static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, |
| 537 | size_t count, loff_t *pos) | 570 | size_t count, loff_t *pos) |
| 538 | { | 571 | { |
| 572 | struct lis3lv02d *lis3 = container_of(file->private_data, | ||
| 573 | struct lis3lv02d, miscdev); | ||
| 574 | |||
| 539 | DECLARE_WAITQUEUE(wait, current); | 575 | DECLARE_WAITQUEUE(wait, current); |
| 540 | u32 data; | 576 | u32 data; |
| 541 | unsigned char byte_data; | 577 | unsigned char byte_data; |
| @@ -544,10 +580,10 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, | |||
| 544 | if (count < 1) | 580 | if (count < 1) |
| 545 | return -EINVAL; | 581 | return -EINVAL; |
| 546 | 582 | ||
| 547 | add_wait_queue(&lis3_dev.misc_wait, &wait); | 583 | add_wait_queue(&lis3->misc_wait, &wait); |
| 548 | while (true) { | 584 | while (true) { |
| 549 | set_current_state(TASK_INTERRUPTIBLE); | 585 | set_current_state(TASK_INTERRUPTIBLE); |
| 550 | data = atomic_xchg(&lis3_dev.count, 0); | 586 | data = atomic_xchg(&lis3->count, 0); |
| 551 | if (data) | 587 | if (data) |
| 552 | break; | 588 | break; |
| 553 | 589 | ||
| @@ -577,22 +613,28 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, | |||
| 577 | 613 | ||
| 578 | out: | 614 | out: |
| 579 | __set_current_state(TASK_RUNNING); | 615 | __set_current_state(TASK_RUNNING); |
| 580 | remove_wait_queue(&lis3_dev.misc_wait, &wait); | 616 | remove_wait_queue(&lis3->misc_wait, &wait); |
| 581 | 617 | ||
| 582 | return retval; | 618 | return retval; |
| 583 | } | 619 | } |
| 584 | 620 | ||
| 585 | static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait) | 621 | static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait) |
| 586 | { | 622 | { |
| 587 | poll_wait(file, &lis3_dev.misc_wait, wait); | 623 | struct lis3lv02d *lis3 = container_of(file->private_data, |
| 588 | if (atomic_read(&lis3_dev.count)) | 624 | struct lis3lv02d, miscdev); |
| 625 | |||
| 626 | poll_wait(file, &lis3->misc_wait, wait); | ||
| 627 | if (atomic_read(&lis3->count)) | ||
| 589 | return POLLIN | POLLRDNORM; | 628 | return POLLIN | POLLRDNORM; |
| 590 | return 0; | 629 | return 0; |
| 591 | } | 630 | } |
| 592 | 631 | ||
| 593 | static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) | 632 | static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) |
| 594 | { | 633 | { |
| 595 | return fasync_helper(fd, file, on, &lis3_dev.async_queue); | 634 | struct lis3lv02d *lis3 = container_of(file->private_data, |
| 635 | struct lis3lv02d, miscdev); | ||
| 636 | |||
| 637 | return fasync_helper(fd, file, on, &lis3->async_queue); | ||
| 596 | } | 638 | } |
| 597 | 639 | ||
| 598 | static const struct file_operations lis3lv02d_misc_fops = { | 640 | static const struct file_operations lis3lv02d_misc_fops = { |
| @@ -605,85 +647,80 @@ static const struct file_operations lis3lv02d_misc_fops = { | |||
| 605 | .fasync = lis3lv02d_misc_fasync, | 647 | .fasync = lis3lv02d_misc_fasync, |
| 606 | }; | 648 | }; |
| 607 | 649 | ||
| 608 | static struct miscdevice lis3lv02d_misc_device = { | 650 | int lis3lv02d_joystick_enable(struct lis3lv02d *lis3) |
| 609 | .minor = MISC_DYNAMIC_MINOR, | ||
| 610 | .name = "freefall", | ||
| 611 | .fops = &lis3lv02d_misc_fops, | ||
| 612 | }; | ||
| 613 | |||
| 614 | int lis3lv02d_joystick_enable(void) | ||
| 615 | { | 651 | { |
| 616 | struct input_dev *input_dev; | 652 | struct input_dev *input_dev; |
| 617 | int err; | 653 | int err; |
| 618 | int max_val, fuzz, flat; | 654 | int max_val, fuzz, flat; |
| 619 | int btns[] = {BTN_X, BTN_Y, BTN_Z}; | 655 | int btns[] = {BTN_X, BTN_Y, BTN_Z}; |
| 620 | 656 | ||
| 621 | if (lis3_dev.idev) | 657 | if (lis3->idev) |
| 622 | return -EINVAL; | 658 | return -EINVAL; |
| 623 | 659 | ||
| 624 | lis3_dev.idev = input_allocate_polled_device(); | 660 | lis3->idev = input_allocate_polled_device(); |
| 625 | if (!lis3_dev.idev) | 661 | if (!lis3->idev) |
| 626 | return -ENOMEM; | 662 | return -ENOMEM; |
| 627 | 663 | ||
| 628 | lis3_dev.idev->poll = lis3lv02d_joystick_poll; | 664 | lis3->idev->poll = lis3lv02d_joystick_poll; |
| 629 | lis3_dev.idev->open = lis3lv02d_joystick_open; | 665 | lis3->idev->open = lis3lv02d_joystick_open; |
| 630 | lis3_dev.idev->close = lis3lv02d_joystick_close; | 666 | lis3->idev->close = lis3lv02d_joystick_close; |
| 631 | lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL; | 667 | lis3->idev->poll_interval = MDPS_POLL_INTERVAL; |
| 632 | lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN; | 668 | lis3->idev->poll_interval_min = MDPS_POLL_MIN; |
| 633 | lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX; | 669 | lis3->idev->poll_interval_max = MDPS_POLL_MAX; |
| 634 | input_dev = lis3_dev.idev->input; | 670 | lis3->idev->private = lis3; |
| 671 | input_dev = lis3->idev->input; | ||
| 635 | 672 | ||
| 636 | input_dev->name = "ST LIS3LV02DL Accelerometer"; | 673 | input_dev->name = "ST LIS3LV02DL Accelerometer"; |
| 637 | input_dev->phys = DRIVER_NAME "/input0"; | 674 | input_dev->phys = DRIVER_NAME "/input0"; |
| 638 | input_dev->id.bustype = BUS_HOST; | 675 | input_dev->id.bustype = BUS_HOST; |
| 639 | input_dev->id.vendor = 0; | 676 | input_dev->id.vendor = 0; |
| 640 | input_dev->dev.parent = &lis3_dev.pdev->dev; | 677 | input_dev->dev.parent = &lis3->pdev->dev; |
| 641 | 678 | ||
| 642 | set_bit(EV_ABS, input_dev->evbit); | 679 | set_bit(EV_ABS, input_dev->evbit); |
| 643 | max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY; | 680 | max_val = (lis3->mdps_max_val * lis3->scale) / LIS3_ACCURACY; |
| 644 | if (lis3_dev.whoami == WAI_12B) { | 681 | if (lis3->whoami == WAI_12B) { |
| 645 | fuzz = LIS3_DEFAULT_FUZZ_12B; | 682 | fuzz = LIS3_DEFAULT_FUZZ_12B; |
| 646 | flat = LIS3_DEFAULT_FLAT_12B; | 683 | flat = LIS3_DEFAULT_FLAT_12B; |
| 647 | } else { | 684 | } else { |
| 648 | fuzz = LIS3_DEFAULT_FUZZ_8B; | 685 | fuzz = LIS3_DEFAULT_FUZZ_8B; |
| 649 | flat = LIS3_DEFAULT_FLAT_8B; | 686 | flat = LIS3_DEFAULT_FLAT_8B; |
| 650 | } | 687 | } |
| 651 | fuzz = (fuzz * lis3_dev.scale) / LIS3_ACCURACY; | 688 | fuzz = (fuzz * lis3->scale) / LIS3_ACCURACY; |
| 652 | flat = (flat * lis3_dev.scale) / LIS3_ACCURACY; | 689 | flat = (flat * lis3->scale) / LIS3_ACCURACY; |
| 653 | 690 | ||
| 654 | input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat); | 691 | input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat); |
| 655 | input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat); | 692 | input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat); |
| 656 | input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat); | 693 | input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat); |
| 657 | 694 | ||
| 658 | lis3_dev.mapped_btns[0] = lis3lv02d_get_axis(abs(lis3_dev.ac.x), btns); | 695 | lis3->mapped_btns[0] = lis3lv02d_get_axis(abs(lis3->ac.x), btns); |
| 659 | lis3_dev.mapped_btns[1] = lis3lv02d_get_axis(abs(lis3_dev.ac.y), btns); | 696 | lis3->mapped_btns[1] = lis3lv02d_get_axis(abs(lis3->ac.y), btns); |
| 660 | lis3_dev.mapped_btns[2] = lis3lv02d_get_axis(abs(lis3_dev.ac.z), btns); | 697 | lis3->mapped_btns[2] = lis3lv02d_get_axis(abs(lis3->ac.z), btns); |
| 661 | 698 | ||
| 662 | err = input_register_polled_device(lis3_dev.idev); | 699 | err = input_register_polled_device(lis3->idev); |
| 663 | if (err) { | 700 | if (err) { |
| 664 | input_free_polled_device(lis3_dev.idev); | 701 | input_free_polled_device(lis3->idev); |
| 665 | lis3_dev.idev = NULL; | 702 | lis3->idev = NULL; |
| 666 | } | 703 | } |
| 667 | 704 | ||
| 668 | return err; | 705 | return err; |
| 669 | } | 706 | } |
| 670 | EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable); | 707 | EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable); |
| 671 | 708 | ||
| 672 | void lis3lv02d_joystick_disable(void) | 709 | void lis3lv02d_joystick_disable(struct lis3lv02d *lis3) |
| 673 | { | 710 | { |
| 674 | if (lis3_dev.irq) | 711 | if (lis3->irq) |
| 675 | free_irq(lis3_dev.irq, &lis3_dev); | 712 | free_irq(lis3->irq, lis3); |
| 676 | if (lis3_dev.pdata && lis3_dev.pdata->irq2) | 713 | if (lis3->pdata && lis3->pdata->irq2) |
| 677 | free_irq(lis3_dev.pdata->irq2, &lis3_dev); | 714 | free_irq(lis3->pdata->irq2, lis3); |
| 678 | 715 | ||
| 679 | if (!lis3_dev.idev) | 716 | if (!lis3->idev) |
| 680 | return; | 717 | return; |
| 681 | 718 | ||
| 682 | if (lis3_dev.irq) | 719 | if (lis3->irq) |
| 683 | misc_deregister(&lis3lv02d_misc_device); | 720 | misc_deregister(&lis3->miscdev); |
| 684 | input_unregister_polled_device(lis3_dev.idev); | 721 | input_unregister_polled_device(lis3->idev); |
| 685 | input_free_polled_device(lis3_dev.idev); | 722 | input_free_polled_device(lis3->idev); |
| 686 | lis3_dev.idev = NULL; | 723 | lis3->idev = NULL; |
| 687 | } | 724 | } |
| 688 | EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); | 725 | EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); |
| 689 | 726 | ||
| @@ -708,6 +745,7 @@ static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3) | |||
| 708 | static ssize_t lis3lv02d_selftest_show(struct device *dev, | 745 | static ssize_t lis3lv02d_selftest_show(struct device *dev, |
| 709 | struct device_attribute *attr, char *buf) | 746 | struct device_attribute *attr, char *buf) |
| 710 | { | 747 | { |
| 748 | struct lis3lv02d *lis3 = dev_get_drvdata(dev); | ||
| 711 | s16 values[3]; | 749 | s16 values[3]; |
| 712 | 750 | ||
| 713 | static const char ok[] = "OK"; | 751 | static const char ok[] = "OK"; |
| @@ -715,8 +753,8 @@ static ssize_t lis3lv02d_selftest_show(struct device *dev, | |||
| 715 | static const char irq[] = "FAIL_IRQ"; | 753 | static const char irq[] = "FAIL_IRQ"; |
| 716 | const char *res; | 754 | const char *res; |
| 717 | 755 | ||
| 718 | lis3lv02d_sysfs_poweron(&lis3_dev); | 756 | lis3lv02d_sysfs_poweron(lis3); |
| 719 | switch (lis3lv02d_selftest(&lis3_dev, values)) { | 757 | switch (lis3lv02d_selftest(lis3, values)) { |
| 720 | case SELFTEST_FAIL: | 758 | case SELFTEST_FAIL: |
| 721 | res = fail; | 759 | res = fail; |
| 722 | break; | 760 | break; |
| @@ -735,33 +773,37 @@ static ssize_t lis3lv02d_selftest_show(struct device *dev, | |||
| 735 | static ssize_t lis3lv02d_position_show(struct device *dev, | 773 | static ssize_t lis3lv02d_position_show(struct device *dev, |
| 736 | struct device_attribute *attr, char *buf) | 774 | struct device_attribute *attr, char *buf) |
| 737 | { | 775 | { |
| 776 | struct lis3lv02d *lis3 = dev_get_drvdata(dev); | ||
| 738 | int x, y, z; | 777 | int x, y, z; |
| 739 | 778 | ||
| 740 | lis3lv02d_sysfs_poweron(&lis3_dev); | 779 | lis3lv02d_sysfs_poweron(lis3); |
| 741 | mutex_lock(&lis3_dev.mutex); | 780 | mutex_lock(&lis3->mutex); |
| 742 | lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); | 781 | lis3lv02d_get_xyz(lis3, &x, &y, &z); |
| 743 | mutex_unlock(&lis3_dev.mutex); | 782 | mutex_unlock(&lis3->mutex); |
| 744 | return sprintf(buf, "(%d,%d,%d)\n", x, y, z); | 783 | return sprintf(buf, "(%d,%d,%d)\n", x, y, z); |
| 745 | } | 784 | } |
| 746 | 785 | ||
| 747 | static ssize_t lis3lv02d_rate_show(struct device *dev, | 786 | static ssize_t lis3lv02d_rate_show(struct device *dev, |
| 748 | struct device_attribute *attr, char *buf) | 787 | struct device_attribute *attr, char *buf) |
| 749 | { | 788 | { |
| 750 | lis3lv02d_sysfs_poweron(&lis3_dev); | 789 | struct lis3lv02d *lis3 = dev_get_drvdata(dev); |
| 751 | return sprintf(buf, "%d\n", lis3lv02d_get_odr()); | 790 | |
| 791 | lis3lv02d_sysfs_poweron(lis3); | ||
| 792 | return sprintf(buf, "%d\n", lis3lv02d_get_odr(lis3)); | ||
| 752 | } | 793 | } |
| 753 | 794 | ||
| 754 | static ssize_t lis3lv02d_rate_set(struct device *dev, | 795 | static ssize_t lis3lv02d_rate_set(struct device *dev, |
| 755 | struct device_attribute *attr, const char *buf, | 796 | struct device_attribute *attr, const char *buf, |
| 756 | size_t count) | 797 | size_t count) |
| 757 | { | 798 | { |
| 799 | struct lis3lv02d *lis3 = dev_get_drvdata(dev); | ||
| 758 | unsigned long rate; | 800 | unsigned long rate; |
| 759 | 801 | ||
| 760 | if (strict_strtoul(buf, 0, &rate)) | 802 | if (strict_strtoul(buf, 0, &rate)) |
| 761 | return -EINVAL; | 803 | return -EINVAL; |
| 762 | 804 | ||
| 763 | lis3lv02d_sysfs_poweron(&lis3_dev); | 805 | lis3lv02d_sysfs_poweron(lis3); |
| 764 | if (lis3lv02d_set_odr(rate)) | 806 | if (lis3lv02d_set_odr(lis3, rate)) |
| 765 | return -EINVAL; | 807 | return -EINVAL; |
| 766 | 808 | ||
| 767 | return count; | 809 | return count; |
| @@ -790,6 +832,7 @@ static int lis3lv02d_add_fs(struct lis3lv02d *lis3) | |||
| 790 | if (IS_ERR(lis3->pdev)) | 832 | if (IS_ERR(lis3->pdev)) |
| 791 | return PTR_ERR(lis3->pdev); | 833 | return PTR_ERR(lis3->pdev); |
| 792 | 834 | ||
| 835 | platform_set_drvdata(lis3->pdev, lis3); | ||
| 793 | return sysfs_create_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group); | 836 | return sysfs_create_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group); |
| 794 | } | 837 | } |
| 795 | 838 | ||
| @@ -803,7 +846,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3) | |||
| 803 | 846 | ||
| 804 | /* SYSFS may have left chip running. Turn off if necessary */ | 847 | /* SYSFS may have left chip running. Turn off if necessary */ |
| 805 | if (!pm_runtime_suspended(lis3->pm_dev)) | 848 | if (!pm_runtime_suspended(lis3->pm_dev)) |
| 806 | lis3lv02d_poweroff(&lis3_dev); | 849 | lis3lv02d_poweroff(lis3); |
| 807 | 850 | ||
| 808 | pm_runtime_disable(lis3->pm_dev); | 851 | pm_runtime_disable(lis3->pm_dev); |
| 809 | pm_runtime_set_suspended(lis3->pm_dev); | 852 | pm_runtime_set_suspended(lis3->pm_dev); |
| @@ -813,24 +856,24 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3) | |||
| 813 | } | 856 | } |
| 814 | EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); | 857 | EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); |
| 815 | 858 | ||
| 816 | static void lis3lv02d_8b_configure(struct lis3lv02d *dev, | 859 | static void lis3lv02d_8b_configure(struct lis3lv02d *lis3, |
| 817 | struct lis3lv02d_platform_data *p) | 860 | struct lis3lv02d_platform_data *p) |
| 818 | { | 861 | { |
| 819 | int err; | 862 | int err; |
| 820 | int ctrl2 = p->hipass_ctrl; | 863 | int ctrl2 = p->hipass_ctrl; |
| 821 | 864 | ||
| 822 | if (p->click_flags) { | 865 | if (p->click_flags) { |
| 823 | dev->write(dev, CLICK_CFG, p->click_flags); | 866 | lis3->write(lis3, CLICK_CFG, p->click_flags); |
| 824 | dev->write(dev, CLICK_TIMELIMIT, p->click_time_limit); | 867 | lis3->write(lis3, CLICK_TIMELIMIT, p->click_time_limit); |
| 825 | dev->write(dev, CLICK_LATENCY, p->click_latency); | 868 | lis3->write(lis3, CLICK_LATENCY, p->click_latency); |
| 826 | dev->write(dev, CLICK_WINDOW, p->click_window); | 869 | lis3->write(lis3, CLICK_WINDOW, p->click_window); |
| 827 | dev->write(dev, CLICK_THSZ, p->click_thresh_z & 0xf); | 870 | lis3->write(lis3, CLICK_THSZ, p->click_thresh_z & 0xf); |
| 828 | dev->write(dev, CLICK_THSY_X, | 871 | lis3->write(lis3, CLICK_THSY_X, |
| 829 | (p->click_thresh_x & 0xf) | | 872 | (p->click_thresh_x & 0xf) | |
| 830 | (p->click_thresh_y << 4)); | 873 | (p->click_thresh_y << 4)); |
| 831 | 874 | ||
| 832 | if (dev->idev) { | 875 | if (lis3->idev) { |
| 833 | struct input_dev *input_dev = lis3_dev.idev->input; | 876 | struct input_dev *input_dev = lis3->idev->input; |
| 834 | input_set_capability(input_dev, EV_KEY, BTN_X); | 877 | input_set_capability(input_dev, EV_KEY, BTN_X); |
| 835 | input_set_capability(input_dev, EV_KEY, BTN_Y); | 878 | input_set_capability(input_dev, EV_KEY, BTN_Y); |
| 836 | input_set_capability(input_dev, EV_KEY, BTN_Z); | 879 | input_set_capability(input_dev, EV_KEY, BTN_Z); |
| @@ -838,22 +881,22 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, | |||
| 838 | } | 881 | } |
| 839 | 882 | ||
| 840 | if (p->wakeup_flags) { | 883 | if (p->wakeup_flags) { |
| 841 | dev->write(dev, FF_WU_CFG_1, p->wakeup_flags); | 884 | lis3->write(lis3, FF_WU_CFG_1, p->wakeup_flags); |
| 842 | dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f); | 885 | lis3->write(lis3, FF_WU_THS_1, p->wakeup_thresh & 0x7f); |
| 843 | /* pdata value + 1 to keep this backward compatible*/ | 886 | /* pdata value + 1 to keep this backward compatible*/ |
| 844 | dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1); | 887 | lis3->write(lis3, FF_WU_DURATION_1, p->duration1 + 1); |
| 845 | ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/ | 888 | ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/ |
| 846 | } | 889 | } |
| 847 | 890 | ||
| 848 | if (p->wakeup_flags2) { | 891 | if (p->wakeup_flags2) { |
| 849 | dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2); | 892 | lis3->write(lis3, FF_WU_CFG_2, p->wakeup_flags2); |
| 850 | dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f); | 893 | lis3->write(lis3, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f); |
| 851 | /* pdata value + 1 to keep this backward compatible*/ | 894 | /* pdata value + 1 to keep this backward compatible*/ |
| 852 | dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1); | 895 | lis3->write(lis3, FF_WU_DURATION_2, p->duration2 + 1); |
| 853 | ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/ | 896 | ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/ |
| 854 | } | 897 | } |
| 855 | /* Configure hipass filters */ | 898 | /* Configure hipass filters */ |
| 856 | dev->write(dev, CTRL_REG2, ctrl2); | 899 | lis3->write(lis3, CTRL_REG2, ctrl2); |
| 857 | 900 | ||
| 858 | if (p->irq2) { | 901 | if (p->irq2) { |
| 859 | err = request_threaded_irq(p->irq2, | 902 | err = request_threaded_irq(p->irq2, |
| @@ -861,7 +904,7 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, | |||
| 861 | lis302dl_interrupt_thread2_8b, | 904 | lis302dl_interrupt_thread2_8b, |
| 862 | IRQF_TRIGGER_RISING | IRQF_ONESHOT | | 905 | IRQF_TRIGGER_RISING | IRQF_ONESHOT | |
| 863 | (p->irq_flags2 & IRQF_TRIGGER_MASK), | 906 | (p->irq_flags2 & IRQF_TRIGGER_MASK), |
| 864 | DRIVER_NAME, &lis3_dev); | 907 | DRIVER_NAME, lis3); |
| 865 | if (err < 0) | 908 | if (err < 0) |
| 866 | pr_err("No second IRQ. Limited functionality\n"); | 909 | pr_err("No second IRQ. Limited functionality\n"); |
| 867 | } | 910 | } |
| @@ -871,93 +914,97 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, | |||
| 871 | * Initialise the accelerometer and the various subsystems. | 914 | * Initialise the accelerometer and the various subsystems. |
| 872 | * Should be rather independent of the bus system. | 915 | * Should be rather independent of the bus system. |
| 873 | */ | 916 | */ |
| 874 | int lis3lv02d_init_device(struct lis3lv02d *dev) | 917 | int lis3lv02d_init_device(struct lis3lv02d *lis3) |
| 875 | { | 918 | { |
| 876 | int err; | 919 | int err; |
| 877 | irq_handler_t thread_fn; | 920 | irq_handler_t thread_fn; |
| 878 | int irq_flags = 0; | 921 | int irq_flags = 0; |
| 879 | 922 | ||
| 880 | dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I); | 923 | lis3->whoami = lis3lv02d_read_8(lis3, WHO_AM_I); |
| 881 | 924 | ||
| 882 | switch (dev->whoami) { | 925 | switch (lis3->whoami) { |
| 883 | case WAI_12B: | 926 | case WAI_12B: |
| 884 | pr_info("12 bits sensor found\n"); | 927 | pr_info("12 bits sensor found\n"); |
| 885 | dev->read_data = lis3lv02d_read_12; | 928 | lis3->read_data = lis3lv02d_read_12; |
| 886 | dev->mdps_max_val = 2048; | 929 | lis3->mdps_max_val = 2048; |
| 887 | dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B; | 930 | lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_12B; |
| 888 | dev->odrs = lis3_12_rates; | 931 | lis3->odrs = lis3_12_rates; |
| 889 | dev->odr_mask = CTRL1_DF0 | CTRL1_DF1; | 932 | lis3->odr_mask = CTRL1_DF0 | CTRL1_DF1; |
| 890 | dev->scale = LIS3_SENSITIVITY_12B; | 933 | lis3->scale = LIS3_SENSITIVITY_12B; |
| 891 | dev->regs = lis3_wai12_regs; | 934 | lis3->regs = lis3_wai12_regs; |
| 892 | dev->regs_size = ARRAY_SIZE(lis3_wai12_regs); | 935 | lis3->regs_size = ARRAY_SIZE(lis3_wai12_regs); |
| 893 | break; | 936 | break; |
| 894 | case WAI_8B: | 937 | case WAI_8B: |
| 895 | pr_info("8 bits sensor found\n"); | 938 | pr_info("8 bits sensor found\n"); |
| 896 | dev->read_data = lis3lv02d_read_8; | 939 | lis3->read_data = lis3lv02d_read_8; |
| 897 | dev->mdps_max_val = 128; | 940 | lis3->mdps_max_val = 128; |
| 898 | dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; | 941 | lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; |
| 899 | dev->odrs = lis3_8_rates; | 942 | lis3->odrs = lis3_8_rates; |
| 900 | dev->odr_mask = CTRL1_DR; | 943 | lis3->odr_mask = CTRL1_DR; |
| 901 | dev->scale = LIS3_SENSITIVITY_8B; | 944 | lis3->scale = LIS3_SENSITIVITY_8B; |
| 902 | dev->regs = lis3_wai8_regs; | 945 | lis3->regs = lis3_wai8_regs; |
| 903 | dev->regs_size = ARRAY_SIZE(lis3_wai8_regs); | 946 | lis3->regs_size = ARRAY_SIZE(lis3_wai8_regs); |
| 904 | break; | 947 | break; |
| 905 | case WAI_3DC: | 948 | case WAI_3DC: |
| 906 | pr_info("8 bits 3DC sensor found\n"); | 949 | pr_info("8 bits 3DC sensor found\n"); |
| 907 | dev->read_data = lis3lv02d_read_8; | 950 | lis3->read_data = lis3lv02d_read_8; |
| 908 | dev->mdps_max_val = 128; | 951 | lis3->mdps_max_val = 128; |
| 909 | dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; | 952 | lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; |
| 910 | dev->odrs = lis3_3dc_rates; | 953 | lis3->odrs = lis3_3dc_rates; |
| 911 | dev->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3; | 954 | lis3->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3; |
| 912 | dev->scale = LIS3_SENSITIVITY_8B; | 955 | lis3->scale = LIS3_SENSITIVITY_8B; |
| 913 | break; | 956 | break; |
| 914 | default: | 957 | default: |
| 915 | pr_err("unknown sensor type 0x%X\n", dev->whoami); | 958 | pr_err("unknown sensor type 0x%X\n", lis3->whoami); |
| 916 | return -EINVAL; | 959 | return -EINVAL; |
| 917 | } | 960 | } |
| 918 | 961 | ||
| 919 | dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs), | 962 | lis3->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs), |
| 920 | sizeof(lis3_wai12_regs)), GFP_KERNEL); | 963 | sizeof(lis3_wai12_regs)), GFP_KERNEL); |
| 921 | 964 | ||
| 922 | if (dev->reg_cache == NULL) { | 965 | if (lis3->reg_cache == NULL) { |
| 923 | printk(KERN_ERR DRIVER_NAME "out of memory\n"); | 966 | printk(KERN_ERR DRIVER_NAME "out of memory\n"); |
| 924 | return -ENOMEM; | 967 | return -ENOMEM; |
| 925 | } | 968 | } |
| 926 | 969 | ||
| 927 | mutex_init(&dev->mutex); | 970 | mutex_init(&lis3->mutex); |
| 928 | atomic_set(&dev->wake_thread, 0); | 971 | atomic_set(&lis3->wake_thread, 0); |
| 929 | 972 | ||
| 930 | lis3lv02d_add_fs(dev); | 973 | lis3lv02d_add_fs(lis3); |
| 931 | lis3lv02d_poweron(dev); | 974 | err = lis3lv02d_poweron(lis3); |
| 975 | if (err) { | ||
| 976 | lis3lv02d_remove_fs(lis3); | ||
| 977 | return err; | ||
| 978 | } | ||
| 932 | 979 | ||
| 933 | if (dev->pm_dev) { | 980 | if (lis3->pm_dev) { |
| 934 | pm_runtime_set_active(dev->pm_dev); | 981 | pm_runtime_set_active(lis3->pm_dev); |
| 935 | pm_runtime_enable(dev->pm_dev); | 982 | pm_runtime_enable(lis3->pm_dev); |
| 936 | } | 983 | } |
| 937 | 984 | ||
| 938 | if (lis3lv02d_joystick_enable()) | 985 | if (lis3lv02d_joystick_enable(lis3)) |
| 939 | pr_err("joystick initialization failed\n"); | 986 | pr_err("joystick initialization failed\n"); |
| 940 | 987 | ||
| 941 | /* passing in platform specific data is purely optional and only | 988 | /* passing in platform specific data is purely optional and only |
| 942 | * used by the SPI transport layer at the moment */ | 989 | * used by the SPI transport layer at the moment */ |
| 943 | if (dev->pdata) { | 990 | if (lis3->pdata) { |
| 944 | struct lis3lv02d_platform_data *p = dev->pdata; | 991 | struct lis3lv02d_platform_data *p = lis3->pdata; |
| 945 | 992 | ||
| 946 | if (dev->whoami == WAI_8B) | 993 | if (lis3->whoami == WAI_8B) |
| 947 | lis3lv02d_8b_configure(dev, p); | 994 | lis3lv02d_8b_configure(lis3, p); |
| 948 | 995 | ||
| 949 | irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK; | 996 | irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK; |
| 950 | 997 | ||
| 951 | dev->irq_cfg = p->irq_cfg; | 998 | lis3->irq_cfg = p->irq_cfg; |
| 952 | if (p->irq_cfg) | 999 | if (p->irq_cfg) |
| 953 | dev->write(dev, CTRL_REG3, p->irq_cfg); | 1000 | lis3->write(lis3, CTRL_REG3, p->irq_cfg); |
| 954 | 1001 | ||
| 955 | if (p->default_rate) | 1002 | if (p->default_rate) |
| 956 | lis3lv02d_set_odr(p->default_rate); | 1003 | lis3lv02d_set_odr(lis3, p->default_rate); |
| 957 | } | 1004 | } |
| 958 | 1005 | ||
| 959 | /* bail if we did not get an IRQ from the bus layer */ | 1006 | /* bail if we did not get an IRQ from the bus layer */ |
| 960 | if (!dev->irq) { | 1007 | if (!lis3->irq) { |
| 961 | pr_debug("No IRQ. Disabling /dev/freefall\n"); | 1008 | pr_debug("No IRQ. Disabling /dev/freefall\n"); |
| 962 | goto out; | 1009 | goto out; |
| 963 | } | 1010 | } |
| @@ -973,23 +1020,27 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) | |||
| 973 | * io-apic is not configurable (and generates a warning) but I keep it | 1020 | * io-apic is not configurable (and generates a warning) but I keep it |
| 974 | * in case of support for other hardware. | 1021 | * in case of support for other hardware. |
| 975 | */ | 1022 | */ |
| 976 | if (dev->pdata && dev->whoami == WAI_8B) | 1023 | if (lis3->pdata && lis3->whoami == WAI_8B) |
| 977 | thread_fn = lis302dl_interrupt_thread1_8b; | 1024 | thread_fn = lis302dl_interrupt_thread1_8b; |
| 978 | else | 1025 | else |
| 979 | thread_fn = NULL; | 1026 | thread_fn = NULL; |
| 980 | 1027 | ||
| 981 | err = request_threaded_irq(dev->irq, lis302dl_interrupt, | 1028 | err = request_threaded_irq(lis3->irq, lis302dl_interrupt, |
| 982 | thread_fn, | 1029 | thread_fn, |
| 983 | IRQF_TRIGGER_RISING | IRQF_ONESHOT | | 1030 | IRQF_TRIGGER_RISING | IRQF_ONESHOT | |
| 984 | irq_flags, | 1031 | irq_flags, |
| 985 | DRIVER_NAME, &lis3_dev); | 1032 | DRIVER_NAME, lis3); |
| 986 | 1033 | ||
| 987 | if (err < 0) { | 1034 | if (err < 0) { |
| 988 | pr_err("Cannot get IRQ\n"); | 1035 | pr_err("Cannot get IRQ\n"); |
| 989 | goto out; | 1036 | goto out; |
| 990 | } | 1037 | } |
| 991 | 1038 | ||
| 992 | if (misc_register(&lis3lv02d_misc_device)) | 1039 | lis3->miscdev.minor = MISC_DYNAMIC_MINOR; |
| 1040 | lis3->miscdev.name = "freefall"; | ||
| 1041 | lis3->miscdev.fops = &lis3lv02d_misc_fops; | ||
| 1042 | |||
| 1043 | if (misc_register(&lis3->miscdev)) | ||
| 993 | pr_err("misc_register failed\n"); | 1044 | pr_err("misc_register failed\n"); |
| 994 | out: | 1045 | out: |
| 995 | return 0; | 1046 | return 0; |
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h index a1939589eb2c..2b1482ad3f16 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.h +++ b/drivers/misc/lis3lv02d/lis3lv02d.h | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/input-polldev.h> | 22 | #include <linux/input-polldev.h> |
| 23 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
| 24 | #include <linux/miscdevice.h> | ||
| 24 | 25 | ||
| 25 | /* | 26 | /* |
| 26 | * This driver tries to support the "digital" accelerometer chips from | 27 | * This driver tries to support the "digital" accelerometer chips from |
| @@ -273,6 +274,8 @@ struct lis3lv02d { | |||
| 273 | struct fasync_struct *async_queue; /* queue for the misc device */ | 274 | struct fasync_struct *async_queue; /* queue for the misc device */ |
| 274 | wait_queue_head_t misc_wait; /* Wait queue for the misc device */ | 275 | wait_queue_head_t misc_wait; /* Wait queue for the misc device */ |
| 275 | unsigned long misc_opened; /* bit0: whether the device is open */ | 276 | unsigned long misc_opened; /* bit0: whether the device is open */ |
| 277 | struct miscdevice miscdev; | ||
| 278 | |||
| 276 | int data_ready_count[2]; | 279 | int data_ready_count[2]; |
| 277 | atomic_t wake_thread; | 280 | atomic_t wake_thread; |
| 278 | unsigned char irq_cfg; | 281 | unsigned char irq_cfg; |
| @@ -282,10 +285,10 @@ struct lis3lv02d { | |||
| 282 | }; | 285 | }; |
| 283 | 286 | ||
| 284 | int lis3lv02d_init_device(struct lis3lv02d *lis3); | 287 | int lis3lv02d_init_device(struct lis3lv02d *lis3); |
| 285 | int lis3lv02d_joystick_enable(void); | 288 | int lis3lv02d_joystick_enable(struct lis3lv02d *lis3); |
| 286 | void lis3lv02d_joystick_disable(void); | 289 | void lis3lv02d_joystick_disable(struct lis3lv02d *lis3); |
| 287 | void lis3lv02d_poweroff(struct lis3lv02d *lis3); | 290 | void lis3lv02d_poweroff(struct lis3lv02d *lis3); |
| 288 | void lis3lv02d_poweron(struct lis3lv02d *lis3); | 291 | int lis3lv02d_poweron(struct lis3lv02d *lis3); |
| 289 | int lis3lv02d_remove_fs(struct lis3lv02d *lis3); | 292 | int lis3lv02d_remove_fs(struct lis3lv02d *lis3); |
| 290 | 293 | ||
| 291 | extern struct lis3lv02d lis3_dev; | 294 | extern struct lis3lv02d lis3_dev; |
diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index b20dfb4522d2..c02fea029dcf 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) | |||
| 79 | u8 reg; | 79 | u8 reg; |
| 80 | int ret; | 80 | int ret; |
| 81 | 81 | ||
| 82 | if (lis3->reg_ctrl) | 82 | lis3_reg_ctrl(lis3, LIS3_REG_ON); |
| 83 | lis3_reg_ctrl(lis3, LIS3_REG_ON); | ||
| 84 | 83 | ||
| 85 | lis3->read(lis3, WHO_AM_I, ®); | 84 | lis3->read(lis3, WHO_AM_I, ®); |
| 86 | if (reg != lis3->whoami) | 85 | if (reg != lis3->whoami) |
| @@ -106,10 +105,6 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, | |||
| 106 | struct lis3lv02d_platform_data *pdata = client->dev.platform_data; | 105 | struct lis3lv02d_platform_data *pdata = client->dev.platform_data; |
| 107 | 106 | ||
| 108 | if (pdata) { | 107 | if (pdata) { |
| 109 | /* Regulator control is optional */ | ||
| 110 | if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL) | ||
| 111 | lis3_dev.reg_ctrl = lis3_reg_ctrl; | ||
| 112 | |||
| 113 | if ((pdata->driver_features & LIS3_USE_BLOCK_READ) && | 108 | if ((pdata->driver_features & LIS3_USE_BLOCK_READ) && |
| 114 | (i2c_check_functionality(client->adapter, | 109 | (i2c_check_functionality(client->adapter, |
| 115 | I2C_FUNC_SMBUS_I2C_BLOCK))) | 110 | I2C_FUNC_SMBUS_I2C_BLOCK))) |
| @@ -131,15 +126,13 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, | |||
| 131 | goto fail; | 126 | goto fail; |
| 132 | } | 127 | } |
| 133 | 128 | ||
| 134 | if (lis3_dev.reg_ctrl) { | 129 | lis3_dev.regulators[0].supply = reg_vdd; |
| 135 | lis3_dev.regulators[0].supply = reg_vdd; | 130 | lis3_dev.regulators[1].supply = reg_vdd_io; |
| 136 | lis3_dev.regulators[1].supply = reg_vdd_io; | 131 | ret = regulator_bulk_get(&client->dev, |
| 137 | ret = regulator_bulk_get(&client->dev, | 132 | ARRAY_SIZE(lis3_dev.regulators), |
| 138 | ARRAY_SIZE(lis3_dev.regulators), | 133 | lis3_dev.regulators); |
| 139 | lis3_dev.regulators); | 134 | if (ret < 0) |
| 140 | if (ret < 0) | 135 | goto fail; |
| 141 | goto fail; | ||
| 142 | } | ||
| 143 | 136 | ||
| 144 | lis3_dev.pdata = pdata; | 137 | lis3_dev.pdata = pdata; |
| 145 | lis3_dev.bus_priv = client; | 138 | lis3_dev.bus_priv = client; |
| @@ -153,16 +146,19 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, | |||
| 153 | i2c_set_clientdata(client, &lis3_dev); | 146 | i2c_set_clientdata(client, &lis3_dev); |
| 154 | 147 | ||
| 155 | /* Provide power over the init call */ | 148 | /* Provide power over the init call */ |
| 156 | if (lis3_dev.reg_ctrl) | 149 | lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON); |
| 157 | lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON); | ||
| 158 | 150 | ||
| 159 | ret = lis3lv02d_init_device(&lis3_dev); | 151 | ret = lis3lv02d_init_device(&lis3_dev); |
| 160 | 152 | ||
| 161 | if (lis3_dev.reg_ctrl) | 153 | lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF); |
| 162 | lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF); | ||
| 163 | 154 | ||
| 164 | if (ret == 0) | 155 | if (ret) |
| 165 | return 0; | 156 | goto fail2; |
| 157 | return 0; | ||
| 158 | |||
| 159 | fail2: | ||
| 160 | regulator_bulk_free(ARRAY_SIZE(lis3_dev.regulators), | ||
| 161 | lis3_dev.regulators); | ||
| 166 | fail: | 162 | fail: |
| 167 | if (pdata && pdata->release_resources) | 163 | if (pdata && pdata->release_resources) |
| 168 | pdata->release_resources(); | 164 | pdata->release_resources(); |
| @@ -177,12 +173,11 @@ static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client) | |||
| 177 | if (pdata && pdata->release_resources) | 173 | if (pdata && pdata->release_resources) |
| 178 | pdata->release_resources(); | 174 | pdata->release_resources(); |
| 179 | 175 | ||
| 180 | lis3lv02d_joystick_disable(); | 176 | lis3lv02d_joystick_disable(lis3); |
| 181 | lis3lv02d_remove_fs(&lis3_dev); | 177 | lis3lv02d_remove_fs(&lis3_dev); |
| 182 | 178 | ||
| 183 | if (lis3_dev.reg_ctrl) | 179 | regulator_bulk_free(ARRAY_SIZE(lis3->regulators), |
| 184 | regulator_bulk_free(ARRAY_SIZE(lis3->regulators), | 180 | lis3_dev.regulators); |
| 185 | lis3_dev.regulators); | ||
| 186 | return 0; | 181 | return 0; |
| 187 | } | 182 | } |
| 188 | 183 | ||
diff --git a/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c index c1f8a8fbf694..b2c1be12d16f 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) | |||
| 83 | static int __devexit lis302dl_spi_remove(struct spi_device *spi) | 83 | static int __devexit lis302dl_spi_remove(struct spi_device *spi) |
| 84 | { | 84 | { |
| 85 | struct lis3lv02d *lis3 = spi_get_drvdata(spi); | 85 | struct lis3lv02d *lis3 = spi_get_drvdata(spi); |
| 86 | lis3lv02d_joystick_disable(); | 86 | lis3lv02d_joystick_disable(lis3); |
| 87 | lis3lv02d_poweroff(lis3); | 87 | lis3lv02d_poweroff(lis3); |
| 88 | 88 | ||
| 89 | return lis3lv02d_remove_fs(&lis3_dev); | 89 | 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 fca66165110e..8fda331c65df 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; | |||
| 581 | * printk / logging functions | 581 | * printk / logging functions |
| 582 | */ | 582 | */ |
| 583 | 583 | ||
| 584 | __printf(3, 4) | ||
| 584 | int en_print(const char *level, const struct mlx4_en_priv *priv, | 585 | int en_print(const char *level, const struct mlx4_en_priv *priv, |
| 585 | const char *format, ...) __attribute__ ((format (printf, 3, 4))); | 586 | const char *format, ...); |
| 586 | 587 | ||
| 587 | #define en_dbg(mlevel, priv, format, arg...) \ | 588 | #define en_dbg(mlevel, priv, format, arg...) \ |
| 588 | do { \ | 589 | do { \ |
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 39322d4121b7..4045e5ab0555 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) | |||
| 517 | goto exit; | 517 | goto exit; |
| 518 | 518 | ||
| 519 | while (len--) { | 519 | while (len--) { |
| 520 | obuf = pack_hex_byte(obuf, *ibuf++); | 520 | obuf = hex_byte_pack(obuf, *ibuf++); |
| 521 | *obuf++ = '-'; | 521 | *obuf++ = '-'; |
| 522 | } | 522 | } |
| 523 | obuf--; | 523 | obuf--; |
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 908fdbc3e0ee..0f9ee46cfc97 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); | |||
| 173 | void ath_hw_cycle_counters_update(struct ath_common *common); | 173 | void ath_hw_cycle_counters_update(struct ath_common *common); |
| 174 | int32_t ath_hw_get_listen_time(struct ath_common *common); | 174 | int32_t ath_hw_get_listen_time(struct ath_common *common); |
| 175 | 175 | ||
| 176 | extern __attribute__((format (printf, 2, 3))) | 176 | extern __printf(2, 3) void ath_printk(const char *level, const char *fmt, ...); |
| 177 | void ath_printk(const char *level, const char *fmt, ...); | ||
| 178 | 177 | ||
| 179 | #define _ath_printk(level, common, fmt, ...) \ | 178 | #define _ath_printk(level, common, fmt, ...) \ |
| 180 | do { \ | 179 | do { \ |
| @@ -258,7 +257,7 @@ do { \ | |||
| 258 | 257 | ||
| 259 | #else | 258 | #else |
| 260 | 259 | ||
| 261 | static inline __attribute__((format (printf, 3, 4))) | 260 | static inline __attribute__ ((format (printf, 3, 4))) |
| 262 | void ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask, | 261 | void ath_dbg(struct ath_common *common, enum ATH_DEBUG dbg_mask, |
| 263 | const char *fmt, ...) | 262 | const char *fmt, ...) |
| 264 | { | 263 | { |
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index 7f37df3125fd..0a3f916a1ef3 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); | |||
| 141 | 141 | ||
| 142 | #include <linux/compiler.h> | 142 | #include <linux/compiler.h> |
| 143 | 143 | ||
| 144 | static inline void __attribute__ ((format (printf, 3, 4))) | 144 | static inline __printf(3, 4) void |
| 145 | ATH5K_DBG(struct ath5k_hw *ah, unsigned int m, const char *fmt, ...) {} | 145 | ATH5K_DBG(struct ath5k_hw *ah, unsigned int m, const char *fmt, ...) {} |
| 146 | 146 | ||
| 147 | static inline void __attribute__ ((format (printf, 3, 4))) | 147 | static inline __printf(3, 4) void |
| 148 | ATH5K_DBG_UNLIMIT(struct ath5k_hw *ah, unsigned int m, const char *fmt, ...) | 148 | ATH5K_DBG_UNLIMIT(struct ath5k_hw *ah, unsigned int m, const char *fmt, ...) |
| 149 | {} | 149 | {} |
| 150 | 150 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index 9288a3ce1e39..7b7675f70a10 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 { | |||
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | extern unsigned int debug_mask; | 46 | extern unsigned int debug_mask; |
| 47 | extern int ath6kl_printk(const char *level, const char *fmt, ...) | 47 | extern __printf(2, 3) |
| 48 | __attribute__ ((format (printf, 2, 3))); | 48 | int ath6kl_printk(const char *level, const char *fmt, ...); |
| 49 | 49 | ||
| 50 | #define ath6kl_info(fmt, ...) \ | 50 | #define ath6kl_info(fmt, ...) \ |
| 51 | ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__) | 51 | ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__) |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 447a2307c9d9..37110dfd2c96 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) | |||
| 1011 | } | 1011 | } |
| 1012 | 1012 | ||
| 1013 | /* Message printing */ | 1013 | /* Message printing */ |
| 1014 | void b43info(struct b43_wl *wl, const char *fmt, ...) | 1014 | __printf(2, 3) void b43info(struct b43_wl *wl, const char *fmt, ...); |
| 1015 | __attribute__ ((format(printf, 2, 3))); | 1015 | __printf(2, 3) void b43err(struct b43_wl *wl, const char *fmt, ...); |
| 1016 | void b43err(struct b43_wl *wl, const char *fmt, ...) | 1016 | __printf(2, 3) void b43warn(struct b43_wl *wl, const char *fmt, ...); |
| 1017 | __attribute__ ((format(printf, 2, 3))); | 1017 | __printf(2, 3) void b43dbg(struct b43_wl *wl, const char *fmt, ...); |
| 1018 | void b43warn(struct b43_wl *wl, const char *fmt, ...) | ||
| 1019 | __attribute__ ((format(printf, 2, 3))); | ||
| 1020 | void b43dbg(struct b43_wl *wl, const char *fmt, ...) | ||
| 1021 | __attribute__ ((format(printf, 2, 3))); | ||
| 1022 | 1018 | ||
| 1023 | 1019 | ||
| 1024 | /* A WARN_ON variant that vanishes when b43 debugging is disabled. | 1020 | /* 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 12b518251581..1d4fc9db7f5e 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, | |||
| 810 | 810 | ||
| 811 | 811 | ||
| 812 | /* Message printing */ | 812 | /* Message printing */ |
| 813 | void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...) | 813 | __printf(2, 3) |
| 814 | __attribute__((format(printf, 2, 3))); | 814 | void b43legacyinfo(struct b43legacy_wl *wl, const char *fmt, ...); |
| 815 | void b43legacyerr(struct b43legacy_wl *wl, const char *fmt, ...) | 815 | __printf(2, 3) |
| 816 | __attribute__((format(printf, 2, 3))); | 816 | void b43legacyerr(struct b43legacy_wl *wl, const char *fmt, ...); |
| 817 | void b43legacywarn(struct b43legacy_wl *wl, const char *fmt, ...) | 817 | __printf(2, 3) |
| 818 | __attribute__((format(printf, 2, 3))); | 818 | void b43legacywarn(struct b43legacy_wl *wl, const char *fmt, ...); |
| 819 | #if B43legacy_DEBUG | 819 | #if B43legacy_DEBUG |
| 820 | void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...) | 820 | __printf(2, 3) |
| 821 | __attribute__((format(printf, 2, 3))); | 821 | void b43legacydbg(struct b43legacy_wl *wl, const char *fmt, ...); |
| 822 | #else /* DEBUG */ | 822 | #else /* DEBUG */ |
| 823 | # define b43legacydbg(wl, fmt...) do { /* nothing */ } while (0) | 823 | # define b43legacydbg(wl, fmt...) do { /* nothing */ } while (0) |
| 824 | #endif /* DEBUG */ | 824 | #endif /* DEBUG */ |
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 64b454855f65..22b2dfa73148 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[] = { | |||
| 210 | AXIS_DMI_MATCH("NC6715x", "HP Compaq 6715", y_inverted), | 210 | AXIS_DMI_MATCH("NC6715x", "HP Compaq 6715", y_inverted), |
| 211 | AXIS_DMI_MATCH("NC693xx", "HP EliteBook 693", xy_rotated_right), | 211 | AXIS_DMI_MATCH("NC693xx", "HP EliteBook 693", xy_rotated_right), |
| 212 | AXIS_DMI_MATCH("NC693xx", "HP EliteBook 853", xy_swap), | 212 | AXIS_DMI_MATCH("NC693xx", "HP EliteBook 853", xy_swap), |
| 213 | AXIS_DMI_MATCH("NC854xx", "HP EliteBook 854", y_inverted), | ||
| 214 | AXIS_DMI_MATCH("NC273xx", "HP EliteBook 273", y_inverted), | ||
| 213 | /* Intel-based HP Pavilion dv5 */ | 215 | /* Intel-based HP Pavilion dv5 */ |
| 214 | AXIS_DMI_MATCH2("HPDV5_I", | 216 | AXIS_DMI_MATCH2("HPDV5_I", |
| 215 | PRODUCT_NAME, "HP Pavilion dv5", | 217 | PRODUCT_NAME, "HP Pavilion dv5", |
| @@ -228,6 +230,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { | |||
| 228 | AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted), | 230 | AXIS_DMI_MATCH("HPB452x", "HP ProBook 452", y_inverted), |
| 229 | AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap), | 231 | AXIS_DMI_MATCH("HPB522x", "HP ProBook 522", xy_swap), |
| 230 | AXIS_DMI_MATCH("HPB532x", "HP ProBook 532", y_inverted), | 232 | AXIS_DMI_MATCH("HPB532x", "HP ProBook 532", y_inverted), |
| 233 | AXIS_DMI_MATCH("HPB655x", "HP ProBook 655", xy_swap_inverted), | ||
| 231 | AXIS_DMI_MATCH("Mini510x", "HP Mini 510", xy_rotated_left_usd), | 234 | AXIS_DMI_MATCH("Mini510x", "HP Mini 510", xy_rotated_left_usd), |
| 232 | AXIS_DMI_MATCH("HPB63xx", "HP ProBook 63", xy_swap), | 235 | AXIS_DMI_MATCH("HPB63xx", "HP ProBook 63", xy_swap), |
| 233 | AXIS_DMI_MATCH("HPB64xx", "HP ProBook 64", xy_swap), | 236 | AXIS_DMI_MATCH("HPB64xx", "HP ProBook 64", xy_swap), |
| @@ -325,7 +328,7 @@ static int lis3lv02d_add(struct acpi_device *device) | |||
| 325 | INIT_WORK(&hpled_led.work, delayed_set_status_worker); | 328 | INIT_WORK(&hpled_led.work, delayed_set_status_worker); |
| 326 | ret = led_classdev_register(NULL, &hpled_led.led_classdev); | 329 | ret = led_classdev_register(NULL, &hpled_led.led_classdev); |
| 327 | if (ret) { | 330 | if (ret) { |
| 328 | lis3lv02d_joystick_disable(); | 331 | lis3lv02d_joystick_disable(&lis3_dev); |
| 329 | lis3lv02d_poweroff(&lis3_dev); | 332 | lis3lv02d_poweroff(&lis3_dev); |
| 330 | flush_work(&hpled_led.work); | 333 | flush_work(&hpled_led.work); |
| 331 | return ret; | 334 | return ret; |
| @@ -339,7 +342,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) | |||
| 339 | if (!device) | 342 | if (!device) |
| 340 | return -EINVAL; | 343 | return -EINVAL; |
| 341 | 344 | ||
| 342 | lis3lv02d_joystick_disable(); | 345 | lis3lv02d_joystick_disable(&lis3_dev); |
| 343 | lis3lv02d_poweroff(&lis3_dev); | 346 | lis3lv02d_poweroff(&lis3_dev); |
| 344 | 347 | ||
| 345 | led_classdev_unregister(&hpled_led.led_classdev); | 348 | led_classdev_unregister(&hpled_led.led_classdev); |
| @@ -359,8 +362,7 @@ static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) | |||
| 359 | 362 | ||
| 360 | static int lis3lv02d_resume(struct acpi_device *device) | 363 | static int lis3lv02d_resume(struct acpi_device *device) |
| 361 | { | 364 | { |
| 362 | lis3lv02d_poweron(&lis3_dev); | 365 | return lis3lv02d_poweron(&lis3_dev); |
| 363 | return 0; | ||
| 364 | } | 366 | } |
| 365 | #else | 367 | #else |
| 366 | #define lis3lv02d_suspend NULL | 368 | #define lis3lv02d_suspend NULL |
diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h index 598fcb3599f9..5cc42a655c88 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); | |||
| 115 | 115 | ||
| 116 | irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private); | 116 | irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private); |
| 117 | 117 | ||
| 118 | struct iio_trigger *iio_allocate_trigger(const char *fmt, ...) | 118 | __printf(1, 2) struct iio_trigger *iio_allocate_trigger(const char *fmt, ...); |
| 119 | __attribute__((format(printf, 1, 2))); | ||
| 120 | void iio_free_trigger(struct iio_trigger *trig); | 119 | void iio_free_trigger(struct iio_trigger *trig); |
| 121 | 120 | ||
| 122 | #endif /* _IIO_TRIGGER_H_ */ | 121 | #endif /* _IIO_TRIGGER_H_ */ |
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c index 98e0304deeaf..6c68a6899e87 100644 --- a/drivers/video/backlight/adp8870_bl.c +++ b/drivers/video/backlight/adp8870_bl.c | |||
| @@ -931,7 +931,6 @@ out: | |||
| 931 | out1: | 931 | out1: |
| 932 | backlight_device_unregister(bl); | 932 | backlight_device_unregister(bl); |
| 933 | out2: | 933 | out2: |
| 934 | i2c_set_clientdata(client, NULL); | ||
| 935 | kfree(data); | 934 | kfree(data); |
| 936 | 935 | ||
| 937 | return ret; | 936 | return ret; |
| @@ -951,7 +950,6 @@ static int __devexit adp8870_remove(struct i2c_client *client) | |||
| 951 | &adp8870_bl_attr_group); | 950 | &adp8870_bl_attr_group); |
| 952 | 951 | ||
| 953 | backlight_device_unregister(data->bl); | 952 | backlight_device_unregister(data->bl); |
| 954 | i2c_set_clientdata(client, NULL); | ||
| 955 | kfree(data); | 953 | kfree(data); |
| 956 | 954 | ||
| 957 | return 0; | 955 | return 0; |
diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c index 8c6befd65a33..adb191466d64 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) | |||
| 56 | * Called when the battery is low to limit the backlight intensity. | 56 | * Called when the battery is low to limit the backlight intensity. |
| 57 | * If limit==0 clear any limit, otherwise limit the intensity | 57 | * If limit==0 clear any limit, otherwise limit the intensity |
| 58 | */ | 58 | */ |
| 59 | void corgibl_limit_intensity(int limit) | 59 | void genericbl_limit_intensity(int limit) |
| 60 | { | 60 | { |
| 61 | struct backlight_device *bd = generic_backlight_device; | 61 | struct backlight_device *bd = generic_backlight_device; |
| 62 | 62 | ||
| @@ -68,7 +68,7 @@ void corgibl_limit_intensity(int limit) | |||
| 68 | backlight_update_status(generic_backlight_device); | 68 | backlight_update_status(generic_backlight_device); |
| 69 | mutex_unlock(&bd->ops_lock); | 69 | mutex_unlock(&bd->ops_lock); |
| 70 | } | 70 | } |
| 71 | EXPORT_SYMBOL(corgibl_limit_intensity); | 71 | EXPORT_SYMBOL(genericbl_limit_intensity); |
| 72 | 72 | ||
| 73 | static const struct backlight_ops genericbl_ops = { | 73 | static const struct backlight_ops genericbl_ops = { |
| 74 | .options = BL_CORE_SUSPENDRESUME, | 74 | .options = BL_CORE_SUSPENDRESUME, |
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index 98ad3e5f7c85..3543f1b7d5f1 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) | |||
| 52 | 52 | ||
| 53 | dev_dbg(&spi->dev, "initializing LCD\n"); | 53 | dev_dbg(&spi->dev, "initializing LCD\n"); |
| 54 | 54 | ||
| 55 | if (priv->io_reg) { | 55 | regulator_set_voltage(priv->io_reg, 1800000, 1800000); |
| 56 | regulator_set_voltage(priv->io_reg, 1800000, 1800000); | 56 | regulator_enable(priv->io_reg); |
| 57 | regulator_enable(priv->io_reg); | ||
| 58 | } | ||
| 59 | 57 | ||
| 60 | if (priv->core_reg) { | 58 | regulator_set_voltage(priv->core_reg, 2800000, 2800000); |
| 61 | regulator_set_voltage(priv->core_reg, 2800000, 2800000); | 59 | regulator_enable(priv->core_reg); |
| 62 | regulator_enable(priv->core_reg); | ||
| 63 | } | ||
| 64 | 60 | ||
| 65 | l4f00242t03_reset(pdata->reset_gpio); | 61 | l4f00242t03_reset(pdata->reset_gpio); |
| 66 | 62 | ||
| @@ -78,11 +74,8 @@ static void l4f00242t03_lcd_powerdown(struct spi_device *spi) | |||
| 78 | 74 | ||
| 79 | gpio_set_value(pdata->data_enable_gpio, 0); | 75 | gpio_set_value(pdata->data_enable_gpio, 0); |
| 80 | 76 | ||
| 81 | if (priv->io_reg) | 77 | regulator_disable(priv->io_reg); |
| 82 | regulator_disable(priv->io_reg); | 78 | regulator_disable(priv->core_reg); |
| 83 | |||
| 84 | if (priv->core_reg) | ||
| 85 | regulator_disable(priv->core_reg); | ||
| 86 | } | 79 | } |
| 87 | 80 | ||
| 88 | static int l4f00242t03_lcd_power_get(struct lcd_device *ld) | 81 | static int l4f00242t03_lcd_power_get(struct lcd_device *ld) |
| @@ -178,47 +171,34 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) | |||
| 178 | 171 | ||
| 179 | priv->spi = spi; | 172 | priv->spi = spi; |
| 180 | 173 | ||
| 181 | ret = gpio_request(pdata->reset_gpio, "lcd l4f00242t03 reset"); | 174 | ret = gpio_request_one(pdata->reset_gpio, GPIOF_OUT_INIT_HIGH, |
| 175 | "lcd l4f00242t03 reset"); | ||
| 182 | if (ret) { | 176 | if (ret) { |
| 183 | dev_err(&spi->dev, | 177 | dev_err(&spi->dev, |
| 184 | "Unable to get the lcd l4f00242t03 reset gpio.\n"); | 178 | "Unable to get the lcd l4f00242t03 reset gpio.\n"); |
| 185 | goto err; | 179 | goto err; |
| 186 | } | 180 | } |
| 187 | 181 | ||
| 188 | ret = gpio_direction_output(pdata->reset_gpio, 1); | 182 | ret = gpio_request_one(pdata->data_enable_gpio, GPIOF_OUT_INIT_LOW, |
| 189 | if (ret) | 183 | "lcd l4f00242t03 data enable"); |
| 190 | goto err2; | ||
| 191 | |||
| 192 | ret = gpio_request(pdata->data_enable_gpio, | ||
| 193 | "lcd l4f00242t03 data enable"); | ||
| 194 | if (ret) { | 184 | if (ret) { |
| 195 | dev_err(&spi->dev, | 185 | dev_err(&spi->dev, |
| 196 | "Unable to get the lcd l4f00242t03 data en gpio.\n"); | 186 | "Unable to get the lcd l4f00242t03 data en gpio.\n"); |
| 197 | goto err2; | 187 | goto err2; |
| 198 | } | 188 | } |
| 199 | 189 | ||
| 200 | ret = gpio_direction_output(pdata->data_enable_gpio, 0); | 190 | priv->io_reg = regulator_get(&spi->dev, "vdd"); |
| 201 | if (ret) | 191 | if (IS_ERR(priv->io_reg)) { |
| 192 | dev_err(&spi->dev, "%s: Unable to get the IO regulator\n", | ||
| 193 | __func__); | ||
| 202 | goto err3; | 194 | goto err3; |
| 203 | |||
| 204 | if (pdata->io_supply) { | ||
| 205 | priv->io_reg = regulator_get(NULL, pdata->io_supply); | ||
| 206 | |||
| 207 | if (IS_ERR(priv->io_reg)) { | ||
| 208 | pr_err("%s: Unable to get the IO regulator\n", | ||
| 209 | __func__); | ||
| 210 | goto err3; | ||
| 211 | } | ||
| 212 | } | 195 | } |
| 213 | 196 | ||
| 214 | if (pdata->core_supply) { | 197 | priv->core_reg = regulator_get(&spi->dev, "vcore"); |
| 215 | priv->core_reg = regulator_get(NULL, pdata->core_supply); | 198 | if (IS_ERR(priv->core_reg)) { |
| 216 | 199 | dev_err(&spi->dev, "%s: Unable to get the core regulator\n", | |
| 217 | if (IS_ERR(priv->core_reg)) { | 200 | __func__); |
| 218 | pr_err("%s: Unable to get the core regulator\n", | 201 | goto err4; |
| 219 | __func__); | ||
| 220 | goto err4; | ||
| 221 | } | ||
| 222 | } | 202 | } |
| 223 | 203 | ||
| 224 | priv->ld = lcd_device_register("l4f00242t03", | 204 | priv->ld = lcd_device_register("l4f00242t03", |
| @@ -238,11 +218,9 @@ static int __devinit l4f00242t03_probe(struct spi_device *spi) | |||
| 238 | return 0; | 218 | return 0; |
| 239 | 219 | ||
| 240 | err5: | 220 | err5: |
| 241 | if (priv->core_reg) | 221 | regulator_put(priv->core_reg); |
| 242 | regulator_put(priv->core_reg); | ||
| 243 | err4: | 222 | err4: |
| 244 | if (priv->io_reg) | 223 | regulator_put(priv->io_reg); |
| 245 | regulator_put(priv->io_reg); | ||
| 246 | err3: | 224 | err3: |
| 247 | gpio_free(pdata->data_enable_gpio); | 225 | gpio_free(pdata->data_enable_gpio); |
| 248 | err2: | 226 | err2: |
| @@ -266,10 +244,8 @@ static int __devexit l4f00242t03_remove(struct spi_device *spi) | |||
| 266 | gpio_free(pdata->data_enable_gpio); | 244 | gpio_free(pdata->data_enable_gpio); |
| 267 | gpio_free(pdata->reset_gpio); | 245 | gpio_free(pdata->reset_gpio); |
| 268 | 246 | ||
| 269 | if (priv->io_reg) | 247 | regulator_put(priv->io_reg); |
| 270 | regulator_put(priv->io_reg); | 248 | regulator_put(priv->core_reg); |
| 271 | if (priv->core_reg) | ||
| 272 | regulator_put(priv->core_reg); | ||
| 273 | 249 | ||
| 274 | kfree(priv); | 250 | kfree(priv); |
| 275 | 251 | ||
