From: David Brownell Date: Wed, 27 Jul 2005 07:41:44 +0000 (-0700) Subject: [PATCH] ARM: OMAP: Add missing I2C patch X-Git-Tag: v2.6.13-omap1~52 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=5faf49c0463275f42ef93df571b701d7bbb54960;p=linux-2.6-omap-h63xx.git [PATCH] ARM: OMAP: Add missing I2C patch The original dev-i2c.patch somehow got left out. This patch makes I2C to use driver model. --- diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c index 0f61527e559..e8b3981444c 100644 --- a/arch/arm/mach-omap1/devices.c +++ b/arch/arm/mach-omap1/devices.c @@ -26,6 +26,58 @@ #include +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(); diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 82a2014cf13..fe30caee8b9 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -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");