aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean MacLennan <smaclennan@pikatech.com>2008-04-22 16:16:47 -0400
committerJean Delvare <khali@hyperion.delvare>2008-04-22 16:16:47 -0400
commit838349b5c6454ebce8ec3e8c448941cf8608ffea (patch)
tree217444e5c41d5da9513d7a5881043fd758801365
parent681aae82c5804f8bbecbb495da90587d4167753c (diff)
i2c-ibm_iic: Support building as an of_platform driver
This patch allows the i2c-ibm_iic driver to be built either as an ocp driver or an of_platform driver. This allows it to run under the powerpc arch but maintains backward compatibility with the ppc arch. Signed-off-by: Sean MacLennan <smaclennan@pikatech.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-ibm_iic.c187
2 files changed, 187 insertions, 2 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 51de2ccc1519..1577bcad288a 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -246,7 +246,7 @@ config I2C_PIIX4
246 246
247config I2C_IBM_IIC 247config I2C_IBM_IIC
248 tristate "IBM PPC 4xx on-chip I2C interface" 248 tristate "IBM PPC 4xx on-chip I2C interface"
249 depends on IBM_OCP 249 depends on 4xx
250 help 250 help
251 Say Y here if you want to use IIC peripheral found on 251 Say Y here if you want to use IIC peripheral found on
252 embedded IBM PPC 4xx based systems. 252 embedded IBM PPC 4xx based systems.
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index b330a0c9a6a5..85dbf34382e1 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -6,6 +6,9 @@
6 * Copyright (c) 2003, 2004 Zultys Technologies. 6 * Copyright (c) 2003, 2004 Zultys Technologies.
7 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> 7 * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
8 * 8 *
9 * Copyright (c) 2008 PIKA Technologies
10 * Sean MacLennan <smaclennan@pikatech.com>
11 *
9 * Based on original work by 12 * Based on original work by
10 * Ian DaSilva <idasilva@mvista.com> 13 * Ian DaSilva <idasilva@mvista.com>
11 * Armin Kuster <akuster@mvista.com> 14 * Armin Kuster <akuster@mvista.com>
@@ -39,12 +42,17 @@
39#include <asm/io.h> 42#include <asm/io.h>
40#include <linux/i2c.h> 43#include <linux/i2c.h>
41#include <linux/i2c-id.h> 44#include <linux/i2c-id.h>
45
46#ifdef CONFIG_IBM_OCP
42#include <asm/ocp.h> 47#include <asm/ocp.h>
43#include <asm/ibm4xx.h> 48#include <asm/ibm4xx.h>
49#else
50#include <linux/of_platform.h>
51#endif
44 52
45#include "i2c-ibm_iic.h" 53#include "i2c-ibm_iic.h"
46 54
47#define DRIVER_VERSION "2.1" 55#define DRIVER_VERSION "2.2"
48 56
49MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION); 57MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION);
50MODULE_LICENSE("GPL"); 58MODULE_LICENSE("GPL");
@@ -657,6 +665,7 @@ static inline u8 iic_clckdiv(unsigned int opb)
657 return (u8)((opb + 9) / 10 - 1); 665 return (u8)((opb + 9) / 10 - 1);
658} 666}
659 667
668#ifdef CONFIG_IBM_OCP
660/* 669/*
661 * Register single IIC interface 670 * Register single IIC interface
662 */ 671 */
@@ -828,5 +837,181 @@ static void __exit iic_exit(void)
828 ocp_unregister_driver(&ibm_iic_driver); 837 ocp_unregister_driver(&ibm_iic_driver);
829} 838}
830 839
840#else /* !CONFIG_IBM_OCP */
841
842static int __devinit iic_request_irq(struct of_device *ofdev,
843 struct ibm_iic_private *dev)
844{
845 struct device_node *np = ofdev->node;
846 int irq;
847
848 if (iic_force_poll)
849 return NO_IRQ;
850
851 irq = irq_of_parse_and_map(np, 0);
852 if (irq == NO_IRQ) {
853 dev_err(&ofdev->dev, "irq_of_parse_and_map failed\n");
854 return NO_IRQ;
855 }
856
857 /* Disable interrupts until we finish initialization, assumes
858 * level-sensitive IRQ setup...
859 */
860 iic_interrupt_mode(dev, 0);
861 if (request_irq(irq, iic_handler, 0, "IBM IIC", dev)) {
862 dev_err(&ofdev->dev, "request_irq %d failed\n", irq);
863 /* Fallback to the polling mode */
864 return NO_IRQ;
865 }
866
867 return irq;
868}
869
870/*
871 * Register single IIC interface
872 */
873static int __devinit iic_probe(struct of_device *ofdev,
874 const struct of_device_id *match)
875{
876 struct device_node *np = ofdev->node;
877 struct ibm_iic_private *dev;
878 struct i2c_adapter *adap;
879 const u32 *indexp, *freq;
880 int ret;
881
882 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
883 if (!dev) {
884 dev_err(&ofdev->dev, "failed to allocate device data\n");
885 return -ENOMEM;
886 }
887
888 dev_set_drvdata(&ofdev->dev, dev);
889
890 indexp = of_get_property(np, "index", NULL);
891 if (!indexp) {
892 dev_err(&ofdev->dev, "no index specified\n");
893 ret = -EINVAL;
894 goto error_cleanup;
895 }
896 dev->idx = *indexp;
897
898 dev->vaddr = of_iomap(np, 0);
899 if (dev->vaddr == NULL) {
900 dev_err(&ofdev->dev, "failed to iomap device\n");
901 ret = -ENXIO;
902 goto error_cleanup;
903 }
904
905 init_waitqueue_head(&dev->wq);
906
907 dev->irq = iic_request_irq(ofdev, dev);
908 if (dev->irq == NO_IRQ)
909 dev_warn(&ofdev->dev, "using polling mode\n");
910
911 /* Board specific settings */
912 if (iic_force_fast || of_get_property(np, "fast-mode", NULL))
913 dev->fast_mode = 1;
914
915 freq = of_get_property(np, "clock-frequency", NULL);
916 if (freq == NULL) {
917 freq = of_get_property(np->parent, "clock-frequency", NULL);
918 if (freq == NULL) {
919 dev_err(&ofdev->dev, "Unable to get bus frequency\n");
920 ret = -EINVAL;
921 goto error_cleanup;
922 }
923 }
924
925 dev->clckdiv = iic_clckdiv(*freq);
926 dev_dbg(&ofdev->dev, "clckdiv = %d\n", dev->clckdiv);
927
928 /* Initialize IIC interface */
929 iic_dev_init(dev);
930
931 /* Register it with i2c layer */
932 adap = &dev->adap;
933 adap->dev.parent = &ofdev->dev;
934 strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
935 i2c_set_adapdata(adap, dev);
936 adap->id = I2C_HW_OCP;
937 adap->class = I2C_CLASS_HWMON;
938 adap->algo = &iic_algo;
939 adap->timeout = 1;
940 adap->nr = dev->idx;
941
942 ret = i2c_add_numbered_adapter(adap);
943 if (ret < 0) {
944 dev_err(&ofdev->dev, "failed to register i2c adapter\n");
945 goto error_cleanup;
946 }
947
948 dev_info(&ofdev->dev, "using %s mode\n",
949 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
950
951 return 0;
952
953error_cleanup:
954 if (dev->irq != NO_IRQ) {
955 iic_interrupt_mode(dev, 0);
956 free_irq(dev->irq, dev);
957 }
958
959 if (dev->vaddr)
960 iounmap(dev->vaddr);
961
962 dev_set_drvdata(&ofdev->dev, NULL);
963 kfree(dev);
964 return ret;
965}
966
967/*
968 * Cleanup initialized IIC interface
969 */
970static int __devexit iic_remove(struct of_device *ofdev)
971{
972 struct ibm_iic_private *dev = dev_get_drvdata(&ofdev->dev);
973
974 dev_set_drvdata(&ofdev->dev, NULL);
975
976 i2c_del_adapter(&dev->adap);
977
978 if (dev->irq != NO_IRQ) {
979 iic_interrupt_mode(dev, 0);
980 free_irq(dev->irq, dev);
981 }
982
983 iounmap(dev->vaddr);
984 kfree(dev);
985
986 return 0;
987}
988
989static const struct of_device_id ibm_iic_match[] = {
990 { .compatible = "ibm,iic-405ex", },
991 { .compatible = "ibm,iic-405gp", },
992 { .compatible = "ibm,iic-440gp", },
993 { .compatible = "ibm,iic-440gpx", },
994 { .compatible = "ibm,iic-440grx", },
995 {}
996};
997
998static struct of_platform_driver ibm_iic_driver = {
999 .name = "ibm-iic",
1000 .match_table = ibm_iic_match,
1001 .probe = iic_probe,
1002 .remove = __devexit_p(iic_remove),
1003};
1004
1005static int __init iic_init(void)
1006{
1007 return of_register_platform_driver(&ibm_iic_driver);
1008}
1009
1010static void __exit iic_exit(void)
1011{
1012 of_unregister_platform_driver(&ibm_iic_driver);
1013}
1014#endif /* CONFIG_IBM_OCP */
1015
831module_init(iic_init); 1016module_init(iic_init);
832module_exit(iic_exit); 1017module_exit(iic_exit);