diff options
Diffstat (limited to 'drivers/mfd/ab3100-core.c')
-rw-r--r-- | drivers/mfd/ab3100-core.c | 62 |
1 files changed, 35 insertions, 27 deletions
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index 13e7d7bfe85f..c533f86ff5ea 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/workqueue.h> | ||
18 | #include <linux/debugfs.h> | 17 | #include <linux/debugfs.h> |
19 | #include <linux/seq_file.h> | 18 | #include <linux/seq_file.h> |
20 | #include <linux/uaccess.h> | 19 | #include <linux/uaccess.h> |
@@ -77,7 +76,7 @@ u8 ab3100_get_chip_type(struct ab3100 *ab3100) | |||
77 | } | 76 | } |
78 | EXPORT_SYMBOL(ab3100_get_chip_type); | 77 | EXPORT_SYMBOL(ab3100_get_chip_type); |
79 | 78 | ||
80 | int ab3100_set_register(struct ab3100 *ab3100, u8 reg, u8 regval) | 79 | int ab3100_set_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 regval) |
81 | { | 80 | { |
82 | u8 regandval[2] = {reg, regval}; | 81 | u8 regandval[2] = {reg, regval}; |
83 | int err; | 82 | int err; |
@@ -107,9 +106,10 @@ int ab3100_set_register(struct ab3100 *ab3100, u8 reg, u8 regval) | |||
107 | err = 0; | 106 | err = 0; |
108 | } | 107 | } |
109 | mutex_unlock(&ab3100->access_mutex); | 108 | mutex_unlock(&ab3100->access_mutex); |
110 | return 0; | 109 | return err; |
111 | } | 110 | } |
112 | EXPORT_SYMBOL(ab3100_set_register); | 111 | EXPORT_SYMBOL(ab3100_set_register_interruptible); |
112 | |||
113 | 113 | ||
114 | /* | 114 | /* |
115 | * The test registers exist at an I2C bus address up one | 115 | * The test registers exist at an I2C bus address up one |
@@ -118,7 +118,7 @@ EXPORT_SYMBOL(ab3100_set_register); | |||
118 | * anyway. It's currently only used from this file so declare | 118 | * anyway. It's currently only used from this file so declare |
119 | * it static and do not export. | 119 | * it static and do not export. |
120 | */ | 120 | */ |
121 | static int ab3100_set_test_register(struct ab3100 *ab3100, | 121 | static int ab3100_set_test_register_interruptible(struct ab3100 *ab3100, |
122 | u8 reg, u8 regval) | 122 | u8 reg, u8 regval) |
123 | { | 123 | { |
124 | u8 regandval[2] = {reg, regval}; | 124 | u8 regandval[2] = {reg, regval}; |
@@ -148,7 +148,8 @@ static int ab3100_set_test_register(struct ab3100 *ab3100, | |||
148 | return err; | 148 | return err; |
149 | } | 149 | } |
150 | 150 | ||
151 | int ab3100_get_register(struct ab3100 *ab3100, u8 reg, u8 *regval) | 151 | |
152 | int ab3100_get_register_interruptible(struct ab3100 *ab3100, u8 reg, u8 *regval) | ||
152 | { | 153 | { |
153 | int err; | 154 | int err; |
154 | 155 | ||
@@ -202,9 +203,10 @@ int ab3100_get_register(struct ab3100 *ab3100, u8 reg, u8 *regval) | |||
202 | mutex_unlock(&ab3100->access_mutex); | 203 | mutex_unlock(&ab3100->access_mutex); |
203 | return err; | 204 | return err; |
204 | } | 205 | } |
205 | EXPORT_SYMBOL(ab3100_get_register); | 206 | EXPORT_SYMBOL(ab3100_get_register_interruptible); |
206 | 207 | ||
207 | int ab3100_get_register_page(struct ab3100 *ab3100, | 208 | |
209 | int ab3100_get_register_page_interruptible(struct ab3100 *ab3100, | ||
208 | u8 first_reg, u8 *regvals, u8 numregs) | 210 | u8 first_reg, u8 *regvals, u8 numregs) |
209 | { | 211 | { |
210 | int err; | 212 | int err; |
@@ -258,9 +260,10 @@ int ab3100_get_register_page(struct ab3100 *ab3100, | |||
258 | mutex_unlock(&ab3100->access_mutex); | 260 | mutex_unlock(&ab3100->access_mutex); |
259 | return err; | 261 | return err; |
260 | } | 262 | } |
261 | EXPORT_SYMBOL(ab3100_get_register_page); | 263 | EXPORT_SYMBOL(ab3100_get_register_page_interruptible); |
264 | |||
262 | 265 | ||
263 | int ab3100_mask_and_set_register(struct ab3100 *ab3100, | 266 | int ab3100_mask_and_set_register_interruptible(struct ab3100 *ab3100, |
264 | u8 reg, u8 andmask, u8 ormask) | 267 | u8 reg, u8 andmask, u8 ormask) |
265 | { | 268 | { |
266 | u8 regandval[2] = {reg, 0}; | 269 | u8 regandval[2] = {reg, 0}; |
@@ -328,7 +331,8 @@ int ab3100_mask_and_set_register(struct ab3100 *ab3100, | |||
328 | mutex_unlock(&ab3100->access_mutex); | 331 | mutex_unlock(&ab3100->access_mutex); |
329 | return err; | 332 | return err; |
330 | } | 333 | } |
331 | EXPORT_SYMBOL(ab3100_mask_and_set_register); | 334 | EXPORT_SYMBOL(ab3100_mask_and_set_register_interruptible); |
335 | |||
332 | 336 | ||
333 | /* | 337 | /* |
334 | * Register a simple callback for handling any AB3100 events. | 338 | * Register a simple callback for handling any AB3100 events. |
@@ -371,7 +375,7 @@ static void ab3100_work(struct work_struct *work) | |||
371 | u32 fatevent; | 375 | u32 fatevent; |
372 | int err; | 376 | int err; |
373 | 377 | ||
374 | err = ab3100_get_register_page(ab3100, AB3100_EVENTA1, | 378 | err = ab3100_get_register_page_interruptible(ab3100, AB3100_EVENTA1, |
375 | event_regs, 3); | 379 | event_regs, 3); |
376 | if (err) | 380 | if (err) |
377 | goto err_event_wq; | 381 | goto err_event_wq; |
@@ -417,7 +421,7 @@ static irqreturn_t ab3100_irq_handler(int irq, void *data) | |||
417 | * stuff and we will re-enable the interrupts once th | 421 | * stuff and we will re-enable the interrupts once th |
418 | * worker has finished. | 422 | * worker has finished. |
419 | */ | 423 | */ |
420 | disable_irq(ab3100->i2c_client->irq); | 424 | disable_irq_nosync(irq); |
421 | schedule_work(&ab3100->work); | 425 | schedule_work(&ab3100->work); |
422 | return IRQ_HANDLED; | 426 | return IRQ_HANDLED; |
423 | } | 427 | } |
@@ -435,7 +439,7 @@ static int ab3100_registers_print(struct seq_file *s, void *p) | |||
435 | seq_printf(s, "AB3100 registers:\n"); | 439 | seq_printf(s, "AB3100 registers:\n"); |
436 | 440 | ||
437 | for (reg = 0; reg < 0xff; reg++) { | 441 | for (reg = 0; reg < 0xff; reg++) { |
438 | ab3100_get_register(ab3100, reg, &value); | 442 | ab3100_get_register_interruptible(ab3100, reg, &value); |
439 | seq_printf(s, "[0x%x]: 0x%x\n", reg, value); | 443 | seq_printf(s, "[0x%x]: 0x%x\n", reg, value); |
440 | } | 444 | } |
441 | return 0; | 445 | return 0; |
@@ -465,14 +469,14 @@ static int ab3100_get_set_reg_open_file(struct inode *inode, struct file *file) | |||
465 | return 0; | 469 | return 0; |
466 | } | 470 | } |
467 | 471 | ||
468 | static int ab3100_get_set_reg(struct file *file, | 472 | static ssize_t ab3100_get_set_reg(struct file *file, |
469 | const char __user *user_buf, | 473 | const char __user *user_buf, |
470 | size_t count, loff_t *ppos) | 474 | size_t count, loff_t *ppos) |
471 | { | 475 | { |
472 | struct ab3100_get_set_reg_priv *priv = file->private_data; | 476 | struct ab3100_get_set_reg_priv *priv = file->private_data; |
473 | struct ab3100 *ab3100 = priv->ab3100; | 477 | struct ab3100 *ab3100 = priv->ab3100; |
474 | char buf[32]; | 478 | char buf[32]; |
475 | int buf_size; | 479 | ssize_t buf_size; |
476 | int regp; | 480 | int regp; |
477 | unsigned long user_reg; | 481 | unsigned long user_reg; |
478 | int err; | 482 | int err; |
@@ -515,7 +519,7 @@ static int ab3100_get_set_reg(struct file *file, | |||
515 | u8 reg = (u8) user_reg; | 519 | u8 reg = (u8) user_reg; |
516 | u8 regvalue; | 520 | u8 regvalue; |
517 | 521 | ||
518 | ab3100_get_register(ab3100, reg, ®value); | 522 | ab3100_get_register_interruptible(ab3100, reg, ®value); |
519 | 523 | ||
520 | dev_info(ab3100->dev, | 524 | dev_info(ab3100->dev, |
521 | "debug read AB3100 reg[0x%02x]: 0x%02x\n", | 525 | "debug read AB3100 reg[0x%02x]: 0x%02x\n", |
@@ -547,8 +551,8 @@ static int ab3100_get_set_reg(struct file *file, | |||
547 | return -EINVAL; | 551 | return -EINVAL; |
548 | 552 | ||
549 | value = (u8) user_value; | 553 | value = (u8) user_value; |
550 | ab3100_set_register(ab3100, reg, value); | 554 | ab3100_set_register_interruptible(ab3100, reg, value); |
551 | ab3100_get_register(ab3100, reg, ®value); | 555 | ab3100_get_register_interruptible(ab3100, reg, ®value); |
552 | 556 | ||
553 | dev_info(ab3100->dev, | 557 | dev_info(ab3100->dev, |
554 | "debug write reg[0x%02x] with 0x%02x, " | 558 | "debug write reg[0x%02x] with 0x%02x, " |
@@ -662,7 +666,7 @@ ab3100_init_settings[] = { | |||
662 | .setting = 0x01 | 666 | .setting = 0x01 |
663 | }, { | 667 | }, { |
664 | .abreg = AB3100_IMRB1, | 668 | .abreg = AB3100_IMRB1, |
665 | .setting = 0xFF | 669 | .setting = 0xBF |
666 | }, { | 670 | }, { |
667 | .abreg = AB3100_IMRB2, | 671 | .abreg = AB3100_IMRB2, |
668 | .setting = 0xFF | 672 | .setting = 0xFF |
@@ -696,7 +700,7 @@ static int __init ab3100_setup(struct ab3100 *ab3100) | |||
696 | int i; | 700 | int i; |
697 | 701 | ||
698 | for (i = 0; i < ARRAY_SIZE(ab3100_init_settings); i++) { | 702 | for (i = 0; i < ARRAY_SIZE(ab3100_init_settings); i++) { |
699 | err = ab3100_set_register(ab3100, | 703 | err = ab3100_set_register_interruptible(ab3100, |
700 | ab3100_init_settings[i].abreg, | 704 | ab3100_init_settings[i].abreg, |
701 | ab3100_init_settings[i].setting); | 705 | ab3100_init_settings[i].setting); |
702 | if (err) | 706 | if (err) |
@@ -705,14 +709,14 @@ static int __init ab3100_setup(struct ab3100 *ab3100) | |||
705 | 709 | ||
706 | /* | 710 | /* |
707 | * Special trick to make the AB3100 use the 32kHz clock (RTC) | 711 | * Special trick to make the AB3100 use the 32kHz clock (RTC) |
708 | * bit 3 in test registe 0x02 is a special, undocumented test | 712 | * bit 3 in test register 0x02 is a special, undocumented test |
709 | * register bit that only exist in AB3100 P1E | 713 | * register bit that only exist in AB3100 P1E |
710 | */ | 714 | */ |
711 | if (ab3100->chip_id == 0xc4) { | 715 | if (ab3100->chip_id == 0xc4) { |
712 | dev_warn(ab3100->dev, | 716 | dev_warn(ab3100->dev, |
713 | "AB3100 P1E variant detected, " | 717 | "AB3100 P1E variant detected, " |
714 | "forcing chip to 32KHz\n"); | 718 | "forcing chip to 32KHz\n"); |
715 | err = ab3100_set_test_register(ab3100, 0x02, 0x08); | 719 | err = ab3100_set_test_register_interruptible(ab3100, 0x02, 0x08); |
716 | } | 720 | } |
717 | 721 | ||
718 | exit_no_setup: | 722 | exit_no_setup: |
@@ -833,6 +837,8 @@ static int __init ab3100_probe(struct i2c_client *client, | |||
833 | const struct i2c_device_id *id) | 837 | const struct i2c_device_id *id) |
834 | { | 838 | { |
835 | struct ab3100 *ab3100; | 839 | struct ab3100 *ab3100; |
840 | struct ab3100_platform_data *ab3100_plf_data = | ||
841 | client->dev.platform_data; | ||
836 | int err; | 842 | int err; |
837 | int i; | 843 | int i; |
838 | 844 | ||
@@ -852,8 +858,8 @@ static int __init ab3100_probe(struct i2c_client *client, | |||
852 | i2c_set_clientdata(client, ab3100); | 858 | i2c_set_clientdata(client, ab3100); |
853 | 859 | ||
854 | /* Read chip ID register */ | 860 | /* Read chip ID register */ |
855 | err = ab3100_get_register(ab3100, AB3100_CID, | 861 | err = ab3100_get_register_interruptible(ab3100, AB3100_CID, |
856 | &ab3100->chip_id); | 862 | &ab3100->chip_id); |
857 | if (err) { | 863 | if (err) { |
858 | dev_err(&client->dev, | 864 | dev_err(&client->dev, |
859 | "could not communicate with the AB3100 analog " | 865 | "could not communicate with the AB3100 analog " |
@@ -916,6 +922,8 @@ static int __init ab3100_probe(struct i2c_client *client, | |||
916 | for (i = 0; i < ARRAY_SIZE(ab3100_platform_devs); i++) { | 922 | for (i = 0; i < ARRAY_SIZE(ab3100_platform_devs); i++) { |
917 | ab3100_platform_devs[i]->dev.parent = | 923 | ab3100_platform_devs[i]->dev.parent = |
918 | &client->dev; | 924 | &client->dev; |
925 | ab3100_platform_devs[i]->dev.platform_data = | ||
926 | ab3100_plf_data; | ||
919 | platform_set_drvdata(ab3100_platform_devs[i], ab3100); | 927 | platform_set_drvdata(ab3100_platform_devs[i], ab3100); |
920 | } | 928 | } |
921 | 929 | ||