diff options
author | Aurora zuma automerger <aurora-zuma-automerger@google.com> | 2023-03-16 06:57:53 +0000 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2023-03-20 20:47:52 -0700 |
commit | 2ad1089b18c3ff61ee3423c36347b0c3b95cdfa2 (patch) | |
tree | a465c2534bbf106ddeef6308de5a59d8c4a812b1 | |
parent | 1bece40209e7b86b40b77aa80665c484052e0ee0 (diff) | |
download | zuma-2ad1089b18c3ff61ee3423c36347b0c3b95cdfa2.tar.gz |
gxp: [Copybara Auto Merge] Merge branch 'zuma' into 'android14-gs-pixel-5.15'
gxp: Add GXP device in /sys/class
Bug: 271952597
gxp: Add functions gxp_common_platform_[init|exit]
Bug: 271952597 (repeat)
gxp: set a value to KCI mbox on HW wdg handling
Bug: 270655971
GitOrigin-RevId: 515179bb221ab807e3f5384fbad9eb3a74324dc8
Change-Id: Id7a3dd217af58bbda6801b8e76871b3f94cf5491
-rw-r--r-- | callisto-platform.c | 9 | ||||
-rw-r--r-- | callisto/mailbox-regs.h | 1 | ||||
-rw-r--r-- | gxp-common-platform.c | 99 | ||||
-rw-r--r-- | gxp-internal.h | 5 | ||||
-rw-r--r-- | gxp-mailbox-driver.c | 5 | ||||
-rw-r--r-- | gxp-mailbox-driver.h | 2 | ||||
-rw-r--r-- | gxp-mailbox.h | 3 | ||||
-rw-r--r-- | gxp-mcu-firmware.c | 6 |
8 files changed, 115 insertions, 15 deletions
diff --git a/callisto-platform.c b/callisto-platform.c index 8ccd526..838f066 100644 --- a/callisto-platform.c +++ b/callisto-platform.c @@ -118,14 +118,19 @@ static struct platform_driver gxp_platform_driver = { static int __init gxp_platform_init(void) { - gxp_common_platform_reg_sscd(); + int ret; + + ret = gxp_common_platform_init(); + if (ret) + return ret; + return platform_driver_register(&gxp_platform_driver); } static void __exit gxp_platform_exit(void) { platform_driver_unregister(&gxp_platform_driver); - gxp_common_platform_unreg_sscd(); + gxp_common_platform_exit(); } MODULE_DESCRIPTION("Google GXP platform driver"); diff --git a/callisto/mailbox-regs.h b/callisto/mailbox-regs.h index 6baefed..89880c3 100644 --- a/callisto/mailbox-regs.h +++ b/callisto/mailbox-regs.h @@ -26,5 +26,6 @@ #define MBOX_DATA_DESCRIPTOR_ADDR_OFFSET 0x04 #define MBOX_DATA_CMD_TAIL_RESP_HEAD_OFFSET 0x08 #define MBOX_DATA_CMD_HEAD_RESP_TAIL_OFFSET 0x0C +#define MBOX_DATA_CONTROL_OFFSET 0x30 #endif /* __CALLISTO_MAILBOX_REGS_H__ */ diff --git a/gxp-common-platform.c b/gxp-common-platform.c index 5767377..37c1654 100644 --- a/gxp-common-platform.c +++ b/gxp-common-platform.c @@ -10,11 +10,11 @@ #endif #include <linux/bitops.h> +#include <linux/cdev.h> #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/file.h> #include <linux/fs.h> -#include <linux/miscdevice.h> #include <linux/module.h> #include <linux/of_device.h> #include <linux/platform_device.h> @@ -59,7 +59,12 @@ #include "gxp-dci.h" #endif +/* We will only have one gxp device */ +#define GXP_DEV_COUNT 1 + static struct gxp_dev *gxp_debug_pointer; +static struct class *gxp_class; +static dev_t gxp_base_devno; /* Caller needs to hold client->semaphore for reading */ static bool check_client_has_available_vd_wakelock(struct gxp_client *client, @@ -142,8 +147,8 @@ static const uint aur_memory_state_array[MEMORY_POWER_STATE_MAX + 1] = { static int gxp_open(struct inode *inode, struct file *file) { struct gxp_client *client; - struct gxp_dev *gxp = container_of(file->private_data, struct gxp_dev, - misc_dev); + struct gxp_dev *gxp = + container_of(inode->i_cdev, struct gxp_dev, char_dev); int ret = 0; /* If this is the first call to open(), load the firmware files */ @@ -1912,6 +1917,71 @@ static void gxp_put_gsa_dev(struct gxp_dev *gxp) put_device(gxp->gsa_dev); } +static int gxp_device_add(struct gxp_dev *gxp) +{ + int ret; + struct device *dev; + + dev_dbg(gxp->dev, "adding interface: %s", GXP_NAME); + + gxp->char_dev_no = MKDEV(MAJOR(gxp_base_devno), 0); + cdev_init(&gxp->char_dev, &gxp_fops); + ret = cdev_add(&gxp->char_dev, gxp->char_dev_no, 1); + if (ret) { + dev_err(gxp->dev, "error %d adding cdev for dev %d:%d\n", ret, + MAJOR(gxp->char_dev_no), MINOR(gxp->char_dev_no)); + return ret; + } + + /* + * We only need char_dev_no for device_destroy, no need to record the + * returned dev. + */ + dev = device_create(gxp_class, gxp->dev, gxp->char_dev_no, gxp, "%s", + GXP_NAME); + if (IS_ERR(dev)) { + ret = PTR_ERR(dev); + dev_err(gxp->dev, "failed to create char device: %d\n", ret); + cdev_del(&gxp->char_dev); + return ret; + } + + return 0; +} + +static void gxp_device_remove(struct gxp_dev *gxp) +{ + device_destroy(gxp_class, gxp->char_dev_no); + cdev_del(&gxp->char_dev); +} + +static __init int gxp_fs_init(void) +{ + int ret; + + gxp_class = class_create(THIS_MODULE, GXP_NAME); + if (IS_ERR(gxp_class)) { + pr_err(GXP_NAME " error creating gxp class: %ld\n", + PTR_ERR(gxp_class)); + return PTR_ERR(gxp_class); + } + + ret = alloc_chrdev_region(&gxp_base_devno, 0, GXP_DEV_COUNT, GXP_NAME); + if (ret) { + pr_err(GXP_NAME " char device registration failed: %d\n", ret); + class_destroy(gxp_class); + return ret; + } + pr_debug(GXP_NAME " registered major=%d\n", MAJOR(gxp_base_devno)); + return 0; +} + +static __exit void gxp_fs_exit(void) +{ + unregister_chrdev_region(gxp_base_devno, GXP_DEV_COUNT); + class_destroy(gxp_class); +} + static int gxp_common_platform_probe(struct platform_device *pdev, struct gxp_dev *gxp) { struct device *dev = &pdev->dev; @@ -2054,14 +2124,9 @@ static int gxp_common_platform_probe(struct platform_device *pdev, struct gxp_de */ gxp_fw_data_populate_system_config(gxp); - gxp->misc_dev.minor = MISC_DYNAMIC_MINOR; - gxp->misc_dev.name = GXP_NAME; - gxp->misc_dev.fops = &gxp_fops; - ret = misc_register(&gxp->misc_dev); - if (ret) { - dev_err(dev, "Failed to register misc device: %d", ret); + ret = gxp_device_add(gxp); + if (ret) goto err_before_remove; - } gxp_create_debugfs(gxp); gxp_debug_pointer = gxp; @@ -2112,7 +2177,7 @@ static int gxp_common_platform_remove(struct platform_device *pdev) */ gxp_thermal_exit(gxp); gxp_remove_debugdir(gxp); - misc_deregister(&gxp->misc_dev); + gxp_device_remove(gxp); if (gxp->before_remove) gxp->before_remove(gxp); gxp_core_telemetry_exit(gxp); @@ -2133,6 +2198,18 @@ static int gxp_common_platform_remove(struct platform_device *pdev) return 0; } +static int __init gxp_common_platform_init(void) +{ + gxp_common_platform_reg_sscd(); + return gxp_fs_init(); +} + +static void __exit gxp_common_platform_exit(void) +{ + gxp_fs_exit(); + gxp_common_platform_unreg_sscd(); +} + #if IS_ENABLED(CONFIG_PM_SLEEP) static int gxp_platform_suspend(struct device *dev) diff --git a/gxp-internal.h b/gxp-internal.h index c1a5bf0..ba4cf7b 100644 --- a/gxp-internal.h +++ b/gxp-internal.h @@ -8,6 +8,7 @@ #define __GXP_INTERNAL_H__ #include <linux/atomic.h> +#include <linux/cdev.h> #include <linux/debugfs.h> #include <linux/delay.h> #include <linux/firmware.h> @@ -15,7 +16,6 @@ #include <linux/io.h> #include <linux/iommu.h> #include <linux/list.h> -#include <linux/miscdevice.h> #include <linux/mutex.h> #include <linux/of.h> #include <linux/of_address.h> @@ -74,7 +74,8 @@ struct gxp_power_states; struct gxp_dev { struct device *dev; /* platform bus device */ - struct miscdevice misc_dev; /* misc device structure */ + struct cdev char_dev; /* char device structure */ + dev_t char_dev_no; struct dentry *d_entry; /* debugfs dir for this device */ struct gxp_mapped_resource regs; /* ioremapped CSRs */ struct gxp_mapped_resource lpm_regs; /* ioremapped LPM CSRs, may be equal to @regs */ diff --git a/gxp-mailbox-driver.c b/gxp-mailbox-driver.c index 40fdba1..8d610c3 100644 --- a/gxp-mailbox-driver.c +++ b/gxp-mailbox-driver.c @@ -301,6 +301,11 @@ void gxp_mailbox_set_resp_queue_head(struct gxp_mailbox *mailbox, u32 value) gxp_mailbox_write_resp_queue_head(mailbox, value); } +void gxp_mailbox_set_control(struct gxp_mailbox *mailbox, u32 val) +{ + data_write(mailbox, MBOX_DATA_CONTROL_OFFSET, val); +} + int gxp_mailbox_inc_cmd_queue_tail_nolock(struct gxp_mailbox *mailbox, u32 inc, u32 wrap_bit) { diff --git a/gxp-mailbox-driver.h b/gxp-mailbox-driver.h index 30292d2..4eaf36b 100644 --- a/gxp-mailbox-driver.h +++ b/gxp-mailbox-driver.h @@ -75,6 +75,8 @@ void gxp_mailbox_set_cmd_queue_tail(struct gxp_mailbox *mailbox, u32 value); /* Sets mailbox->resp_queue_head and corresponding CSR on device. */ void gxp_mailbox_set_resp_queue_head(struct gxp_mailbox *mailbox, u32 value); +void gxp_mailbox_set_control(struct gxp_mailbox *mailbox, u32 val); + /* * Increases the command queue tail by @inc. * diff --git a/gxp-mailbox.h b/gxp-mailbox.h index cf72fbe..887578e 100644 --- a/gxp-mailbox.h +++ b/gxp-mailbox.h @@ -20,6 +20,9 @@ #include <gcip/gcip-mailbox.h> #endif +/* Pre-agreed values can be passed to gxp_mailbox_set_control(). */ +#define GXP_MBOX_CONTROL_MAGIC_POWER_DOWN (0xcafebabeu) + /* * Offset from the host mailbox interface to the device interface that needs to * be mapped. diff --git a/gxp-mcu-firmware.c b/gxp-mcu-firmware.c index bae6853..6c39e52 100644 --- a/gxp-mcu-firmware.c +++ b/gxp-mcu-firmware.c @@ -29,7 +29,9 @@ #include "gxp-internal.h" #include "gxp-kci.h" #include "gxp-lpm.h" +#include "gxp-mailbox-driver.h" #include "gxp-mcu-firmware.h" +#include "gxp-mcu-platform.h" #include "gxp-mcu.h" #include "gxp-pm.h" @@ -583,6 +585,10 @@ void gxp_mcu_firmware_crash_handler(struct gxp_dev *gxp, * fall into the WFI mode. We have to trigger the doorbell to let the MCU do that. */ if (crash_type == GCIP_FW_CRASH_HW_WDG_TIMEOUT) { + struct gxp_mcu *mcu = &to_mcu_dev(gxp)->mcu; + + gxp_mailbox_set_control(mcu->kci.mbx, + GXP_MBOX_CONTROL_MAGIC_POWER_DOWN); gxp_doorbell_enable_for_core( gxp, CORE_WAKEUP_DOORBELL(GXP_MCU_CORE_ID), GXP_MCU_CORE_ID); |