1*97fb5e8dSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 20b9641f5SGilad Avidov /* 30b9641f5SGilad Avidov * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. 45a86bf34SKenneth Heitke */ 55a86bf34SKenneth Heitke #include <linux/kernel.h> 65a86bf34SKenneth Heitke #include <linux/errno.h> 75a86bf34SKenneth Heitke #include <linux/idr.h> 85a86bf34SKenneth Heitke #include <linux/slab.h> 95a86bf34SKenneth Heitke #include <linux/module.h> 105a86bf34SKenneth Heitke #include <linux/of.h> 115a86bf34SKenneth Heitke #include <linux/of_device.h> 125a86bf34SKenneth Heitke #include <linux/platform_device.h> 135a86bf34SKenneth Heitke #include <linux/spmi.h> 145a86bf34SKenneth Heitke #include <linux/pm_runtime.h> 155a86bf34SKenneth Heitke 165a86bf34SKenneth Heitke #include <dt-bindings/spmi/spmi.h> 17a9fce374SAnkit Gupta #define CREATE_TRACE_POINTS 18a9fce374SAnkit Gupta #include <trace/events/spmi.h> 195a86bf34SKenneth Heitke 2047f55b74SSudip Mukherjee static bool is_registered; 215a86bf34SKenneth Heitke static DEFINE_IDA(ctrl_ida); 225a86bf34SKenneth Heitke 235a86bf34SKenneth Heitke static void spmi_dev_release(struct device *dev) 245a86bf34SKenneth Heitke { 255a86bf34SKenneth Heitke struct spmi_device *sdev = to_spmi_device(dev); 265a86bf34SKenneth Heitke kfree(sdev); 275a86bf34SKenneth Heitke } 285a86bf34SKenneth Heitke 295a86bf34SKenneth Heitke static const struct device_type spmi_dev_type = { 305a86bf34SKenneth Heitke .release = spmi_dev_release, 315a86bf34SKenneth Heitke }; 325a86bf34SKenneth Heitke 335a86bf34SKenneth Heitke static void spmi_ctrl_release(struct device *dev) 345a86bf34SKenneth Heitke { 355a86bf34SKenneth Heitke struct spmi_controller *ctrl = to_spmi_controller(dev); 365a86bf34SKenneth Heitke ida_simple_remove(&ctrl_ida, ctrl->nr); 375a86bf34SKenneth Heitke kfree(ctrl); 385a86bf34SKenneth Heitke } 395a86bf34SKenneth Heitke 405a86bf34SKenneth Heitke static const struct device_type spmi_ctrl_type = { 415a86bf34SKenneth Heitke .release = spmi_ctrl_release, 425a86bf34SKenneth Heitke }; 435a86bf34SKenneth Heitke 445a86bf34SKenneth Heitke static int spmi_device_match(struct device *dev, struct device_driver *drv) 455a86bf34SKenneth Heitke { 465a86bf34SKenneth Heitke if (of_driver_match_device(dev, drv)) 475a86bf34SKenneth Heitke return 1; 485a86bf34SKenneth Heitke 495a86bf34SKenneth Heitke if (drv->name) 505a86bf34SKenneth Heitke return strncmp(dev_name(dev), drv->name, 515a86bf34SKenneth Heitke SPMI_NAME_SIZE) == 0; 525a86bf34SKenneth Heitke 535a86bf34SKenneth Heitke return 0; 545a86bf34SKenneth Heitke } 555a86bf34SKenneth Heitke 565a86bf34SKenneth Heitke /** 575a86bf34SKenneth Heitke * spmi_device_add() - add a device previously constructed via spmi_device_alloc() 585a86bf34SKenneth Heitke * @sdev: spmi_device to be added 595a86bf34SKenneth Heitke */ 605a86bf34SKenneth Heitke int spmi_device_add(struct spmi_device *sdev) 615a86bf34SKenneth Heitke { 625a86bf34SKenneth Heitke struct spmi_controller *ctrl = sdev->ctrl; 635a86bf34SKenneth Heitke int err; 645a86bf34SKenneth Heitke 655a86bf34SKenneth Heitke dev_set_name(&sdev->dev, "%d-%02x", ctrl->nr, sdev->usid); 665a86bf34SKenneth Heitke 675a86bf34SKenneth Heitke err = device_add(&sdev->dev); 685a86bf34SKenneth Heitke if (err < 0) { 695a86bf34SKenneth Heitke dev_err(&sdev->dev, "Can't add %s, status %d\n", 705a86bf34SKenneth Heitke dev_name(&sdev->dev), err); 715a86bf34SKenneth Heitke goto err_device_add; 725a86bf34SKenneth Heitke } 735a86bf34SKenneth Heitke 745a86bf34SKenneth Heitke dev_dbg(&sdev->dev, "device %s registered\n", dev_name(&sdev->dev)); 755a86bf34SKenneth Heitke 765a86bf34SKenneth Heitke err_device_add: 775a86bf34SKenneth Heitke return err; 785a86bf34SKenneth Heitke } 795a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_device_add); 805a86bf34SKenneth Heitke 815a86bf34SKenneth Heitke /** 825a86bf34SKenneth Heitke * spmi_device_remove(): remove an SPMI device 835a86bf34SKenneth Heitke * @sdev: spmi_device to be removed 845a86bf34SKenneth Heitke */ 855a86bf34SKenneth Heitke void spmi_device_remove(struct spmi_device *sdev) 865a86bf34SKenneth Heitke { 875a86bf34SKenneth Heitke device_unregister(&sdev->dev); 885a86bf34SKenneth Heitke } 895a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_device_remove); 905a86bf34SKenneth Heitke 915a86bf34SKenneth Heitke static inline int 925a86bf34SKenneth Heitke spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid) 935a86bf34SKenneth Heitke { 94a9fce374SAnkit Gupta int ret; 95a9fce374SAnkit Gupta 965a86bf34SKenneth Heitke if (!ctrl || !ctrl->cmd || ctrl->dev.type != &spmi_ctrl_type) 975a86bf34SKenneth Heitke return -EINVAL; 985a86bf34SKenneth Heitke 99a9fce374SAnkit Gupta ret = ctrl->cmd(ctrl, opcode, sid); 100a9fce374SAnkit Gupta trace_spmi_cmd(opcode, sid, ret); 101a9fce374SAnkit Gupta return ret; 1025a86bf34SKenneth Heitke } 1035a86bf34SKenneth Heitke 1045a86bf34SKenneth Heitke static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode, 1055a86bf34SKenneth Heitke u8 sid, u16 addr, u8 *buf, size_t len) 1065a86bf34SKenneth Heitke { 107a9fce374SAnkit Gupta int ret; 108a9fce374SAnkit Gupta 1095a86bf34SKenneth Heitke if (!ctrl || !ctrl->read_cmd || ctrl->dev.type != &spmi_ctrl_type) 1105a86bf34SKenneth Heitke return -EINVAL; 1115a86bf34SKenneth Heitke 112a9fce374SAnkit Gupta trace_spmi_read_begin(opcode, sid, addr); 113a9fce374SAnkit Gupta ret = ctrl->read_cmd(ctrl, opcode, sid, addr, buf, len); 114a9fce374SAnkit Gupta trace_spmi_read_end(opcode, sid, addr, ret, len, buf); 115a9fce374SAnkit Gupta return ret; 1165a86bf34SKenneth Heitke } 1175a86bf34SKenneth Heitke 1185a86bf34SKenneth Heitke static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode, 1195a86bf34SKenneth Heitke u8 sid, u16 addr, const u8 *buf, size_t len) 1205a86bf34SKenneth Heitke { 121a9fce374SAnkit Gupta int ret; 122a9fce374SAnkit Gupta 1235a86bf34SKenneth Heitke if (!ctrl || !ctrl->write_cmd || ctrl->dev.type != &spmi_ctrl_type) 1245a86bf34SKenneth Heitke return -EINVAL; 1255a86bf34SKenneth Heitke 126a9fce374SAnkit Gupta trace_spmi_write_begin(opcode, sid, addr, len, buf); 127a9fce374SAnkit Gupta ret = ctrl->write_cmd(ctrl, opcode, sid, addr, buf, len); 128a9fce374SAnkit Gupta trace_spmi_write_end(opcode, sid, addr, ret); 129a9fce374SAnkit Gupta return ret; 1305a86bf34SKenneth Heitke } 1315a86bf34SKenneth Heitke 1325a86bf34SKenneth Heitke /** 1335a86bf34SKenneth Heitke * spmi_register_read() - register read 1345a86bf34SKenneth Heitke * @sdev: SPMI device. 1355a86bf34SKenneth Heitke * @addr: slave register address (5-bit address). 1365a86bf34SKenneth Heitke * @buf: buffer to be populated with data from the Slave. 1375a86bf34SKenneth Heitke * 1385a86bf34SKenneth Heitke * Reads 1 byte of data from a Slave device register. 1395a86bf34SKenneth Heitke */ 1405a86bf34SKenneth Heitke int spmi_register_read(struct spmi_device *sdev, u8 addr, u8 *buf) 1415a86bf34SKenneth Heitke { 1425a86bf34SKenneth Heitke /* 5-bit register address */ 1435a86bf34SKenneth Heitke if (addr > 0x1F) 1445a86bf34SKenneth Heitke return -EINVAL; 1455a86bf34SKenneth Heitke 1465a86bf34SKenneth Heitke return spmi_read_cmd(sdev->ctrl, SPMI_CMD_READ, sdev->usid, addr, 1475a86bf34SKenneth Heitke buf, 1); 1485a86bf34SKenneth Heitke } 1495a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_register_read); 1505a86bf34SKenneth Heitke 1515a86bf34SKenneth Heitke /** 1525a86bf34SKenneth Heitke * spmi_ext_register_read() - extended register read 1535a86bf34SKenneth Heitke * @sdev: SPMI device. 1545a86bf34SKenneth Heitke * @addr: slave register address (8-bit address). 1555a86bf34SKenneth Heitke * @buf: buffer to be populated with data from the Slave. 1565a86bf34SKenneth Heitke * @len: the request number of bytes to read (up to 16 bytes). 1575a86bf34SKenneth Heitke * 1585a86bf34SKenneth Heitke * Reads up to 16 bytes of data from the extended register space on a 1595a86bf34SKenneth Heitke * Slave device. 1605a86bf34SKenneth Heitke */ 1615a86bf34SKenneth Heitke int spmi_ext_register_read(struct spmi_device *sdev, u8 addr, u8 *buf, 1625a86bf34SKenneth Heitke size_t len) 1635a86bf34SKenneth Heitke { 1645a86bf34SKenneth Heitke /* 8-bit register address, up to 16 bytes */ 1655a86bf34SKenneth Heitke if (len == 0 || len > 16) 1665a86bf34SKenneth Heitke return -EINVAL; 1675a86bf34SKenneth Heitke 1685a86bf34SKenneth Heitke return spmi_read_cmd(sdev->ctrl, SPMI_CMD_EXT_READ, sdev->usid, addr, 1695a86bf34SKenneth Heitke buf, len); 1705a86bf34SKenneth Heitke } 1715a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_ext_register_read); 1725a86bf34SKenneth Heitke 1735a86bf34SKenneth Heitke /** 1745a86bf34SKenneth Heitke * spmi_ext_register_readl() - extended register read long 1755a86bf34SKenneth Heitke * @sdev: SPMI device. 1765a86bf34SKenneth Heitke * @addr: slave register address (16-bit address). 1775a86bf34SKenneth Heitke * @buf: buffer to be populated with data from the Slave. 1785a86bf34SKenneth Heitke * @len: the request number of bytes to read (up to 8 bytes). 1795a86bf34SKenneth Heitke * 1805a86bf34SKenneth Heitke * Reads up to 8 bytes of data from the extended register space on a 1815a86bf34SKenneth Heitke * Slave device using 16-bit address. 1825a86bf34SKenneth Heitke */ 1835a86bf34SKenneth Heitke int spmi_ext_register_readl(struct spmi_device *sdev, u16 addr, u8 *buf, 1845a86bf34SKenneth Heitke size_t len) 1855a86bf34SKenneth Heitke { 1865a86bf34SKenneth Heitke /* 16-bit register address, up to 8 bytes */ 1875a86bf34SKenneth Heitke if (len == 0 || len > 8) 1885a86bf34SKenneth Heitke return -EINVAL; 1895a86bf34SKenneth Heitke 1905a86bf34SKenneth Heitke return spmi_read_cmd(sdev->ctrl, SPMI_CMD_EXT_READL, sdev->usid, addr, 1915a86bf34SKenneth Heitke buf, len); 1925a86bf34SKenneth Heitke } 1935a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_ext_register_readl); 1945a86bf34SKenneth Heitke 1955a86bf34SKenneth Heitke /** 1965a86bf34SKenneth Heitke * spmi_register_write() - register write 1975a86bf34SKenneth Heitke * @sdev: SPMI device 1985a86bf34SKenneth Heitke * @addr: slave register address (5-bit address). 1995a86bf34SKenneth Heitke * @data: buffer containing the data to be transferred to the Slave. 2005a86bf34SKenneth Heitke * 2015a86bf34SKenneth Heitke * Writes 1 byte of data to a Slave device register. 2025a86bf34SKenneth Heitke */ 2035a86bf34SKenneth Heitke int spmi_register_write(struct spmi_device *sdev, u8 addr, u8 data) 2045a86bf34SKenneth Heitke { 2055a86bf34SKenneth Heitke /* 5-bit register address */ 2065a86bf34SKenneth Heitke if (addr > 0x1F) 2075a86bf34SKenneth Heitke return -EINVAL; 2085a86bf34SKenneth Heitke 2095a86bf34SKenneth Heitke return spmi_write_cmd(sdev->ctrl, SPMI_CMD_WRITE, sdev->usid, addr, 2105a86bf34SKenneth Heitke &data, 1); 2115a86bf34SKenneth Heitke } 2125a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_register_write); 2135a86bf34SKenneth Heitke 2145a86bf34SKenneth Heitke /** 2155a86bf34SKenneth Heitke * spmi_register_zero_write() - register zero write 2165a86bf34SKenneth Heitke * @sdev: SPMI device. 2175a86bf34SKenneth Heitke * @data: the data to be written to register 0 (7-bits). 2185a86bf34SKenneth Heitke * 2195a86bf34SKenneth Heitke * Writes data to register 0 of the Slave device. 2205a86bf34SKenneth Heitke */ 2215a86bf34SKenneth Heitke int spmi_register_zero_write(struct spmi_device *sdev, u8 data) 2225a86bf34SKenneth Heitke { 2235a86bf34SKenneth Heitke return spmi_write_cmd(sdev->ctrl, SPMI_CMD_ZERO_WRITE, sdev->usid, 0, 2245a86bf34SKenneth Heitke &data, 1); 2255a86bf34SKenneth Heitke } 2265a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_register_zero_write); 2275a86bf34SKenneth Heitke 2285a86bf34SKenneth Heitke /** 2295a86bf34SKenneth Heitke * spmi_ext_register_write() - extended register write 2305a86bf34SKenneth Heitke * @sdev: SPMI device. 2315a86bf34SKenneth Heitke * @addr: slave register address (8-bit address). 2325a86bf34SKenneth Heitke * @buf: buffer containing the data to be transferred to the Slave. 2335a86bf34SKenneth Heitke * @len: the request number of bytes to read (up to 16 bytes). 2345a86bf34SKenneth Heitke * 2355a86bf34SKenneth Heitke * Writes up to 16 bytes of data to the extended register space of a 2365a86bf34SKenneth Heitke * Slave device. 2375a86bf34SKenneth Heitke */ 2385a86bf34SKenneth Heitke int spmi_ext_register_write(struct spmi_device *sdev, u8 addr, const u8 *buf, 2395a86bf34SKenneth Heitke size_t len) 2405a86bf34SKenneth Heitke { 2415a86bf34SKenneth Heitke /* 8-bit register address, up to 16 bytes */ 2425a86bf34SKenneth Heitke if (len == 0 || len > 16) 2435a86bf34SKenneth Heitke return -EINVAL; 2445a86bf34SKenneth Heitke 2455a86bf34SKenneth Heitke return spmi_write_cmd(sdev->ctrl, SPMI_CMD_EXT_WRITE, sdev->usid, addr, 2465a86bf34SKenneth Heitke buf, len); 2475a86bf34SKenneth Heitke } 2485a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_ext_register_write); 2495a86bf34SKenneth Heitke 2505a86bf34SKenneth Heitke /** 2515a86bf34SKenneth Heitke * spmi_ext_register_writel() - extended register write long 2525a86bf34SKenneth Heitke * @sdev: SPMI device. 2535a86bf34SKenneth Heitke * @addr: slave register address (16-bit address). 2545a86bf34SKenneth Heitke * @buf: buffer containing the data to be transferred to the Slave. 2555a86bf34SKenneth Heitke * @len: the request number of bytes to read (up to 8 bytes). 2565a86bf34SKenneth Heitke * 2575a86bf34SKenneth Heitke * Writes up to 8 bytes of data to the extended register space of a 2585a86bf34SKenneth Heitke * Slave device using 16-bit address. 2595a86bf34SKenneth Heitke */ 2605a86bf34SKenneth Heitke int spmi_ext_register_writel(struct spmi_device *sdev, u16 addr, const u8 *buf, 2615a86bf34SKenneth Heitke size_t len) 2625a86bf34SKenneth Heitke { 2635a86bf34SKenneth Heitke /* 4-bit Slave Identifier, 16-bit register address, up to 8 bytes */ 2645a86bf34SKenneth Heitke if (len == 0 || len > 8) 2655a86bf34SKenneth Heitke return -EINVAL; 2665a86bf34SKenneth Heitke 2675a86bf34SKenneth Heitke return spmi_write_cmd(sdev->ctrl, SPMI_CMD_EXT_WRITEL, sdev->usid, 2685a86bf34SKenneth Heitke addr, buf, len); 2695a86bf34SKenneth Heitke } 2705a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_ext_register_writel); 2715a86bf34SKenneth Heitke 2725a86bf34SKenneth Heitke /** 2735a86bf34SKenneth Heitke * spmi_command_reset() - sends RESET command to the specified slave 2745a86bf34SKenneth Heitke * @sdev: SPMI device. 2755a86bf34SKenneth Heitke * 2765a86bf34SKenneth Heitke * The Reset command initializes the Slave and forces all registers to 2775a86bf34SKenneth Heitke * their reset values. The Slave shall enter the STARTUP state after 2785a86bf34SKenneth Heitke * receiving a Reset command. 2795a86bf34SKenneth Heitke */ 2805a86bf34SKenneth Heitke int spmi_command_reset(struct spmi_device *sdev) 2815a86bf34SKenneth Heitke { 2825a86bf34SKenneth Heitke return spmi_cmd(sdev->ctrl, SPMI_CMD_RESET, sdev->usid); 2835a86bf34SKenneth Heitke } 2845a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_command_reset); 2855a86bf34SKenneth Heitke 2865a86bf34SKenneth Heitke /** 2875a86bf34SKenneth Heitke * spmi_command_sleep() - sends SLEEP command to the specified SPMI device 2885a86bf34SKenneth Heitke * @sdev: SPMI device. 2895a86bf34SKenneth Heitke * 2905a86bf34SKenneth Heitke * The Sleep command causes the Slave to enter the user defined SLEEP state. 2915a86bf34SKenneth Heitke */ 2925a86bf34SKenneth Heitke int spmi_command_sleep(struct spmi_device *sdev) 2935a86bf34SKenneth Heitke { 2945a86bf34SKenneth Heitke return spmi_cmd(sdev->ctrl, SPMI_CMD_SLEEP, sdev->usid); 2955a86bf34SKenneth Heitke } 2965a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_command_sleep); 2975a86bf34SKenneth Heitke 2985a86bf34SKenneth Heitke /** 2995a86bf34SKenneth Heitke * spmi_command_wakeup() - sends WAKEUP command to the specified SPMI device 3005a86bf34SKenneth Heitke * @sdev: SPMI device. 3015a86bf34SKenneth Heitke * 3025a86bf34SKenneth Heitke * The Wakeup command causes the Slave to move from the SLEEP state to 3035a86bf34SKenneth Heitke * the ACTIVE state. 3045a86bf34SKenneth Heitke */ 3055a86bf34SKenneth Heitke int spmi_command_wakeup(struct spmi_device *sdev) 3065a86bf34SKenneth Heitke { 3075a86bf34SKenneth Heitke return spmi_cmd(sdev->ctrl, SPMI_CMD_WAKEUP, sdev->usid); 3085a86bf34SKenneth Heitke } 3095a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_command_wakeup); 3105a86bf34SKenneth Heitke 3115a86bf34SKenneth Heitke /** 3125a86bf34SKenneth Heitke * spmi_command_shutdown() - sends SHUTDOWN command to the specified SPMI device 3135a86bf34SKenneth Heitke * @sdev: SPMI device. 3145a86bf34SKenneth Heitke * 3155a86bf34SKenneth Heitke * The Shutdown command causes the Slave to enter the SHUTDOWN state. 3165a86bf34SKenneth Heitke */ 3175a86bf34SKenneth Heitke int spmi_command_shutdown(struct spmi_device *sdev) 3185a86bf34SKenneth Heitke { 3195a86bf34SKenneth Heitke return spmi_cmd(sdev->ctrl, SPMI_CMD_SHUTDOWN, sdev->usid); 3205a86bf34SKenneth Heitke } 3215a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_command_shutdown); 3225a86bf34SKenneth Heitke 3235a86bf34SKenneth Heitke static int spmi_drv_probe(struct device *dev) 3245a86bf34SKenneth Heitke { 3255a86bf34SKenneth Heitke const struct spmi_driver *sdrv = to_spmi_driver(dev->driver); 3265a86bf34SKenneth Heitke struct spmi_device *sdev = to_spmi_device(dev); 3275a86bf34SKenneth Heitke int err; 3285a86bf34SKenneth Heitke 3295a86bf34SKenneth Heitke pm_runtime_get_noresume(dev); 3305a86bf34SKenneth Heitke pm_runtime_set_active(dev); 3315a86bf34SKenneth Heitke pm_runtime_enable(dev); 3325a86bf34SKenneth Heitke 3335a86bf34SKenneth Heitke err = sdrv->probe(sdev); 3345a86bf34SKenneth Heitke if (err) 3355a86bf34SKenneth Heitke goto fail_probe; 3365a86bf34SKenneth Heitke 3375a86bf34SKenneth Heitke return 0; 3385a86bf34SKenneth Heitke 3395a86bf34SKenneth Heitke fail_probe: 3405a86bf34SKenneth Heitke pm_runtime_disable(dev); 3415a86bf34SKenneth Heitke pm_runtime_set_suspended(dev); 3425a86bf34SKenneth Heitke pm_runtime_put_noidle(dev); 3435a86bf34SKenneth Heitke return err; 3445a86bf34SKenneth Heitke } 3455a86bf34SKenneth Heitke 3465a86bf34SKenneth Heitke static int spmi_drv_remove(struct device *dev) 3475a86bf34SKenneth Heitke { 3485a86bf34SKenneth Heitke const struct spmi_driver *sdrv = to_spmi_driver(dev->driver); 3495a86bf34SKenneth Heitke 3505a86bf34SKenneth Heitke pm_runtime_get_sync(dev); 3515a86bf34SKenneth Heitke sdrv->remove(to_spmi_device(dev)); 3525a86bf34SKenneth Heitke pm_runtime_put_noidle(dev); 3535a86bf34SKenneth Heitke 3545a86bf34SKenneth Heitke pm_runtime_disable(dev); 3555a86bf34SKenneth Heitke pm_runtime_set_suspended(dev); 3565a86bf34SKenneth Heitke pm_runtime_put_noidle(dev); 3575a86bf34SKenneth Heitke return 0; 3585a86bf34SKenneth Heitke } 3595a86bf34SKenneth Heitke 360d50daa2aSBjorn Andersson static int spmi_drv_uevent(struct device *dev, struct kobj_uevent_env *env) 361d50daa2aSBjorn Andersson { 362d50daa2aSBjorn Andersson int ret; 363d50daa2aSBjorn Andersson 364d50daa2aSBjorn Andersson ret = of_device_uevent_modalias(dev, env); 365d50daa2aSBjorn Andersson if (ret != -ENODEV) 366d50daa2aSBjorn Andersson return ret; 367d50daa2aSBjorn Andersson 368d50daa2aSBjorn Andersson return 0; 369d50daa2aSBjorn Andersson } 370d50daa2aSBjorn Andersson 3715a86bf34SKenneth Heitke static struct bus_type spmi_bus_type = { 3725a86bf34SKenneth Heitke .name = "spmi", 3735a86bf34SKenneth Heitke .match = spmi_device_match, 3745a86bf34SKenneth Heitke .probe = spmi_drv_probe, 3755a86bf34SKenneth Heitke .remove = spmi_drv_remove, 376d50daa2aSBjorn Andersson .uevent = spmi_drv_uevent, 3775a86bf34SKenneth Heitke }; 3785a86bf34SKenneth Heitke 3795a86bf34SKenneth Heitke /** 3805a86bf34SKenneth Heitke * spmi_controller_alloc() - Allocate a new SPMI device 3815a86bf34SKenneth Heitke * @ctrl: associated controller 3825a86bf34SKenneth Heitke * 3835a86bf34SKenneth Heitke * Caller is responsible for either calling spmi_device_add() to add the 3845a86bf34SKenneth Heitke * newly allocated controller, or calling spmi_device_put() to discard it. 3855a86bf34SKenneth Heitke */ 3865a86bf34SKenneth Heitke struct spmi_device *spmi_device_alloc(struct spmi_controller *ctrl) 3875a86bf34SKenneth Heitke { 3885a86bf34SKenneth Heitke struct spmi_device *sdev; 3895a86bf34SKenneth Heitke 3905a86bf34SKenneth Heitke sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); 3915a86bf34SKenneth Heitke if (!sdev) 3925a86bf34SKenneth Heitke return NULL; 3935a86bf34SKenneth Heitke 3945a86bf34SKenneth Heitke sdev->ctrl = ctrl; 3955a86bf34SKenneth Heitke device_initialize(&sdev->dev); 3965a86bf34SKenneth Heitke sdev->dev.parent = &ctrl->dev; 3975a86bf34SKenneth Heitke sdev->dev.bus = &spmi_bus_type; 3985a86bf34SKenneth Heitke sdev->dev.type = &spmi_dev_type; 3995a86bf34SKenneth Heitke return sdev; 4005a86bf34SKenneth Heitke } 4015a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_device_alloc); 4025a86bf34SKenneth Heitke 4035a86bf34SKenneth Heitke /** 4045a86bf34SKenneth Heitke * spmi_controller_alloc() - Allocate a new SPMI controller 4055a86bf34SKenneth Heitke * @parent: parent device 4065a86bf34SKenneth Heitke * @size: size of private data 4075a86bf34SKenneth Heitke * 4085a86bf34SKenneth Heitke * Caller is responsible for either calling spmi_controller_add() to add the 4095a86bf34SKenneth Heitke * newly allocated controller, or calling spmi_controller_put() to discard it. 4105a86bf34SKenneth Heitke * The allocated private data region may be accessed via 4115a86bf34SKenneth Heitke * spmi_controller_get_drvdata() 4125a86bf34SKenneth Heitke */ 4135a86bf34SKenneth Heitke struct spmi_controller *spmi_controller_alloc(struct device *parent, 4145a86bf34SKenneth Heitke size_t size) 4155a86bf34SKenneth Heitke { 4165a86bf34SKenneth Heitke struct spmi_controller *ctrl; 4175a86bf34SKenneth Heitke int id; 4185a86bf34SKenneth Heitke 4195a86bf34SKenneth Heitke if (WARN_ON(!parent)) 4205a86bf34SKenneth Heitke return NULL; 4215a86bf34SKenneth Heitke 4225a86bf34SKenneth Heitke ctrl = kzalloc(sizeof(*ctrl) + size, GFP_KERNEL); 4235a86bf34SKenneth Heitke if (!ctrl) 4245a86bf34SKenneth Heitke return NULL; 4255a86bf34SKenneth Heitke 4265a86bf34SKenneth Heitke device_initialize(&ctrl->dev); 4275a86bf34SKenneth Heitke ctrl->dev.type = &spmi_ctrl_type; 4285a86bf34SKenneth Heitke ctrl->dev.bus = &spmi_bus_type; 4295a86bf34SKenneth Heitke ctrl->dev.parent = parent; 4305a86bf34SKenneth Heitke ctrl->dev.of_node = parent->of_node; 4315a86bf34SKenneth Heitke spmi_controller_set_drvdata(ctrl, &ctrl[1]); 4325a86bf34SKenneth Heitke 4335a86bf34SKenneth Heitke id = ida_simple_get(&ctrl_ida, 0, 0, GFP_KERNEL); 4345a86bf34SKenneth Heitke if (id < 0) { 4355a86bf34SKenneth Heitke dev_err(parent, 4365a86bf34SKenneth Heitke "unable to allocate SPMI controller identifier.\n"); 4375a86bf34SKenneth Heitke spmi_controller_put(ctrl); 4385a86bf34SKenneth Heitke return NULL; 4395a86bf34SKenneth Heitke } 4405a86bf34SKenneth Heitke 4415a86bf34SKenneth Heitke ctrl->nr = id; 4425a86bf34SKenneth Heitke dev_set_name(&ctrl->dev, "spmi-%d", id); 4435a86bf34SKenneth Heitke 4445a86bf34SKenneth Heitke dev_dbg(&ctrl->dev, "allocated controller 0x%p id %d\n", ctrl, id); 4455a86bf34SKenneth Heitke return ctrl; 4465a86bf34SKenneth Heitke } 4475a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_controller_alloc); 4485a86bf34SKenneth Heitke 4495a86bf34SKenneth Heitke static void of_spmi_register_devices(struct spmi_controller *ctrl) 4505a86bf34SKenneth Heitke { 4515a86bf34SKenneth Heitke struct device_node *node; 4525a86bf34SKenneth Heitke int err; 4535a86bf34SKenneth Heitke 4545a86bf34SKenneth Heitke if (!ctrl->dev.of_node) 4555a86bf34SKenneth Heitke return; 4565a86bf34SKenneth Heitke 4575a86bf34SKenneth Heitke for_each_available_child_of_node(ctrl->dev.of_node, node) { 4585a86bf34SKenneth Heitke struct spmi_device *sdev; 4595a86bf34SKenneth Heitke u32 reg[2]; 4605a86bf34SKenneth Heitke 461e55fe64aSRob Herring dev_dbg(&ctrl->dev, "adding child %pOF\n", node); 4625a86bf34SKenneth Heitke 4635a86bf34SKenneth Heitke err = of_property_read_u32_array(node, "reg", reg, 2); 4645a86bf34SKenneth Heitke if (err) { 4655a86bf34SKenneth Heitke dev_err(&ctrl->dev, 466e55fe64aSRob Herring "node %pOF err (%d) does not have 'reg' property\n", 467e55fe64aSRob Herring node, err); 4685a86bf34SKenneth Heitke continue; 4695a86bf34SKenneth Heitke } 4705a86bf34SKenneth Heitke 4715a86bf34SKenneth Heitke if (reg[1] != SPMI_USID) { 4725a86bf34SKenneth Heitke dev_err(&ctrl->dev, 473e55fe64aSRob Herring "node %pOF contains unsupported 'reg' entry\n", 474e55fe64aSRob Herring node); 4755a86bf34SKenneth Heitke continue; 4765a86bf34SKenneth Heitke } 4775a86bf34SKenneth Heitke 4785a86bf34SKenneth Heitke if (reg[0] >= SPMI_MAX_SLAVE_ID) { 479e55fe64aSRob Herring dev_err(&ctrl->dev, "invalid usid on node %pOF\n", node); 4805a86bf34SKenneth Heitke continue; 4815a86bf34SKenneth Heitke } 4825a86bf34SKenneth Heitke 4835a86bf34SKenneth Heitke dev_dbg(&ctrl->dev, "read usid %02x\n", reg[0]); 4845a86bf34SKenneth Heitke 4855a86bf34SKenneth Heitke sdev = spmi_device_alloc(ctrl); 4865a86bf34SKenneth Heitke if (!sdev) 4875a86bf34SKenneth Heitke continue; 4885a86bf34SKenneth Heitke 4895a86bf34SKenneth Heitke sdev->dev.of_node = node; 4905a86bf34SKenneth Heitke sdev->usid = (u8) reg[0]; 4915a86bf34SKenneth Heitke 4925a86bf34SKenneth Heitke err = spmi_device_add(sdev); 4935a86bf34SKenneth Heitke if (err) { 4945a86bf34SKenneth Heitke dev_err(&sdev->dev, 4955a86bf34SKenneth Heitke "failure adding device. status %d\n", err); 4965a86bf34SKenneth Heitke spmi_device_put(sdev); 4975a86bf34SKenneth Heitke } 4985a86bf34SKenneth Heitke } 4995a86bf34SKenneth Heitke } 5005a86bf34SKenneth Heitke 5015a86bf34SKenneth Heitke /** 5025a86bf34SKenneth Heitke * spmi_controller_add() - Add an SPMI controller 5035a86bf34SKenneth Heitke * @ctrl: controller to be registered. 5045a86bf34SKenneth Heitke * 5055a86bf34SKenneth Heitke * Register a controller previously allocated via spmi_controller_alloc() with 5065a86bf34SKenneth Heitke * the SPMI core. 5075a86bf34SKenneth Heitke */ 5085a86bf34SKenneth Heitke int spmi_controller_add(struct spmi_controller *ctrl) 5095a86bf34SKenneth Heitke { 5105a86bf34SKenneth Heitke int ret; 5115a86bf34SKenneth Heitke 5125a86bf34SKenneth Heitke /* Can't register until after driver model init */ 51347f55b74SSudip Mukherjee if (WARN_ON(!is_registered)) 5145a86bf34SKenneth Heitke return -EAGAIN; 5155a86bf34SKenneth Heitke 5165a86bf34SKenneth Heitke ret = device_add(&ctrl->dev); 5175a86bf34SKenneth Heitke if (ret) 5185a86bf34SKenneth Heitke return ret; 5195a86bf34SKenneth Heitke 5205a86bf34SKenneth Heitke if (IS_ENABLED(CONFIG_OF)) 5215a86bf34SKenneth Heitke of_spmi_register_devices(ctrl); 5225a86bf34SKenneth Heitke 5235a86bf34SKenneth Heitke dev_dbg(&ctrl->dev, "spmi-%d registered: dev:%p\n", 5245a86bf34SKenneth Heitke ctrl->nr, &ctrl->dev); 5255a86bf34SKenneth Heitke 5265a86bf34SKenneth Heitke return 0; 5275a86bf34SKenneth Heitke }; 5285a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_controller_add); 5295a86bf34SKenneth Heitke 5305a86bf34SKenneth Heitke /* Remove a device associated with a controller */ 5315a86bf34SKenneth Heitke static int spmi_ctrl_remove_device(struct device *dev, void *data) 5325a86bf34SKenneth Heitke { 5335a86bf34SKenneth Heitke struct spmi_device *spmidev = to_spmi_device(dev); 5345a86bf34SKenneth Heitke if (dev->type == &spmi_dev_type) 5355a86bf34SKenneth Heitke spmi_device_remove(spmidev); 5365a86bf34SKenneth Heitke return 0; 5375a86bf34SKenneth Heitke } 5385a86bf34SKenneth Heitke 5395a86bf34SKenneth Heitke /** 5405a86bf34SKenneth Heitke * spmi_controller_remove(): remove an SPMI controller 5415a86bf34SKenneth Heitke * @ctrl: controller to remove 5425a86bf34SKenneth Heitke * 5435a86bf34SKenneth Heitke * Remove a SPMI controller. Caller is responsible for calling 5445a86bf34SKenneth Heitke * spmi_controller_put() to discard the allocated controller. 5455a86bf34SKenneth Heitke */ 5465a86bf34SKenneth Heitke void spmi_controller_remove(struct spmi_controller *ctrl) 5475a86bf34SKenneth Heitke { 5485a86bf34SKenneth Heitke int dummy; 5495a86bf34SKenneth Heitke 5505a86bf34SKenneth Heitke if (!ctrl) 5515a86bf34SKenneth Heitke return; 5525a86bf34SKenneth Heitke 5535a86bf34SKenneth Heitke dummy = device_for_each_child(&ctrl->dev, NULL, 5545a86bf34SKenneth Heitke spmi_ctrl_remove_device); 5555a86bf34SKenneth Heitke device_del(&ctrl->dev); 5565a86bf34SKenneth Heitke } 5575a86bf34SKenneth Heitke EXPORT_SYMBOL_GPL(spmi_controller_remove); 5585a86bf34SKenneth Heitke 5595a86bf34SKenneth Heitke /** 5605a86bf34SKenneth Heitke * spmi_driver_register() - Register client driver with SPMI core 5615a86bf34SKenneth Heitke * @sdrv: client driver to be associated with client-device. 5625a86bf34SKenneth Heitke * 5635a86bf34SKenneth Heitke * This API will register the client driver with the SPMI framework. 5645a86bf34SKenneth Heitke * It is typically called from the driver's module-init function. 5655a86bf34SKenneth Heitke */ 566ff6f4648SStephen Boyd int __spmi_driver_register(struct spmi_driver *sdrv, struct module *owner) 5675a86bf34SKenneth Heitke { 5685a86bf34SKenneth Heitke sdrv->driver.bus = &spmi_bus_type; 569ff6f4648SStephen Boyd sdrv->driver.owner = owner; 5705a86bf34SKenneth Heitke return driver_register(&sdrv->driver); 5715a86bf34SKenneth Heitke } 572ff6f4648SStephen Boyd EXPORT_SYMBOL_GPL(__spmi_driver_register); 5735a86bf34SKenneth Heitke 5745a86bf34SKenneth Heitke static void __exit spmi_exit(void) 5755a86bf34SKenneth Heitke { 5765a86bf34SKenneth Heitke bus_unregister(&spmi_bus_type); 5775a86bf34SKenneth Heitke } 5785a86bf34SKenneth Heitke module_exit(spmi_exit); 5795a86bf34SKenneth Heitke 5805a86bf34SKenneth Heitke static int __init spmi_init(void) 5815a86bf34SKenneth Heitke { 58247f55b74SSudip Mukherjee int ret; 58347f55b74SSudip Mukherjee 58447f55b74SSudip Mukherjee ret = bus_register(&spmi_bus_type); 58547f55b74SSudip Mukherjee if (ret) 58647f55b74SSudip Mukherjee return ret; 58747f55b74SSudip Mukherjee 58847f55b74SSudip Mukherjee is_registered = true; 58947f55b74SSudip Mukherjee return 0; 5905a86bf34SKenneth Heitke } 5915a86bf34SKenneth Heitke postcore_initcall(spmi_init); 5925a86bf34SKenneth Heitke 5935a86bf34SKenneth Heitke MODULE_LICENSE("GPL v2"); 5945a86bf34SKenneth Heitke MODULE_DESCRIPTION("SPMI module"); 5955a86bf34SKenneth Heitke MODULE_ALIAS("platform:spmi"); 596