diff options
Diffstat (limited to 'drivers/mfd/menelaus.c')
| -rw-r--r-- | drivers/mfd/menelaus.c | 122 |
1 files changed, 27 insertions, 95 deletions
diff --git a/drivers/mfd/menelaus.c b/drivers/mfd/menelaus.c index 998ce8cb3065..a125d40fa121 100644 --- a/drivers/mfd/menelaus.c +++ b/drivers/mfd/menelaus.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2004 Texas Instruments, Inc. * @@ -15,20 +16,6 @@ * Added support for controlling VCORE and regulator sleep states, * Amit Kucheria <amit.kucheria@nokia.com> * Copyright (C) 2005, 2006 Nokia Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/module.h> @@ -45,7 +32,6 @@ #include <asm/mach/irq.h> -#include <asm/gpio.h> #define DRIVER_NAME "menelaus" @@ -442,7 +428,7 @@ void menelaus_unregister_mmc_callback(void) menelaus_remove_irq_work(MENELAUS_MMC_S2D1_IRQ); the_menelaus->mmc_callback = NULL; - the_menelaus->mmc_callback_data = 0; + the_menelaus->mmc_callback_data = NULL; } EXPORT_SYMBOL(menelaus_unregister_mmc_callback); @@ -466,8 +452,6 @@ static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV, struct i2c_client *c = the_menelaus->client; mutex_lock(&the_menelaus->lock); - if (vtg == 0) - goto set_voltage; ret = menelaus_read_reg(vtg->vtg_reg); if (ret < 0) @@ -482,7 +466,6 @@ static int menelaus_set_voltage(const struct menelaus_vtg *vtg, int mV, ret = menelaus_write_reg(vtg->vtg_reg, val); if (ret < 0) goto out; -set_voltage: ret = menelaus_write_reg(vtg->mode_reg, mode); out: mutex_unlock(&the_menelaus->lock); @@ -535,29 +518,6 @@ static const struct menelaus_vtg_value vcore_values[] = { { 1450, 18 }, }; -int menelaus_set_vcore_sw(unsigned int mV) -{ - int val, ret; - struct i2c_client *c = the_menelaus->client; - - val = menelaus_get_vtg_value(mV, vcore_values, - ARRAY_SIZE(vcore_values)); - if (val < 0) - return -EINVAL; - - dev_dbg(&c->dev, "Setting VCORE to %d mV (val 0x%02x)\n", mV, val); - - /* Set SW mode and the voltage in one go. */ - mutex_lock(&the_menelaus->lock); - ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val); - if (ret == 0) - the_menelaus->vcore_hw_mode = 0; - mutex_unlock(&the_menelaus->lock); - msleep(1); - - return ret; -} - int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV) { int fval, rval, val, ret; @@ -1048,9 +1008,7 @@ static int menelaus_set_alarm(struct device *dev, struct rtc_wkalrm *w) static void menelaus_rtc_update_work(struct menelaus_chip *m) { /* report 1/sec update */ - local_irq_disable(); rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_UF); - local_irq_enable(); } static int menelaus_ioctl(struct device *dev, unsigned cmd, unsigned long arg) @@ -1112,9 +1070,7 @@ static const struct rtc_class_ops menelaus_rtc_ops = { static void menelaus_rtc_alarm_work(struct menelaus_chip *m) { /* report alarm */ - local_irq_disable(); rtc_update_irq(m->rtc, 1, RTC_IRQF | RTC_AF); - local_irq_enable(); /* then disable it; alarms are oneshot */ the_menelaus->rtc_control &= ~RTC_CTRL_AL_EN; @@ -1124,6 +1080,7 @@ static void menelaus_rtc_alarm_work(struct menelaus_chip *m) static inline void menelaus_rtc_init(struct menelaus_chip *m) { int alarm = (m->client->irq > 0); + int err; /* assume 32KDETEN pin is pulled high */ if (!(menelaus_read_reg(MENELAUS_OSC_CTRL) & 0x80)) { @@ -1131,6 +1088,12 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m) return; } + m->rtc = devm_rtc_allocate_device(&m->client->dev); + if (IS_ERR(m->rtc)) + return; + + m->rtc->ops = &menelaus_rtc_ops; + /* support RTC alarm; it can issue wakeups */ if (alarm) { if (menelaus_add_irq_work(MENELAUS_RTCALM_IRQ, @@ -1155,16 +1118,12 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m) menelaus_write_reg(MENELAUS_RTC_CTRL, m->rtc_control); } - m->rtc = rtc_device_register(DRIVER_NAME, - &m->client->dev, - &menelaus_rtc_ops, THIS_MODULE); - if (IS_ERR(m->rtc)) { + err = devm_rtc_register_device(m->rtc); + if (err) { if (alarm) { menelaus_remove_irq_work(MENELAUS_RTCALM_IRQ); device_init_wakeup(&m->client->dev, 0); } - dev_err(&m->client->dev, "can't register RTC: %d\n", - (int) PTR_ERR(m->rtc)); the_menelaus->rtc = NULL; } } @@ -1182,14 +1141,13 @@ static inline void menelaus_rtc_init(struct menelaus_chip *m) static struct i2c_driver menelaus_i2c_driver; -static int menelaus_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int menelaus_probe(struct i2c_client *client) { struct menelaus_chip *menelaus; - int rev = 0, val; + int rev = 0; int err = 0; struct menelaus_platform_data *menelaus_pdata = - client->dev.platform_data; + dev_get_platdata(&client->dev); if (the_menelaus) { dev_dbg(&client->dev, "only one %s for now\n", @@ -1197,7 +1155,7 @@ static int menelaus_probe(struct i2c_client *client, return -ENODEV; } - menelaus = kzalloc(sizeof *menelaus, GFP_KERNEL); + menelaus = devm_kzalloc(&client->dev, sizeof(*menelaus), GFP_KERNEL); if (!menelaus) return -ENOMEM; @@ -1210,8 +1168,7 @@ static int menelaus_probe(struct i2c_client *client, rev = menelaus_read_reg(MENELAUS_REV); if (rev < 0) { pr_err(DRIVER_NAME ": device not found"); - err = -ENODEV; - goto fail1; + return -ENODEV; } /* Ack and disable all Menelaus interrupts */ @@ -1231,7 +1188,7 @@ static int menelaus_probe(struct i2c_client *client, if (err) { dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", client->irq, err); - goto fail1; + return err; } } @@ -1240,10 +1197,10 @@ static int menelaus_probe(struct i2c_client *client, pr_info("Menelaus rev %d.%d\n", rev >> 4, rev & 0x0f); - val = menelaus_read_reg(MENELAUS_VCORE_CTRL1); - if (val < 0) - goto fail2; - if (val & (1 << 7)) + err = menelaus_read_reg(MENELAUS_VCORE_CTRL1); + if (err < 0) + goto fail; + if (err & VCORE_CTRL1_HW_NSW) menelaus->vcore_hw_mode = 1; else menelaus->vcore_hw_mode = 0; @@ -1251,33 +1208,29 @@ static int menelaus_probe(struct i2c_client *client, if (menelaus_pdata != NULL && menelaus_pdata->late_init != NULL) { err = menelaus_pdata->late_init(&client->dev); if (err < 0) - goto fail2; + goto fail; } menelaus_rtc_init(menelaus); return 0; -fail2: +fail: free_irq(client->irq, menelaus); flush_work(&menelaus->work); -fail1: - kfree(menelaus); return err; } -static int __exit menelaus_remove(struct i2c_client *client) +static void menelaus_remove(struct i2c_client *client) { struct menelaus_chip *menelaus = i2c_get_clientdata(client); free_irq(client->irq, menelaus); flush_work(&menelaus->work); - kfree(menelaus); the_menelaus = NULL; - return 0; } static const struct i2c_device_id menelaus_id[] = { - { "menelaus", 0 }, + { "menelaus" }, { } }; MODULE_DEVICE_TABLE(i2c, menelaus_id); @@ -1287,33 +1240,12 @@ static struct i2c_driver menelaus_i2c_driver = { .name = DRIVER_NAME, }, .probe = menelaus_probe, - .remove = __exit_p(menelaus_remove), + .remove = menelaus_remove, .id_table = menelaus_id, }; -static int __init menelaus_init(void) -{ - int res; - - res = i2c_add_driver(&menelaus_i2c_driver); - if (res < 0) { - pr_err(DRIVER_NAME ": driver registration failed\n"); - return res; - } - - return 0; -} - -static void __exit menelaus_exit(void) -{ - i2c_del_driver(&menelaus_i2c_driver); - - /* FIXME: Shutdown menelaus parts that can be shut down */ -} +module_i2c_driver(menelaus_i2c_driver); MODULE_AUTHOR("Texas Instruments, Inc. (and others)"); MODULE_DESCRIPTION("I2C interface for Menelaus."); MODULE_LICENSE("GPL"); - -module_init(menelaus_init); -module_exit(menelaus_exit); |
