diff options
author | Marc Reilly <marc@cpdesign.com.au> | 2012-05-01 06:26:46 -0400 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-05-01 06:35:40 -0400 |
commit | 5006fe546a4eb0393782b818d4e0e2a6b4fa3803 (patch) | |
tree | 3565d39367e75cb7581fb196748e00d95b53c5b5 | |
parent | 4c394bb1683dbd110314ab37da7bfa6c9a77073d (diff) |
mfd: Prepare for separating spi and i2c mc13xxx-core backends
This patch abstracts the bus specific operations from the driver core.
Generic init and cleanup is consolidated into mc13xxx_common_*.
spi specific functions are renamed to reflect such.
(The irq member of the mc13xxx struct is no longer redundant, it's used
to store the irq for cleanup time).
Signed-off-by: Marc Reilly <marc@cpdesign.com.au>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/mfd/mc13xxx-core.c | 188 |
1 files changed, 113 insertions, 75 deletions
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index 9fd4f63c45cc..c8b7a28b2669 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
@@ -22,8 +22,18 @@ | |||
22 | #include <linux/of_device.h> | 22 | #include <linux/of_device.h> |
23 | #include <linux/of_gpio.h> | 23 | #include <linux/of_gpio.h> |
24 | 24 | ||
25 | enum mc13xxx_id { | ||
26 | MC13XXX_ID_MC13783, | ||
27 | MC13XXX_ID_MC13892, | ||
28 | MC13XXX_ID_INVALID, | ||
29 | }; | ||
30 | |||
25 | struct mc13xxx { | 31 | struct mc13xxx { |
26 | struct spi_device *spidev; | 32 | struct spi_device *spidev; |
33 | |||
34 | struct device *dev; | ||
35 | enum mc13xxx_id ictype; | ||
36 | |||
27 | struct mutex lock; | 37 | struct mutex lock; |
28 | int irq; | 38 | int irq; |
29 | int flags; | 39 | int flags; |
@@ -144,36 +154,32 @@ struct mc13xxx { | |||
144 | void mc13xxx_lock(struct mc13xxx *mc13xxx) | 154 | void mc13xxx_lock(struct mc13xxx *mc13xxx) |
145 | { | 155 | { |
146 | if (!mutex_trylock(&mc13xxx->lock)) { | 156 | if (!mutex_trylock(&mc13xxx->lock)) { |
147 | dev_dbg(&mc13xxx->spidev->dev, "wait for %s from %pf\n", | 157 | dev_dbg(mc13xxx->dev, "wait for %s from %pf\n", |
148 | __func__, __builtin_return_address(0)); | 158 | __func__, __builtin_return_address(0)); |
149 | 159 | ||
150 | mutex_lock(&mc13xxx->lock); | 160 | mutex_lock(&mc13xxx->lock); |
151 | } | 161 | } |
152 | dev_dbg(&mc13xxx->spidev->dev, "%s from %pf\n", | 162 | dev_dbg(mc13xxx->dev, "%s from %pf\n", |
153 | __func__, __builtin_return_address(0)); | 163 | __func__, __builtin_return_address(0)); |
154 | } | 164 | } |
155 | EXPORT_SYMBOL(mc13xxx_lock); | 165 | EXPORT_SYMBOL(mc13xxx_lock); |
156 | 166 | ||
157 | void mc13xxx_unlock(struct mc13xxx *mc13xxx) | 167 | void mc13xxx_unlock(struct mc13xxx *mc13xxx) |
158 | { | 168 | { |
159 | dev_dbg(&mc13xxx->spidev->dev, "%s from %pf\n", | 169 | dev_dbg(mc13xxx->dev, "%s from %pf\n", |
160 | __func__, __builtin_return_address(0)); | 170 | __func__, __builtin_return_address(0)); |
161 | mutex_unlock(&mc13xxx->lock); | 171 | mutex_unlock(&mc13xxx->lock); |
162 | } | 172 | } |
163 | EXPORT_SYMBOL(mc13xxx_unlock); | 173 | EXPORT_SYMBOL(mc13xxx_unlock); |
164 | 174 | ||
165 | #define MC13XXX_REGOFFSET_SHIFT 25 | 175 | #define MC13XXX_REGOFFSET_SHIFT 25 |
166 | int mc13xxx_reg_read(struct mc13xxx *mc13xxx, unsigned int offset, u32 *val) | 176 | static int mc13xxx_spi_reg_read(struct mc13xxx *mc13xxx, |
177 | unsigned int offset, u32 *val) | ||
167 | { | 178 | { |
168 | struct spi_transfer t; | 179 | struct spi_transfer t; |
169 | struct spi_message m; | 180 | struct spi_message m; |
170 | int ret; | 181 | int ret; |
171 | 182 | ||
172 | BUG_ON(!mutex_is_locked(&mc13xxx->lock)); | ||
173 | |||
174 | if (offset > MC13XXX_NUMREGS) | ||
175 | return -EINVAL; | ||
176 | |||
177 | *val = offset << MC13XXX_REGOFFSET_SHIFT; | 183 | *val = offset << MC13XXX_REGOFFSET_SHIFT; |
178 | 184 | ||
179 | memset(&t, 0, sizeof(t)); | 185 | memset(&t, 0, sizeof(t)); |
@@ -195,26 +201,17 @@ int mc13xxx_reg_read(struct mc13xxx *mc13xxx, unsigned int offset, u32 *val) | |||
195 | 201 | ||
196 | *val &= 0xffffff; | 202 | *val &= 0xffffff; |
197 | 203 | ||
198 | dev_vdbg(&mc13xxx->spidev->dev, "[0x%02x] -> 0x%06x\n", offset, *val); | ||
199 | |||
200 | return 0; | 204 | return 0; |
201 | } | 205 | } |
202 | EXPORT_SYMBOL(mc13xxx_reg_read); | ||
203 | 206 | ||
204 | int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val) | 207 | static int mc13xxx_spi_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, |
208 | u32 val) | ||
205 | { | 209 | { |
206 | u32 buf; | 210 | u32 buf; |
207 | struct spi_transfer t; | 211 | struct spi_transfer t; |
208 | struct spi_message m; | 212 | struct spi_message m; |
209 | int ret; | 213 | int ret; |
210 | 214 | ||
211 | BUG_ON(!mutex_is_locked(&mc13xxx->lock)); | ||
212 | |||
213 | dev_vdbg(&mc13xxx->spidev->dev, "[0x%02x] <- 0x%06x\n", offset, val); | ||
214 | |||
215 | if (offset > MC13XXX_NUMREGS || val > 0xffffff) | ||
216 | return -EINVAL; | ||
217 | |||
218 | buf = 1 << 31 | offset << MC13XXX_REGOFFSET_SHIFT | val; | 215 | buf = 1 << 31 | offset << MC13XXX_REGOFFSET_SHIFT | val; |
219 | 216 | ||
220 | memset(&t, 0, sizeof(t)); | 217 | memset(&t, 0, sizeof(t)); |
@@ -235,6 +232,34 @@ int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val) | |||
235 | 232 | ||
236 | return 0; | 233 | return 0; |
237 | } | 234 | } |
235 | |||
236 | int mc13xxx_reg_read(struct mc13xxx *mc13xxx, unsigned int offset, u32 *val) | ||
237 | { | ||
238 | int ret; | ||
239 | |||
240 | BUG_ON(!mutex_is_locked(&mc13xxx->lock)); | ||
241 | |||
242 | if (offset > MC13XXX_NUMREGS) | ||
243 | return -EINVAL; | ||
244 | |||
245 | ret = mc13xxx_spi_reg_read(mc13xxx, offset, val); | ||
246 | dev_vdbg(mc13xxx->dev, "[0x%02x] -> 0x%06x\n", offset, *val); | ||
247 | |||
248 | return ret; | ||
249 | } | ||
250 | EXPORT_SYMBOL(mc13xxx_reg_read); | ||
251 | |||
252 | int mc13xxx_reg_write(struct mc13xxx *mc13xxx, unsigned int offset, u32 val) | ||
253 | { | ||
254 | BUG_ON(!mutex_is_locked(&mc13xxx->lock)); | ||
255 | |||
256 | dev_vdbg(mc13xxx->dev, "[0x%02x] <- 0x%06x\n", offset, val); | ||
257 | |||
258 | if (offset > MC13XXX_NUMREGS || val > 0xffffff) | ||
259 | return -EINVAL; | ||
260 | |||
261 | return mc13xxx_spi_reg_write(mc13xxx, offset, val); | ||
262 | } | ||
238 | EXPORT_SYMBOL(mc13xxx_reg_write); | 263 | EXPORT_SYMBOL(mc13xxx_reg_write); |
239 | 264 | ||
240 | int mc13xxx_reg_rmw(struct mc13xxx *mc13xxx, unsigned int offset, | 265 | int mc13xxx_reg_rmw(struct mc13xxx *mc13xxx, unsigned int offset, |
@@ -439,7 +464,7 @@ static int mc13xxx_irq_handle(struct mc13xxx *mc13xxx, | |||
439 | if (handled == IRQ_HANDLED) | 464 | if (handled == IRQ_HANDLED) |
440 | num_handled++; | 465 | num_handled++; |
441 | } else { | 466 | } else { |
442 | dev_err(&mc13xxx->spidev->dev, | 467 | dev_err(mc13xxx->dev, |
443 | "BUG: irq %u but no handler\n", | 468 | "BUG: irq %u but no handler\n", |
444 | baseirq + irq); | 469 | baseirq + irq); |
445 | 470 | ||
@@ -475,25 +500,23 @@ static irqreturn_t mc13xxx_irq_thread(int irq, void *data) | |||
475 | return IRQ_RETVAL(handled); | 500 | return IRQ_RETVAL(handled); |
476 | } | 501 | } |
477 | 502 | ||
478 | enum mc13xxx_id { | ||
479 | MC13XXX_ID_MC13783, | ||
480 | MC13XXX_ID_MC13892, | ||
481 | MC13XXX_ID_INVALID, | ||
482 | }; | ||
483 | |||
484 | static const char *mc13xxx_chipname[] = { | 503 | static const char *mc13xxx_chipname[] = { |
485 | [MC13XXX_ID_MC13783] = "mc13783", | 504 | [MC13XXX_ID_MC13783] = "mc13783", |
486 | [MC13XXX_ID_MC13892] = "mc13892", | 505 | [MC13XXX_ID_MC13892] = "mc13892", |
487 | }; | 506 | }; |
488 | 507 | ||
489 | #define maskval(reg, mask) (((reg) & (mask)) >> __ffs(mask)) | 508 | #define maskval(reg, mask) (((reg) & (mask)) >> __ffs(mask)) |
490 | static int mc13xxx_identify(struct mc13xxx *mc13xxx, enum mc13xxx_id *id) | 509 | static int mc13xxx_identify(struct mc13xxx *mc13xxx) |
491 | { | 510 | { |
492 | u32 icid; | 511 | u32 icid; |
493 | u32 revision; | 512 | u32 revision; |
494 | const char *name; | ||
495 | int ret; | 513 | int ret; |
496 | 514 | ||
515 | /* | ||
516 | * Get the generation ID from register 46, as apparently some older | ||
517 | * IC revisions only have this info at this location. Newer ICs seem to | ||
518 | * have both. | ||
519 | */ | ||
497 | ret = mc13xxx_reg_read(mc13xxx, 46, &icid); | 520 | ret = mc13xxx_reg_read(mc13xxx, 46, &icid); |
498 | if (ret) | 521 | if (ret) |
499 | return ret; | 522 | return ret; |
@@ -502,26 +525,23 @@ static int mc13xxx_identify(struct mc13xxx *mc13xxx, enum mc13xxx_id *id) | |||
502 | 525 | ||
503 | switch (icid) { | 526 | switch (icid) { |
504 | case 2: | 527 | case 2: |
505 | *id = MC13XXX_ID_MC13783; | 528 | mc13xxx->ictype = MC13XXX_ID_MC13783; |
506 | name = "mc13783"; | ||
507 | break; | 529 | break; |
508 | case 7: | 530 | case 7: |
509 | *id = MC13XXX_ID_MC13892; | 531 | mc13xxx->ictype = MC13XXX_ID_MC13892; |
510 | name = "mc13892"; | ||
511 | break; | 532 | break; |
512 | default: | 533 | default: |
513 | *id = MC13XXX_ID_INVALID; | 534 | mc13xxx->ictype = MC13XXX_ID_INVALID; |
514 | break; | 535 | break; |
515 | } | 536 | } |
516 | 537 | ||
517 | if (*id == MC13XXX_ID_MC13783 || *id == MC13XXX_ID_MC13892) { | 538 | if (mc13xxx->ictype == MC13XXX_ID_MC13783 || |
539 | mc13xxx->ictype == MC13XXX_ID_MC13892) { | ||
518 | ret = mc13xxx_reg_read(mc13xxx, MC13XXX_REVISION, &revision); | 540 | ret = mc13xxx_reg_read(mc13xxx, MC13XXX_REVISION, &revision); |
519 | if (ret) | ||
520 | return ret; | ||
521 | 541 | ||
522 | dev_info(&mc13xxx->spidev->dev, "%s: rev: %d.%d, " | 542 | dev_info(mc13xxx->dev, "%s: rev: %d.%d, " |
523 | "fin: %d, fab: %d, icid: %d/%d\n", | 543 | "fin: %d, fab: %d, icid: %d/%d\n", |
524 | mc13xxx_chipname[*id], | 544 | mc13xxx_chipname[mc13xxx->ictype], |
525 | maskval(revision, MC13XXX_REVISION_REVFULL), | 545 | maskval(revision, MC13XXX_REVISION_REVFULL), |
526 | maskval(revision, MC13XXX_REVISION_REVMETAL), | 546 | maskval(revision, MC13XXX_REVISION_REVMETAL), |
527 | maskval(revision, MC13XXX_REVISION_FIN), | 547 | maskval(revision, MC13XXX_REVISION_FIN), |
@@ -530,26 +550,12 @@ static int mc13xxx_identify(struct mc13xxx *mc13xxx, enum mc13xxx_id *id) | |||
530 | maskval(revision, MC13XXX_REVISION_ICIDCODE)); | 550 | maskval(revision, MC13XXX_REVISION_ICIDCODE)); |
531 | } | 551 | } |
532 | 552 | ||
533 | if (*id != MC13XXX_ID_INVALID) { | 553 | return (mc13xxx->ictype == MC13XXX_ID_INVALID) ? -ENODEV : 0; |
534 | const struct spi_device_id *devid = | ||
535 | spi_get_device_id(mc13xxx->spidev); | ||
536 | if (!devid || devid->driver_data != *id) | ||
537 | dev_warn(&mc13xxx->spidev->dev, "device id doesn't " | ||
538 | "match auto detection!\n"); | ||
539 | } | ||
540 | |||
541 | return 0; | ||
542 | } | 554 | } |
543 | 555 | ||
544 | static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx) | 556 | static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx) |
545 | { | 557 | { |
546 | const struct spi_device_id *devid = | 558 | return mc13xxx_chipname[mc13xxx->ictype]; |
547 | spi_get_device_id(mc13xxx->spidev); | ||
548 | |||
549 | if (!devid) | ||
550 | return NULL; | ||
551 | |||
552 | return mc13xxx_chipname[devid->driver_data]; | ||
553 | } | 559 | } |
554 | 560 | ||
555 | int mc13xxx_get_flags(struct mc13xxx *mc13xxx) | 561 | int mc13xxx_get_flags(struct mc13xxx *mc13xxx) |
@@ -592,7 +598,7 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, | |||
592 | }; | 598 | }; |
593 | init_completion(&adcdone_data.done); | 599 | init_completion(&adcdone_data.done); |
594 | 600 | ||
595 | dev_dbg(&mc13xxx->spidev->dev, "%s\n", __func__); | 601 | dev_dbg(mc13xxx->dev, "%s\n", __func__); |
596 | 602 | ||
597 | mc13xxx_lock(mc13xxx); | 603 | mc13xxx_lock(mc13xxx); |
598 | 604 | ||
@@ -637,7 +643,8 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, | |||
637 | adc1 |= ato << MC13783_ADC1_ATO_SHIFT; | 643 | adc1 |= ato << MC13783_ADC1_ATO_SHIFT; |
638 | if (atox) | 644 | if (atox) |
639 | adc1 |= MC13783_ADC1_ATOX; | 645 | adc1 |= MC13783_ADC1_ATOX; |
640 | dev_dbg(&mc13xxx->spidev->dev, "%s: request irq\n", __func__); | 646 | |
647 | dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__); | ||
641 | mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, | 648 | mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, |
642 | mc13xxx_handler_adcdone, __func__, &adcdone_data); | 649 | mc13xxx_handler_adcdone, __func__, &adcdone_data); |
643 | mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_ADCDONE); | 650 | mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_ADCDONE); |
@@ -695,7 +702,7 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx, | |||
695 | if (!cell.name) | 702 | if (!cell.name) |
696 | return -ENOMEM; | 703 | return -ENOMEM; |
697 | 704 | ||
698 | return mfd_add_devices(&mc13xxx->spidev->dev, -1, &cell, 1, NULL, 0); | 705 | return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0); |
699 | } | 706 | } |
700 | 707 | ||
701 | static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) | 708 | static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) |
@@ -706,7 +713,7 @@ static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) | |||
706 | #ifdef CONFIG_OF | 713 | #ifdef CONFIG_OF |
707 | static int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx) | 714 | static int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx) |
708 | { | 715 | { |
709 | struct device_node *np = mc13xxx->spidev->dev.of_node; | 716 | struct device_node *np = mc13xxx->dev.of_node; |
710 | 717 | ||
711 | if (!np) | 718 | if (!np) |
712 | return -ENODEV; | 719 | return -ENODEV; |
@@ -752,13 +759,17 @@ static const struct of_device_id mc13xxx_dt_ids[] = { | |||
752 | }; | 759 | }; |
753 | MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids); | 760 | MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids); |
754 | 761 | ||
755 | static int mc13xxx_probe(struct spi_device *spi) | 762 | static int mc13xxx_common_init(struct mc13xxx *mc13xxx, |
763 | struct mc13xxx_platform_data *pdata, int irq); | ||
764 | |||
765 | static void mc13xxx_common_cleanup(struct mc13xxx *mc13xxx); | ||
766 | |||
767 | static int mc13xxx_spi_probe(struct spi_device *spi) | ||
756 | { | 768 | { |
757 | const struct of_device_id *of_id; | 769 | const struct of_device_id *of_id; |
758 | struct spi_driver *sdrv = to_spi_driver(spi->dev.driver); | 770 | struct spi_driver *sdrv = to_spi_driver(spi->dev.driver); |
759 | struct mc13xxx *mc13xxx; | 771 | struct mc13xxx *mc13xxx; |
760 | struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev); | 772 | struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev); |
761 | enum mc13xxx_id id; | ||
762 | int ret; | 773 | int ret; |
763 | 774 | ||
764 | of_id = of_match_device(mc13xxx_dt_ids, &spi->dev); | 775 | of_id = of_match_device(mc13xxx_dt_ids, &spi->dev); |
@@ -774,13 +785,34 @@ static int mc13xxx_probe(struct spi_device *spi) | |||
774 | spi->bits_per_word = 32; | 785 | spi->bits_per_word = 32; |
775 | spi_setup(spi); | 786 | spi_setup(spi); |
776 | 787 | ||
788 | mc13xxx->dev = &spi->dev; | ||
777 | mc13xxx->spidev = spi; | 789 | mc13xxx->spidev = spi; |
778 | 790 | ||
791 | ret = mc13xxx_common_init(mc13xxx, pdata, spi->irq); | ||
792 | |||
793 | if (ret) { | ||
794 | dev_set_drvdata(&spi->dev, NULL); | ||
795 | } else { | ||
796 | const struct spi_device_id *devid = | ||
797 | spi_get_device_id(mc13xxx->spidev); | ||
798 | if (!devid || devid->driver_data != mc13xxx->ictype) | ||
799 | dev_warn(mc13xxx->dev, | ||
800 | "device id doesn't match auto detection!\n"); | ||
801 | } | ||
802 | |||
803 | return ret; | ||
804 | } | ||
805 | |||
806 | static int mc13xxx_common_init(struct mc13xxx *mc13xxx, | ||
807 | struct mc13xxx_platform_data *pdata, int irq) | ||
808 | { | ||
809 | int ret; | ||
810 | |||
779 | mutex_init(&mc13xxx->lock); | 811 | mutex_init(&mc13xxx->lock); |
780 | mc13xxx_lock(mc13xxx); | 812 | mc13xxx_lock(mc13xxx); |
781 | 813 | ||
782 | ret = mc13xxx_identify(mc13xxx, &id); | 814 | ret = mc13xxx_identify(mc13xxx); |
783 | if (ret || id == MC13XXX_ID_INVALID) | 815 | if (ret) |
784 | goto err_revision; | 816 | goto err_revision; |
785 | 817 | ||
786 | /* mask all irqs */ | 818 | /* mask all irqs */ |
@@ -792,18 +824,19 @@ static int mc13xxx_probe(struct spi_device *spi) | |||
792 | if (ret) | 824 | if (ret) |
793 | goto err_mask; | 825 | goto err_mask; |
794 | 826 | ||
795 | ret = request_threaded_irq(spi->irq, NULL, mc13xxx_irq_thread, | 827 | ret = request_threaded_irq(irq, NULL, mc13xxx_irq_thread, |
796 | IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx); | 828 | IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13xxx", mc13xxx); |
797 | 829 | ||
798 | if (ret) { | 830 | if (ret) { |
799 | err_mask: | 831 | err_mask: |
800 | err_revision: | 832 | err_revision: |
801 | mc13xxx_unlock(mc13xxx); | 833 | mc13xxx_unlock(mc13xxx); |
802 | dev_set_drvdata(&spi->dev, NULL); | ||
803 | kfree(mc13xxx); | 834 | kfree(mc13xxx); |
804 | return ret; | 835 | return ret; |
805 | } | 836 | } |
806 | 837 | ||
838 | mc13xxx->irq = irq; | ||
839 | |||
807 | mc13xxx_unlock(mc13xxx); | 840 | mc13xxx_unlock(mc13xxx); |
808 | 841 | ||
809 | if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) | 842 | if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) |
@@ -838,39 +871,44 @@ err_revision: | |||
838 | return 0; | 871 | return 0; |
839 | } | 872 | } |
840 | 873 | ||
841 | static int __devexit mc13xxx_remove(struct spi_device *spi) | 874 | static int __devexit mc13xxx_spi_remove(struct spi_device *spi) |
842 | { | 875 | { |
843 | struct mc13xxx *mc13xxx = dev_get_drvdata(&spi->dev); | 876 | struct mc13xxx *mc13xxx = dev_get_drvdata(&spi->dev); |
844 | 877 | ||
845 | free_irq(mc13xxx->spidev->irq, mc13xxx); | 878 | mc13xxx_common_cleanup(mc13xxx); |
846 | 879 | ||
847 | mfd_remove_devices(&spi->dev); | 880 | return 0; |
881 | } | ||
848 | 882 | ||
849 | kfree(mc13xxx); | 883 | static void mc13xxx_common_cleanup(struct mc13xxx *mc13xxx) |
884 | { | ||
885 | free_irq(mc13xxx->irq, mc13xxx); | ||
850 | 886 | ||
851 | return 0; | 887 | mfd_remove_devices(mc13xxx->dev); |
888 | |||
889 | kfree(mc13xxx); | ||
852 | } | 890 | } |
853 | 891 | ||
854 | static struct spi_driver mc13xxx_driver = { | 892 | static struct spi_driver mc13xxx_spi_driver = { |
855 | .id_table = mc13xxx_device_id, | 893 | .id_table = mc13xxx_device_id, |
856 | .driver = { | 894 | .driver = { |
857 | .name = "mc13xxx", | 895 | .name = "mc13xxx", |
858 | .owner = THIS_MODULE, | 896 | .owner = THIS_MODULE, |
859 | .of_match_table = mc13xxx_dt_ids, | 897 | .of_match_table = mc13xxx_dt_ids, |
860 | }, | 898 | }, |
861 | .probe = mc13xxx_probe, | 899 | .probe = mc13xxx_spi_probe, |
862 | .remove = __devexit_p(mc13xxx_remove), | 900 | .remove = __devexit_p(mc13xxx_spi_remove), |
863 | }; | 901 | }; |
864 | 902 | ||
865 | static int __init mc13xxx_init(void) | 903 | static int __init mc13xxx_init(void) |
866 | { | 904 | { |
867 | return spi_register_driver(&mc13xxx_driver); | 905 | return spi_register_driver(&mc13xxx_spi_driver); |
868 | } | 906 | } |
869 | subsys_initcall(mc13xxx_init); | 907 | subsys_initcall(mc13xxx_init); |
870 | 908 | ||
871 | static void __exit mc13xxx_exit(void) | 909 | static void __exit mc13xxx_exit(void) |
872 | { | 910 | { |
873 | spi_unregister_driver(&mc13xxx_driver); | 911 | spi_unregister_driver(&mc13xxx_spi_driver); |
874 | } | 912 | } |
875 | module_exit(mc13xxx_exit); | 913 | module_exit(mc13xxx_exit); |
876 | 914 | ||