diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-stu300.c')
| -rw-r--r-- | drivers/i2c/busses/i2c-stu300.c | 141 |
1 files changed, 49 insertions, 92 deletions
diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c index 495be451d32..fefb1c19ec1 100644 --- a/drivers/i2c/busses/i2c-stu300.c +++ b/drivers/i2c/busses/i2c-stu300.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2009 ST-Ericsson AB + * Copyright (C) 2007-2012 ST-Ericsson AB * License terms: GNU General Public License (GPL) version 2 * ST DDC I2C master mode driver, used in e.g. U300 series platforms. * Author: Linus Walleij <linus.walleij@stericsson.com> @@ -139,8 +139,6 @@ module_param(scl_frequency, uint, 0644); * struct stu300_dev - the stu300 driver state holder * @pdev: parent platform device * @adapter: corresponding I2C adapter - * @phybase: location of I/O area in memory - * @physize: size of I/O area in memory * @clk: hardware block clock * @irq: assigned interrupt line * @cmd_issue_lock: this locks the following cmd_ variables @@ -155,8 +153,6 @@ module_param(scl_frequency, uint, 0644); struct stu300_dev { struct platform_device *pdev; struct i2c_adapter adapter; - resource_size_t phybase; - resource_size_t physize; void __iomem *virtbase; struct clk *clk; int irq; @@ -497,7 +493,7 @@ static int stu300_set_clk(struct stu300_dev *dev, unsigned long clkrate) u32 val; int i = 0; - /* Locate the apropriate clock setting */ + /* Locate the appropriate clock setting */ while (i < ARRAY_SIZE(stu300_clktable) - 1 && stu300_clktable[i].rate < clkrate) i++; @@ -644,7 +640,7 @@ static int stu300_send_address(struct stu300_dev *dev, ret = stu300_await_event(dev, STU300_EVENT_6); /* - * Clear any pending EVENT 6 no matter what happend during + * Clear any pending EVENT 6 no matter what happened during * await_event. */ val = stu300_r8(dev->virtbase + I2C_CR); @@ -805,7 +801,7 @@ static int stu300_xfer_msg(struct i2c_adapter *adap, /* Check that the bus is free, or wait until some timeout occurs */ ret = stu300_wait_while_busy(dev); if (ret != 0) { - dev_err(&dev->pdev->dev, "timout waiting for transfer " + dev_err(&dev->pdev->dev, "timeout waiting for transfer " "to commence.\n"); goto exit_disable; } @@ -863,74 +859,46 @@ static const struct i2c_algorithm stu300_algo = { .functionality = stu300_func, }; -static int __init -stu300_probe(struct platform_device *pdev) +static int stu300_probe(struct platform_device *pdev) { struct stu300_dev *dev; struct i2c_adapter *adap; struct resource *res; int bus_nr; int ret = 0; - char clk_name[] = "I2C0"; - dev = kzalloc(sizeof(struct stu300_dev), GFP_KERNEL); - if (!dev) { - dev_err(&pdev->dev, "could not allocate device struct\n"); - ret = -ENOMEM; - goto err_no_devmem; - } + dev = devm_kzalloc(&pdev->dev, sizeof(struct stu300_dev), GFP_KERNEL); + if (!dev) + return -ENOMEM; bus_nr = pdev->id; - clk_name[3] += (char)bus_nr; - dev->clk = clk_get(&pdev->dev, clk_name); + dev->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(dev->clk)) { - ret = PTR_ERR(dev->clk); dev_err(&pdev->dev, "could not retrieve i2c bus clock\n"); - goto err_no_clk; + return PTR_ERR(dev->clk); } dev->pdev = pdev; - platform_set_drvdata(pdev, dev); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENOENT; - goto err_no_resource; - } - - dev->phybase = res->start; - dev->physize = resource_size(res); - - if (request_mem_region(dev->phybase, dev->physize, - NAME " I/O Area") == NULL) { - ret = -EBUSY; - goto err_no_ioregion; - } - - dev->virtbase = ioremap(dev->phybase, dev->physize); + dev->virtbase = devm_ioremap_resource(&pdev->dev, res); dev_dbg(&pdev->dev, "initialize bus device I2C%d on virtual " "base %p\n", bus_nr, dev->virtbase); - if (!dev->virtbase) { - ret = -ENOMEM; - goto err_no_ioremap; - } + if (IS_ERR(dev->virtbase)) + return PTR_ERR(dev->virtbase); dev->irq = platform_get_irq(pdev, 0); - if (request_irq(dev->irq, stu300_irh, IRQF_DISABLED, - NAME, dev)) { - ret = -EIO; - goto err_no_irq; - } + ret = devm_request_irq(&pdev->dev, dev->irq, stu300_irh, 0, NAME, dev); + if (ret < 0) + return ret; dev->speed = scl_frequency; - clk_enable(dev->clk); + clk_prepare_enable(dev->clk); ret = stu300_init_hw(dev); clk_disable(dev->clk); - if (ret != 0) { dev_err(&dev->pdev->dev, "error initializing hardware.\n"); - goto err_init_hw; + return -EIO; } /* IRQ event handling initialization */ @@ -941,101 +909,90 @@ stu300_probe(struct platform_device *pdev) adap = &dev->adapter; adap->owner = THIS_MODULE; /* DDC class but actually often used for more generic I2C */ - adap->class = I2C_CLASS_DDC; - strncpy(adap->name, "ST Microelectronics DDC I2C adapter", + adap->class = I2C_CLASS_DDC | I2C_CLASS_DEPRECATED; + strlcpy(adap->name, "ST Microelectronics DDC I2C adapter", sizeof(adap->name)); adap->nr = bus_nr; adap->algo = &stu300_algo; adap->dev.parent = &pdev->dev; + adap->dev.of_node = pdev->dev.of_node; i2c_set_adapdata(adap, dev); /* i2c device drivers may be active on return from add_adapter() */ ret = i2c_add_numbered_adapter(adap); if (ret) { - dev_err(&dev->pdev->dev, "failure adding ST Micro DDC " + dev_err(&pdev->dev, "failure adding ST Micro DDC " "I2C adapter\n"); - goto err_add_adapter; + return ret; } - return 0; - err_add_adapter: - err_init_hw: - free_irq(dev->irq, dev); - err_no_irq: - iounmap(dev->virtbase); - err_no_ioremap: - release_mem_region(dev->phybase, dev->physize); - err_no_ioregion: - platform_set_drvdata(pdev, NULL); - err_no_resource: - clk_put(dev->clk); - err_no_clk: - kfree(dev); - err_no_devmem: - dev_err(&pdev->dev, "failed to add " NAME " adapter: %d\n", - pdev->id); - return ret; + platform_set_drvdata(pdev, dev); + dev_info(&pdev->dev, "ST DDC I2C @ %p, irq %d\n", + dev->virtbase, dev->irq); + + return 0; } -#ifdef CONFIG_PM -static int stu300_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int stu300_suspend(struct device *device) { - struct stu300_dev *dev = platform_get_drvdata(pdev); + struct stu300_dev *dev = dev_get_drvdata(device); /* Turn off everything */ stu300_wr8(0x00, dev->virtbase + I2C_CR); return 0; } -static int stu300_resume(struct platform_device *pdev) +static int stu300_resume(struct device *device) { int ret = 0; - struct stu300_dev *dev = platform_get_drvdata(pdev); + struct stu300_dev *dev = dev_get_drvdata(device); clk_enable(dev->clk); ret = stu300_init_hw(dev); clk_disable(dev->clk); if (ret != 0) - dev_err(&pdev->dev, "error re-initializing hardware.\n"); + dev_err(device, "error re-initializing hardware.\n"); return ret; } + +static SIMPLE_DEV_PM_OPS(stu300_pm, stu300_suspend, stu300_resume); +#define STU300_I2C_PM (&stu300_pm) #else -#define stu300_suspend NULL -#define stu300_resume NULL +#define STU300_I2C_PM NULL #endif -static int __exit -stu300_remove(struct platform_device *pdev) +static int stu300_remove(struct platform_device *pdev) { struct stu300_dev *dev = platform_get_drvdata(pdev); i2c_del_adapter(&dev->adapter); /* Turn off everything */ stu300_wr8(0x00, dev->virtbase + I2C_CR); - free_irq(dev->irq, dev); - iounmap(dev->virtbase); - release_mem_region(dev->phybase, dev->physize); - clk_put(dev->clk); - platform_set_drvdata(pdev, NULL); - kfree(dev); return 0; } +static const struct of_device_id stu300_dt_match[] = { + { .compatible = "st,ddci2c" }, + {}, +}; + static struct platform_driver stu300_i2c_driver = { .driver = { .name = NAME, .owner = THIS_MODULE, + .pm = STU300_I2C_PM, + .of_match_table = stu300_dt_match, }, - .remove = __exit_p(stu300_remove), - .suspend = stu300_suspend, - .resume = stu300_resume, + .probe = stu300_probe, + .remove = stu300_remove, }; static int __init stu300_init(void) { - return platform_driver_probe(&stu300_i2c_driver, stu300_probe); + return platform_driver_register(&stu300_i2c_driver); } static void __exit stu300_exit(void) |
