linux-imx/drivers/mfd/fp9931-core.c
Zhipeng Wang 2f455bcc12 MA-21077 mfd: Remove __init from fp9931_exit
The function fp9931_exit is defined with the __init annotation, which
means that it can only be called during the initialization phase of
the module. However, this function is registered as the
module exit function using the module_exit macro.

To fix this issue, remove the __init annotation from the
fp9931_exit function.

Change-Id: I7bc17298577c44a9a67445be4a479234f7298a36
Signed-off-by: Zhipeng Wang <zhipeng.wang_1@nxp.com>
2023-10-30 16:09:25 +08:00

161 lines
3.2 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Fitipower FP9931 PMIC core driver
*
* Copyright 2021 NXP
*/
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/mfd/core.h>
#include <linux/mfd/fp9931.h>
#include <linux/module.h>
static const unsigned short normal_i2c[] = {
0x18, I2C_CLIENT_END
};
static struct mfd_cell fp9931_devs[] = {
{ .name = "fp9931-pmic", },
{ .name = "fp9931-hwmon", },
};
int fp9931_reg_read(struct i2c_client *client, int reg, u8 *val)
{
int ret;
ret = i2c_smbus_read_byte_data(client, reg);
if (ret < 0) {
dev_err(&client->dev, "Unable to read reg %d : %d\n",
reg, ret);
return ret;
}
*val = ret;
return 0;
}
EXPORT_SYMBOL(fp9931_reg_read);
int fp9931_reg_write(struct i2c_client *client, int reg, u8 val)
{
int ret;
ret = i2c_smbus_write_byte_data(client, reg, val);
if (ret < 0)
dev_err(&client->dev, "Unable to write to reg %d with %u : %d\n",
reg, val, ret);
return ret;
}
EXPORT_SYMBOL(fp9931_reg_write);
static int fp9931_detect(struct i2c_client *client,
struct i2c_board_info *info)
{
int ret;
u8 tmst_value;
s8 temperature;
struct i2c_adapter *adapter = client->adapter;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
ret = fp9931_reg_read(client, FP9931_TMST_VALUE, &tmst_value);
if (ret)
return ret;
temperature = tmst_value;
dev_info(&client->dev,
"detect temperature is : %d Celsius Degree\n",
temperature);
return 0;
}
static int fp9931_probe(struct i2c_client *client)
{
int ret;
struct fp9931 *fp9931;
struct device *dev = &client->dev;
fp9931 = devm_kzalloc(dev, sizeof(*fp9931), GFP_KERNEL);
if (!fp9931)
return -ENOMEM;
fp9931->dev = dev;
fp9931->client = client;
i2c_set_clientdata(client, fp9931);
/* call detect here, since the .detect function of
* i2c_driver won't be called if the driver's class
* and adapter's class do not match.
*/
ret = fp9931_detect(client, NULL);
if (ret)
return ret;
fp9931->pdata = devm_kzalloc(dev, sizeof(*fp9931->pdata), GFP_KERNEL);
if (!fp9931->pdata)
return -ENOMEM;
ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, fp9931_devs,
ARRAY_SIZE(fp9931_devs), NULL, 0, NULL);
if (ret) {
dev_err(dev, "Failed to add pmic subdevices: %d\n", ret);
return ret;
}
return 0;
}
static void fp9931_remove(struct i2c_client *i2c)
{
/* nothing needs to be done */
}
static const struct i2c_device_id fp9931_id[] = {
{ "fp9931", 0 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, fp9931_id);
static const struct of_device_id fp9931_dt_ids[] = {
{
.compatible = "fitipower,fp9931",
},
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, fp9931_dt_ids);
static struct i2c_driver fp9931_driver = {
.driver = {
.name = "fp9931",
.owner = THIS_MODULE,
.of_match_table = fp9931_dt_ids,
},
.probe = fp9931_probe,
.remove = fp9931_remove,
.id_table = fp9931_id,
.detect = fp9931_detect,
.address_list = normal_i2c,
};
static int __init fp9931_init(void)
{
return i2c_add_driver(&fp9931_driver);
}
static void fp9931_exit(void)
{
i2c_del_driver(&fp9931_driver);
}
subsys_initcall(fp9931_init);
module_exit(fp9931_exit);
MODULE_DESCRIPTION("PF9931 PMIC core driver");
MODULE_AUTHOR("Fancy Fang <chen.fang@nxp.com>");
MODULE_LICENSE("GPL");