]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[PATCH] ARM: OMAP: Add missing I2C patch
authorDavid Brownell <dbrownell@users.sourceforge.net>
Wed, 27 Jul 2005 07:41:44 +0000 (00:41 -0700)
committerTony Lindgren <tony@atomide.com>
Wed, 27 Jul 2005 07:41:44 +0000 (00:41 -0700)
The original dev-i2c.patch somehow got left out. This patch
makes I2C to use driver model.

arch/arm/mach-omap1/devices.c
drivers/i2c/busses/i2c-omap.c

index 0f61527e5597cf6e1b4a6c11eb90749b400800b3..e8b3981444cd0d9da280a58374efa28bd9154bdb 100644 (file)
 #include <asm/arch/gpio.h>
 
 
+static void omap_nop_release(struct device *dev)
+{
+        /* Nothing */
+}
+
+/*-------------------------------------------------------------------------*/
+
+#if    defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
+
+#define        OMAP_I2C_BASE           0xfffb3800
+
+static struct resource i2c_resources[] = {
+       {
+               .start          = OMAP_I2C_BASE,
+               .end            = OMAP_I2C_BASE + 0x3f,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = INT_I2C,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+/* DMA not used; works around erratum writing to non-empty i2c fifo */
+
+static struct platform_device omap_i2c_device = {
+        .name           = "i2c_omap",
+        .id             = -1,
+        .dev = {
+                .release        = omap_nop_release,
+        },
+       .num_resources  = ARRAY_SIZE(i2c_resources),
+       .resource       = i2c_resources,
+};
+
+static void omap_init_i2c(void)
+{
+       /* FIXME define and use a boot tag, in case of boards that
+        * either don't wire up I2C, or chips that mux it differently...
+        * it can include clocking and address info, maybe more.
+        */
+       omap_cfg_reg(I2C_SCL);
+       omap_cfg_reg(I2C_SDA);
+
+       (void) platform_device_register(&omap_i2c_device);
+}
+#else
+static inline void omap_init_i2c(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
 #if    defined(CONFIG_OMAP1610_IR) || defined(CONFIG_OMAP161O_IR_MODULE)
 
 static u64 irda_dmamask = 0xffffffff;
@@ -56,44 +108,6 @@ static void omap_init_irda(void)
 static inline void omap_init_irda(void) {}
 #endif
 
-#if    defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC)
-
-#define        OMAP_RTC_BASE           0xfffb4800
-
-static struct resource rtc_resources[] = {
-       {
-               .start          = OMAP_RTC_BASE,
-               .end            = OMAP_RTC_BASE + 0x5f,
-               .flags          = IORESOURCE_MEM,
-       },
-       {
-               .start          = INT_RTC_TIMER,
-               .flags          = IORESOURCE_IRQ,
-       },
-       {
-               .start          = INT_RTC_ALARM,
-               .flags          = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device omap_rtc_device = {
-       .name      = "omap_rtc",
-       .id          = -1,
-       .dev = {
-               .release        = omap_nop_release,
-       },
-       .num_resources  = ARRAY_SIZE(rtc_resources),
-       .resource       = rtc_resources,
-};
-
-static void omap_init_rtc(void)
-{
-       (void) platform_device_register(&omap_rtc_device);
-}
-#else
-static inline void omap_init_rtc(void) {}
-#endif
-
 /*-------------------------------------------------------------------------*/
 
 #if    defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
@@ -101,11 +115,6 @@ static inline void omap_init_rtc(void) {}
 #define        OMAP_MMC1_BASE          0xfffb7800
 #define        OMAP_MMC2_BASE          0xfffb7c00      /* omap16xx only */
 
-static void mmc_release(struct device *dev)
-{
-       /* Nothing to release */
-}
-
 static struct omap_mmc_conf mmc1_conf;
 
 static u64 mmc1_dmamask = 0xffffffff;
@@ -126,7 +135,7 @@ static struct platform_device mmc_omap_device1 = {
        .name           = "mmci-omap",
        .id             = 1,
        .dev = {
-               .release        = mmc_release,
+               .release        = omap_nop_release,
                .dma_mask       = &mmc1_dmamask,
                .platform_data  = &mmc1_conf,
        },
@@ -156,7 +165,7 @@ static struct platform_device mmc_omap_device2 = {
        .name           = "mmci-omap",
        .id             = 2,
        .dev = {
-               .release        = mmc_release,
+               .release        = omap_nop_release,
                .dma_mask       = &mmc2_dmamask,
                .platform_data  = &mmc2_conf,
        },
@@ -232,6 +241,46 @@ static void __init omap_init_mmc(void)
 static inline void omap_init_mmc(void) {}
 #endif
 
+#if    defined(CONFIG_OMAP_RTC) || defined(CONFIG_OMAP_RTC)
+
+#define        OMAP_RTC_BASE           0xfffb4800
+
+static struct resource rtc_resources[] = {
+       {
+               .start          = OMAP_RTC_BASE,
+               .end            = OMAP_RTC_BASE + 0x5f,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = INT_RTC_TIMER,
+               .flags          = IORESOURCE_IRQ,
+       },
+       {
+               .start          = INT_RTC_ALARM,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device omap_rtc_device = {
+       .name           = "omap_rtc",
+       .id             = -1,
+       .dev = {
+               .release        = omap_nop_release,
+       },
+       .num_resources  = ARRAY_SIZE(rtc_resources),
+       .resource       = rtc_resources,
+};
+
+static void omap_init_rtc(void)
+{
+       (void) platform_device_register(&omap_rtc_device);
+}
+#else
+static inline void omap_init_rtc(void) {}
+#endif
+
+/*-------------------------------------------------------------------------*/
+
 #if    defined(CONFIG_OMAP16XX_WATCHDOG) || defined(CONFIG_OMAP16XX_WATCHDOG_MODULE)
 
 #define        OMAP_WDT_BASE           0xfffeb000
@@ -287,7 +336,10 @@ static inline void omap_init_wdt(void) {}
  */
 static int __init omap_init_devices(void)
 {
-       //omap_init_i2c();
+       /* please keep these calls, and their implementations above,
+        * in alphabetical order so they're easier to sort through.
+        */
+       omap_init_i2c();
        omap_init_irda();
        omap_init_mmc();
        omap_init_rtc();
index 82a2014cf135b4bcc01d0fa9e3cde52386c5b73c..fe30caee8b950d6d6f702949bfac7521e111b3aa 100644 (file)
@@ -430,16 +430,6 @@ omap_i2c_isr(int this_irq, void *dev_id, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
-static int omap_i2c_remove(struct device *dev)
-{
-        return 0;
-}
-
-static void omap_i2c_device_release(struct device *dev)
-{
-        /* Nothing */
-}
-
 static struct i2c_algorithm omap_i2c_algo = {
        .name           = "OMAP I2C algorithm",
        .id             = I2C_ALGO_EXP,
@@ -454,27 +444,20 @@ static struct i2c_adapter omap_i2c_adap = {
        .algo           = &omap_i2c_algo,
 };
 
-static struct device_driver omap_i2c_driver = {
-        .name           = "omap_i2c",
-        .bus            = &platform_bus_type,
-        .remove         = omap_i2c_remove,
-};
-
-static struct platform_device omap_i2c_device = {
-        .name           = "i2c",
-        .id             = -1,
-        .dev = {
-                .driver         = &omap_i2c_driver,
-                .release        = omap_i2c_device_release,
-        },
-};
-
 static int __init
-omap_i2c_init(void)
+omap_i2c_probe(struct device *dev)
 {
+       struct platform_device  *pdev = to_platform_device(dev);
+       struct resource         *mem;
        int r;
 
-       r = (int) request_mem_region(io_v2p(OMAP_I2C_BASE), OMAP_I2C_IOSIZE,
+       /* NOTE:  driver uses the static register mapping */
+       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!mem) {
+               pr_debug("%s: no mem resource?\n", driver_name);
+               return -ENODEV;
+       }
+       r = (int) request_mem_region(mem->start, (mem->end - mem->start) + 1,
                        driver_name);
        if (!r) {
                pr_debug("%s: I2C region already claimed\n", driver_name);
@@ -492,6 +475,9 @@ omap_i2c_init(void)
        memset(&omap_i2c_dev, 0, sizeof(omap_i2c_dev));
        init_waitqueue_head(&omap_i2c_dev.cmd_wait);
 
+       /* reset ASAP, clearing any IRQs */
+       omap_i2c_reset();
+
        r = request_irq(INT_I2C, omap_i2c_isr, 0, driver_name, &omap_i2c_dev);
        if (r) {
                pr_debug("%s: failure requesting irq\n", driver_name);
@@ -502,51 +488,59 @@ omap_i2c_init(void)
        pr_info("%s: rev%d.%d at %d KHz\n", driver_name,
                        r >> 4, r & 0xf, clock);
 
+       /* i2c device drivers may be active on return from add_adapter() */
        i2c_set_adapdata(&omap_i2c_adap, &omap_i2c_dev);
+       omap_i2c_adap.dev.parent = dev;
        r = i2c_add_adapter(&omap_i2c_adap);
        if (r) {
                pr_debug("%s: failure adding adapter\n", driver_name);
                goto do_free_irq;
        }
 
-       /* configure I/O pin multiplexing */
-       /* FIXME: This should be done in bootloader */
-       omap_cfg_reg(I2C_SCL);
-       omap_cfg_reg(I2C_SDA);
-
-       omap_i2c_reset();
-
-       if(driver_register(&omap_i2c_driver) != 0)
-               printk(KERN_ERR "Driver register failed for omap_i2c\n");
-       if(platform_device_register(&omap_i2c_device) != 0) {
-               printk(KERN_ERR "Device register failed for i2c\n");
-               driver_unregister(&omap_i2c_driver);
-       }
-
        return 0;
 
 do_free_irq:
        free_irq(INT_I2C, &omap_i2c_dev);
 do_release_region:
-       release_region(io_v2p(OMAP_I2C_BASE), OMAP_I2C_IOSIZE);
+       writew(0, OMAP_I2C_CON);
+       release_mem_region(mem->start, (mem->end - mem->start) + 1);
 
        return r;
 }
 
 static void __exit
-omap_i2c_exit(void)
+omap_i2c_remove(struct device *dev)
 {
-       i2c_del_adapter(&omap_i2c_adap);
+       struct platform_device  *pdev = to_platform_device(dev);
+       struct resource         *mem;
+
        writew(0, OMAP_I2C_CON);
+       i2c_del_adapter(&omap_i2c_adap);
        free_irq(INT_I2C, &omap_i2c_dev);
-       release_region(io_v2p(OMAP_I2C_BASE), OMAP_I2C_IOSIZE);
-        driver_unregister(&omap_i2c_driver);
-        platform_device_unregister(&omap_i2c_device);
+       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(mem->start, (mem->end - mem->start) + 1);
 }
 
+static struct device_driver omap_i2c_driver = {
+       .name           = (char *)driver_name,
+       .bus            = &platform_bus_type,
+       .probe          = omap_i2c_probe,
+       .remove         = __exit_p(omap_i2c_remove),
+};
+
 /* i2c may be needed to bring up other drivers */
-subsys_initcall(omap_i2c_init);
-module_exit(omap_i2c_exit);
+static int __init
+omap_i2c_init_driver(void)
+{
+       return driver_register(&omap_i2c_driver);
+}
+subsys_initcall(omap_i2c_init_driver);
+
+static void __exit omap_i2c_exit_driver(void)
+{
+       driver_unregister(&omap_i2c_driver);
+}
+module_exit(omap_i2c_exit_driver);
 
 MODULE_AUTHOR("MontaVista Software, Inc. (and others)");
 MODULE_DESCRIPTION("TI OMAP I2C bus adapter");