diff options
author | Todd Poynor <toddpoynor@google.com> | 2021-07-09 19:51:43 +0000 |
---|---|---|
committer | Erick Reyes <erickreyes@google.com> | 2021-07-27 22:51:45 +0000 |
commit | 35c35f589ab443d9bc5b468f127cd6a0113b8104 (patch) | |
tree | 3db3048a8e02cdd315fd034e598723d61fb24331 | |
parent | 8fd890bd673196a1c7e14bf9d046711e353b9467 (diff) | |
download | edgetpu-35c35f589ab443d9bc5b468f127cd6a0113b8104.tar.gz |
edgetpu: sync critical fixes from darwinn-internal
Roll up the following fixes from darwinn-internal/darwinn-2.0 branch:
4bea3ab59 edgetpu: add support for multiple interfaces
Bug: 191193044
a3845eb1f edgetpu: restrict debugfs statusregs file to non-mobile chipsets
0cf49546e edgetpu: add "is a mobile style device" feature flag
Bug: 194228073
0afc743e5 edgetpu: abrolhos: expose thermal suspend/resume
[toddpoynor@google.com: fixup merge conflict on pwr_state enum]
Bug: 193247519
34bd4e2d2 edgetpu: abrolhos: Send throttling notification KCI only if TPU is on.
Bug: 193254607
Signed-off-by: Erick Reyes <erickreyes@google.com>
Signed-off-by: abhilashkul <abhilashkul@google.com>
Signed-off-by: David Chiang <davidchiang@google.com>
Signed-off-by: Todd Poynor <toddpoynor@google.com>
Change-Id: I5eb392271b07f28bba66701639e453f2674cfad2
-rw-r--r-- | drivers/edgetpu/abrolhos-device.c | 34 | ||||
-rw-r--r-- | drivers/edgetpu/abrolhos-platform.c | 10 | ||||
-rw-r--r-- | drivers/edgetpu/abrolhos-thermal.c | 76 | ||||
-rw-r--r-- | drivers/edgetpu/abrolhos/config.h | 2 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-core.c | 24 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-fs.c | 84 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-internal.h | 45 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-kci.c | 3 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-shared-fw.c | 2 | ||||
-rw-r--r-- | drivers/edgetpu/edgetpu-thermal.h | 13 |
10 files changed, 206 insertions, 87 deletions
diff --git a/drivers/edgetpu/abrolhos-device.c b/drivers/edgetpu/abrolhos-device.c index e38c508..25f942f 100644 --- a/drivers/edgetpu/abrolhos-device.c +++ b/drivers/edgetpu/abrolhos-device.c @@ -109,40 +109,6 @@ void edgetpu_mark_probe_fail(struct edgetpu_dev *etdev) { } -struct edgetpu_dumpregs_range edgetpu_chip_statusregs_ranges[] = { - { - .firstreg = EDGETPU_REG_USER_HIB_FIRST_ERROR_STATUS, - .lastreg = EDGETPU_REG_USER_HIB_FIRST_ERROR_STATUS, - }, - { - .firstreg = EDGETPU_REG_SC_RUNSTATUS, - .lastreg = EDGETPU_REG_SC_RUNSTATUS, - }, - { - .firstreg = EDGETPU_REG_USER_HIB_OUT_ACTVQ_INT_STAT, - .lastreg = EDGETPU_REG_USER_HIB_OUT_ACTVQ_INT_STAT, - }, - { - .firstreg = EDGETPU_REG_USER_HIB_IN_ACTVQ_INT_STAT, - .lastreg = EDGETPU_REG_USER_HIB_IN_ACTVQ_INT_STAT, - }, - { - .firstreg = EDGETPU_REG_USER_HIB_PARAMQ_INT_STAT, - .lastreg = EDGETPU_REG_USER_HIB_PARAMQ_INT_STAT, - }, - { - .firstreg = EDGETPU_REG_USER_HIB_TOPLVL_INT_STAT, - .lastreg = EDGETPU_REG_USER_HIB_TOPLVL_INT_STAT, - }, -}; -int edgetpu_chip_statusregs_nranges = - ARRAY_SIZE(edgetpu_chip_statusregs_ranges); - -struct edgetpu_dumpregs_range edgetpu_chip_tile_statusregs_ranges[] = { -}; -int edgetpu_chip_tile_statusregs_nranges = - ARRAY_SIZE(edgetpu_chip_tile_statusregs_ranges); - static void edgetpu_chip_set_pm_qos(struct edgetpu_dev *etdev, u32 value) { abrolhos_pm_set_pm_qos(etdev, value); diff --git a/drivers/edgetpu/abrolhos-platform.c b/drivers/edgetpu/abrolhos-platform.c index 753e18d..2a3c50d 100644 --- a/drivers/edgetpu/abrolhos-platform.c +++ b/drivers/edgetpu/abrolhos-platform.c @@ -54,6 +54,7 @@ static struct platform_device sscd_dev = { .release = sscd_release, }, }; + /* * Log and trace buffers at the beginning of the remapped region, * pool memory afterwards. @@ -195,6 +196,12 @@ static int edgetpu_platform_probe(struct platform_device *pdev) struct resource *r; struct edgetpu_mapped_resource regs; int ret; + struct edgetpu_iface_params iface_params[] = { + /* Default interface */ + { .name = NULL }, + /* Common name for embedded SoC devices */ + { .name = "edgetpu-soc" }, + }; abpdev = devm_kzalloc(dev, sizeof(*abpdev), GFP_KERNEL); if (!abpdev) @@ -260,7 +267,8 @@ static int edgetpu_platform_probe(struct platform_device *pdev) abpdev->edgetpu_dev.mcp_id = -1; abpdev->edgetpu_dev.mcp_die_index = 0; abpdev->irq = platform_get_irq(pdev, 0); - ret = edgetpu_device_add(&abpdev->edgetpu_dev, ®s); + ret = edgetpu_device_add(&abpdev->edgetpu_dev, ®s, iface_params, + ARRAY_SIZE(iface_params)); if (!ret && abpdev->irq >= 0) ret = edgetpu_register_irq(&abpdev->edgetpu_dev, abpdev->irq); diff --git a/drivers/edgetpu/abrolhos-thermal.c b/drivers/edgetpu/abrolhos-thermal.c index 67016c6..a8a0016 100644 --- a/drivers/edgetpu/abrolhos-thermal.c +++ b/drivers/edgetpu/abrolhos-thermal.c @@ -10,23 +10,45 @@ #include <linux/gfp.h> #include <linux/kernel.h> #include <linux/mutex.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/thermal.h> #include <linux/version.h> -#include <linux/of.h> #include "abrolhos-platform.h" #include "abrolhos-pm.h" #include "edgetpu-config.h" #include "edgetpu-internal.h" #include "edgetpu-mmu.h" +#include "edgetpu-pm.h" #include "edgetpu-thermal.h" #define MAX_NUM_TPU_STATES 10 #define OF_DATA_NUM_MAX MAX_NUM_TPU_STATES * 2 static struct edgetpu_state_pwr state_pwr_map[MAX_NUM_TPU_STATES] = {0}; +/* + * Sends the thermal throttling KCI if the device is powered. + * + * Returns the return value of KCI if the device is powered, otherwise 0. + */ +static int edgetpu_thermal_kci_if_powered(struct edgetpu_dev *etdev, enum tpu_pwr_state state) +{ + int ret = 0; + + if (edgetpu_pm_get_if_powered(etdev->pm)) { + ret = edgetpu_kci_notify_throttling(etdev, state); + if (ret) + etdev_err_ratelimited(etdev, + "Failed to notify FW about power state %u, error:%d", + state, ret); + edgetpu_pm_put(etdev->pm); + } + return ret; +} + static int edgetpu_get_max_state(struct thermal_cooling_device *cdev, unsigned long *state) { @@ -48,7 +70,6 @@ static int edgetpu_set_cur_state(struct thermal_cooling_device *cdev, int ret; struct edgetpu_thermal *cooling = cdev->devdata; struct device *dev = cooling->dev; - struct edgetpu_dev *etdev = cooling->etdev; unsigned long pwr_state; if (state_original >= cooling->tpu_num_states) { @@ -77,15 +98,7 @@ static int edgetpu_set_cur_state(struct thermal_cooling_device *cdev, dev_err(dev, "error setting tpu policy: %d\n", ret); goto out; } - if (pwr_state == TPU_OFF) - cooling->thermal_suspended = true; - else if (state_pwr_map[cooling->cooling_state].state == TPU_OFF) - cooling->thermal_suspended = false; cooling->cooling_state = state_original; - ret = edgetpu_kci_notify_throttling(etdev, pwr_state); - if (ret) - etdev_err(etdev, "Failed to notify FW about power state %lu, error:%d", - pwr_state, ret); } else { ret = -EALREADY; } @@ -337,3 +350,46 @@ struct edgetpu_thermal devres_add(dev, thermal); return thermal; } + +int edgetpu_thermal_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct edgetpu_dev *etdev = platform_get_drvdata(pdev); + struct edgetpu_thermal *cooling = etdev->thermal; + int ret = 0; + + if (IS_ERR(cooling)) + return PTR_ERR(cooling); + mutex_lock(&cooling->lock); + /* + * Always set as suspended even when the FW cannot handle the KCI (it's dead for some + * unknown reasons) because we still want to prevent the runtime from using TPU. + */ + cooling->thermal_suspended = true; + ret = edgetpu_thermal_kci_if_powered(etdev, TPU_OFF); + mutex_unlock(&cooling->lock); + return ret; +} +EXPORT_SYMBOL_GPL(edgetpu_thermal_suspend); + +int edgetpu_thermal_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct edgetpu_dev *etdev = platform_get_drvdata(pdev); + struct edgetpu_thermal *cooling = etdev->thermal; + int ret = 0; + + if (IS_ERR(cooling)) + return PTR_ERR(cooling); + mutex_lock(&cooling->lock); + ret = edgetpu_thermal_kci_if_powered(etdev, state_pwr_map[0].state); + /* + * Unlike edgetpu_thermal_suspend(), only set the device is resumed if the FW handled the + * KCI request. + */ + if (!ret) + cooling->thermal_suspended = false; + mutex_unlock(&cooling->lock); + return ret; +} +EXPORT_SYMBOL_GPL(edgetpu_thermal_resume); diff --git a/drivers/edgetpu/abrolhos/config.h b/drivers/edgetpu/abrolhos/config.h index 00ec926..bb3cc39 100644 --- a/drivers/edgetpu/abrolhos/config.h +++ b/drivers/edgetpu/abrolhos/config.h @@ -18,6 +18,8 @@ /* Reserved VCID that uses the extra partition. */ #define EDGETPU_VCID_EXTRA_PARTITION 0 +/* Is a "mobile" style device. */ +#define EDGETPU_FEATURE_MOBILE #define EDGETPU_HAS_WAKELOCK /* diff --git a/drivers/edgetpu/edgetpu-core.c b/drivers/edgetpu/edgetpu-core.c index bf2ad2d..cab7a6a 100644 --- a/drivers/edgetpu/edgetpu-core.c +++ b/drivers/edgetpu/edgetpu-core.c @@ -345,12 +345,23 @@ int edgetpu_get_state_errno_locked(struct edgetpu_dev *etdev) } int edgetpu_device_add(struct edgetpu_dev *etdev, - const struct edgetpu_mapped_resource *regs) + const struct edgetpu_mapped_resource *regs, + const struct edgetpu_iface_params *iface_params, + uint num_ifaces) { int ret; etdev->regs = *regs; + etdev->etiface = devm_kzalloc( + etdev->dev, sizeof(*etdev->etiface) * num_ifaces, GFP_KERNEL); + + if (!etdev->etiface) { + dev_err(etdev->dev, + "Failed to allocate memory for interfaces\n"); + return -ENOMEM; + } + /* mcp_id and mcp_die_index fields set by caller */ if (etdev->mcp_id < 0) { uint ordinal_id = atomic_add_return(1, &single_dev_count); @@ -377,11 +388,10 @@ int edgetpu_device_add(struct edgetpu_dev *etdev, mutex_init(&etdev->state_lock); etdev->state = ETDEV_STATE_NOFW; - ret = edgetpu_fs_add(etdev); + ret = edgetpu_fs_add(etdev, iface_params, num_ifaces); if (ret) { - dev_err(etdev->dev, "%s: edgetpu_fs_add returns %d\n", - etdev->dev_name, ret); - return ret; + dev_err(etdev->dev, "%s: edgetpu_fs_add returns %d\n", etdev->dev_name, ret); + goto remove_dev; } etdev->mailbox_manager = @@ -456,10 +466,11 @@ void edgetpu_device_remove(struct edgetpu_dev *etdev) edgetpu_fs_remove(etdev); } -struct edgetpu_client *edgetpu_client_add(struct edgetpu_dev *etdev) +struct edgetpu_client *edgetpu_client_add(struct edgetpu_dev_iface *etiface) { struct edgetpu_client *client; struct edgetpu_list_device_client *l = kmalloc(sizeof(*l), GFP_KERNEL); + struct edgetpu_dev *etdev = etiface->etdev; if (!l) return ERR_PTR(-ENOMEM); @@ -478,6 +489,7 @@ struct edgetpu_client *edgetpu_client_add(struct edgetpu_dev *etdev) client->pid = current->pid; client->tgid = current->tgid; client->etdev = etdev; + client->etiface = etiface; mutex_init(&client->group_lock); /* equivalent to edgetpu_client_get() */ refcount_set(&client->count, 1); diff --git a/drivers/edgetpu/edgetpu-fs.c b/drivers/edgetpu/edgetpu-fs.c index c16c964..0dcad64 100644 --- a/drivers/edgetpu/edgetpu-fs.c +++ b/drivers/edgetpu/edgetpu-fs.c @@ -73,13 +73,13 @@ static bool is_edgetpu_file(struct file *file) return file->f_op == &edgetpu_fops; } -int edgetpu_open(struct edgetpu_dev *etdev, struct file *file) +int edgetpu_open(struct edgetpu_dev_iface *etiface, struct file *file) { struct edgetpu_client *client; /* Set client pointer to NULL if error creating client. */ file->private_data = NULL; - client = edgetpu_client_add(etdev); + client = edgetpu_client_add(etiface); if (IS_ERR(client)) return PTR_ERR(client); file->private_data = client; @@ -88,10 +88,10 @@ int edgetpu_open(struct edgetpu_dev *etdev, struct file *file) static int edgetpu_fs_open(struct inode *inode, struct file *file) { - struct edgetpu_dev *etdev = - container_of(inode->i_cdev, struct edgetpu_dev, cdev); + struct edgetpu_dev_iface *etiface = + container_of(inode->i_cdev, struct edgetpu_dev_iface, cdev); - return edgetpu_open(etdev, file); + return edgetpu_open(etiface, file); } static int edgetpu_fs_release(struct inode *inode, struct file *file) @@ -800,6 +800,7 @@ static int edgetpu_fs_mmap(struct file *file, struct vm_area_struct *vma) return edgetpu_mmap(client, vma); } +#ifndef EDGETPU_FEATURE_MOBILE static struct edgetpu_dumpregs_range common_statusregs_ranges[] = { { .firstreg = EDGETPU_REG_AON_RESET, @@ -939,6 +940,7 @@ static const struct file_operations statusregs_ops = { .owner = THIS_MODULE, .release = single_release, }; +#endif /* EDGETPU_FEATURE_MOBILE */ static int mappings_show(struct seq_file *s, void *data) { @@ -979,8 +981,10 @@ static void edgetpu_fs_setup_debugfs(struct edgetpu_dev *etdev) } debugfs_create_file("mappings", 0440, etdev->d_entry, etdev, &mappings_ops); +#ifndef EDGETPU_FEATURE_MOBILE debugfs_create_file("statusregs", 0440, etdev->d_entry, etdev, &statusregs_ops); +#endif } static ssize_t firmware_crash_count_show( @@ -1045,46 +1049,78 @@ const struct file_operations edgetpu_fops = { .unlocked_ioctl = edgetpu_fs_ioctl, }; -/* Called from edgetpu core to add a new edgetpu device. */ -int edgetpu_fs_add(struct edgetpu_dev *etdev) +static int edgeptu_fs_add_interface(struct edgetpu_dev *etdev, struct edgetpu_dev_iface *etiface, + const struct edgetpu_iface_params *etiparams) { + char dev_name[EDGETPU_DEVICE_NAME_MAX]; int ret; - etdev->devno = MKDEV(MAJOR(edgetpu_basedev), + etiface->name = etiparams->name ? etiparams->name : etdev->dev_name; + snprintf(dev_name, EDGETPU_DEVICE_NAME_MAX, "%s", + etiface->name); + + dev_dbg(etdev->dev, "adding interface: %s", dev_name); + + etiface->devno = MKDEV(MAJOR(edgetpu_basedev), atomic_add_return(1, &char_minor)); - cdev_init(&etdev->cdev, &edgetpu_fops); - ret = cdev_add(&etdev->cdev, etdev->devno, 1); + cdev_init(&etiface->cdev, &edgetpu_fops); + ret = cdev_add(&etiface->cdev, etiface->devno, 1); if (ret) { - dev_err(etdev->dev, - "%s: error %d adding cdev for dev %d:%d\n", - etdev->dev_name, ret, - MAJOR(etdev->devno), MINOR(etdev->devno)); + dev_err(etdev->dev, "%s: error %d adding cdev for dev %d:%d\n", + etdev->dev_name, ret, MAJOR(etiface->devno), + MINOR(etiface->devno)); return ret; } - etdev->etcdev = device_create(edgetpu_class, etdev->dev, etdev->devno, - etdev, "%s", etdev->dev_name); - if (IS_ERR(etdev->etcdev)) { - ret = PTR_ERR(etdev->etcdev); + etiface->etcdev = device_create(edgetpu_class, etdev->dev, etiface->devno, + etdev, "%s", dev_name); + if (IS_ERR(etiface->etcdev)) { + ret = PTR_ERR(etiface->etcdev); dev_err(etdev->dev, "%s: failed to create char device: %d\n", - etdev->dev_name, ret); - cdev_del(&etdev->cdev); + dev_name, ret); + cdev_del(&etiface->cdev); return ret; } + return 0; +} + +/* Called from edgetpu core to add new edgetpu device files. */ +int edgetpu_fs_add(struct edgetpu_dev *etdev, const struct edgetpu_iface_params *etiparams, + int num_ifaces) +{ + int ret; + int i; + + etdev->num_ifaces = 0; + dev_dbg(etdev->dev, "%s: adding %u interfaces\n", __func__, num_ifaces); + + for (i = 0; i < num_ifaces; i++) { + etdev->etiface[i].etdev = etdev; + ret = edgeptu_fs_add_interface(etdev, &etdev->etiface[i], &etiparams[i]); + if (ret) + return ret; + etdev->num_ifaces++; + } + ret = device_add_group(etdev->dev, &edgetpu_attr_group); + edgetpu_fs_setup_debugfs(etdev); if (ret) etdev_warn(etdev, "edgetpu attr group create failed: %d", ret); - edgetpu_fs_setup_debugfs(etdev); return 0; } void edgetpu_fs_remove(struct edgetpu_dev *etdev) { + int i; device_remove_group(etdev->dev, &edgetpu_attr_group); - device_destroy(edgetpu_class, etdev->devno); - etdev->etcdev = NULL; - cdev_del(&etdev->cdev); + for (i = 0; i < etdev->num_ifaces; i++) { + struct edgetpu_dev_iface *etiface = &etdev->etiface[i]; + + device_destroy(edgetpu_class, etiface->devno); + etiface->etcdev = NULL; + cdev_del(&etiface->cdev); + } debugfs_remove_recursive(etdev->d_entry); } diff --git a/drivers/edgetpu/edgetpu-internal.h b/drivers/edgetpu/edgetpu-internal.h index 4c1d0a4..aec91d0 100644 --- a/drivers/edgetpu/edgetpu-internal.h +++ b/drivers/edgetpu/edgetpu-internal.h @@ -35,7 +35,8 @@ #include "edgetpu-thermal.h" #include "edgetpu-usage-stats.h" -#define get_dev_for_logging(etdev) ((etdev)->etcdev ? (etdev)->etcdev : (etdev)->dev) +#define get_dev_for_logging(etdev) \ + ((etdev)->etiface->etcdev ? (etdev)->etiface->etcdev : (etdev)->dev) #define etdev_err(etdev, fmt, ...) dev_err(get_dev_for_logging(etdev), fmt, ##__VA_ARGS__) #define etdev_warn(etdev, fmt, ...) \ @@ -97,6 +98,7 @@ struct edgetpu_device_group; struct edgetpu_p2p_csr_map; struct edgetpu_remote_dram_map; struct edgetpu_wakelock; +struct edgetpu_dev_iface; #define EDGETPU_NUM_PERDIE_EVENTS 2 #define perdie_event_id_to_num(event_id) \ @@ -121,6 +123,8 @@ struct edgetpu_client { uint idx; /* the device opened by this client */ struct edgetpu_dev *etdev; + /* the interface from which this client was opened */ + struct edgetpu_dev_iface *etiface; /* Peer CSR dma addrs for this client, if in a group with P2P */ dma_addr_t *p2p_csrs_dma_addrs; /* Peer DRAM dma addrs for this client, if has on-device DRAM */ @@ -131,6 +135,15 @@ struct edgetpu_client { u64 perdie_events; }; +/* Configurable parameters for an edgetpu interface */ +struct edgetpu_iface_params { + /* + * Interface-specific name. + * May be NULL for the default interface (etdev->dev_name will be used) + */ + const char *name; +}; + /* edgetpu_dev#clients list entry. */ struct edgetpu_list_device_client { struct list_head list; @@ -171,9 +184,12 @@ enum edgetpu_dev_state { struct edgetpu_dev { struct device *dev; /* platform/pci bus device */ - struct device *etcdev; /* edgetpu class char device */ - struct cdev cdev; /* cdev char device structure */ - dev_t devno; /* char device dev_t */ + uint num_ifaces; /* Number of device interfaces */ + /* + * Array of device interfaces + * First element is the default interface + */ + struct edgetpu_dev_iface *etiface; char dev_name[EDGETPU_DEVICE_NAME_MAX]; struct edgetpu_mapped_resource regs; /* ioremapped CSRs */ struct dentry *d_entry; /* debugfs dir for this device */ @@ -221,6 +237,14 @@ struct edgetpu_dev { struct work_struct debug_dump_work; }; +struct edgetpu_dev_iface { + struct cdev cdev; /* cdev char device structure */ + struct device *etcdev; /* edgetpu class char device */ + struct edgetpu_dev *etdev; /* Pointer to core device struct */ + dev_t devno; /* char device dev_t */ + const char *name; /* interface specific device name */ +}; + /* Firmware crash_type codes */ enum edgetpu_fw_crash_type { EDGETPU_FW_CRASH_ASSERT = 0, @@ -337,7 +361,7 @@ void edgetpu_free_coherent(struct edgetpu_dev *etdev, /* External drivers can hook up to edgetpu driver using these calls. */ -int edgetpu_open(struct edgetpu_dev *etdev, struct file *file); +int edgetpu_open(struct edgetpu_dev_iface *etiface, struct file *file); long edgetpu_ioctl(struct file *file, uint cmd, ulong arg); #if IS_ENABLED(CONFIG_EDGETPU_EXTERNAL_WRAPPER_CLASS) @@ -361,7 +385,9 @@ void edgetpu_handle_job_lockup(struct edgetpu_dev *etdev, u16 vcid); int __init edgetpu_init(void); void __exit edgetpu_exit(void); int edgetpu_device_add(struct edgetpu_dev *etdev, - const struct edgetpu_mapped_resource *regs); + const struct edgetpu_mapped_resource *regs, + const struct edgetpu_iface_params *iface_params, + uint num_ifaces); void edgetpu_device_remove(struct edgetpu_dev *etdev); int edgetpu_register_irq(struct edgetpu_dev *etdev, int irq); void edgetpu_unregister_irq(struct edgetpu_dev *etdev, int irq); @@ -370,7 +396,9 @@ void edgetpu_unregister_irq(struct edgetpu_dev *etdev, int irq); int __init edgetpu_fs_init(void); void __exit edgetpu_fs_exit(void); -int edgetpu_fs_add(struct edgetpu_dev *etdev); +int edgetpu_fs_add(struct edgetpu_dev *etdev, const struct edgetpu_iface_params *etiparams, + int num_ifaces); + void edgetpu_fs_remove(struct edgetpu_dev *dev); /* Get the top-level debugfs directory for the device class */ struct dentry *edgetpu_fs_debugfs_dir(void); @@ -411,7 +439,8 @@ void edgetpu_chip_handle_reverse_kci(struct edgetpu_dev *etdev, /* Device -> Core API */ /* Add current thread as new TPU client */ -struct edgetpu_client *edgetpu_client_add(struct edgetpu_dev *etdev); +struct edgetpu_client * +edgetpu_client_add(struct edgetpu_dev_iface *etiface); /* Remove TPU client */ void edgetpu_client_remove(struct edgetpu_client *client); diff --git a/drivers/edgetpu/edgetpu-kci.c b/drivers/edgetpu/edgetpu-kci.c index 1b467e2..1f04ecb 100644 --- a/drivers/edgetpu/edgetpu-kci.c +++ b/drivers/edgetpu/edgetpu-kci.c @@ -1044,11 +1044,8 @@ int edgetpu_kci_notify_throttling(struct edgetpu_dev *etdev, u32 level) if (!etdev->kci) return -ENODEV; - if (!edgetpu_pm_get_if_powered(etdev->pm)) - return -EAGAIN; ret = edgetpu_kci_send_cmd(etdev->kci, &cmd); - edgetpu_pm_put(etdev->pm); return ret; } diff --git a/drivers/edgetpu/edgetpu-shared-fw.c b/drivers/edgetpu/edgetpu-shared-fw.c index 9abee03..1a6bcb9 100644 --- a/drivers/edgetpu/edgetpu-shared-fw.c +++ b/drivers/edgetpu/edgetpu-shared-fw.c @@ -178,7 +178,7 @@ edgetpu_shared_fw_load_locked(const char *name, struct edgetpu_dev *etdev) pr_debug("%s: shared fw image %s not found, requesting\n", __func__, name); - ret = request_firmware(&fw, name, etdev ? etdev->etcdev : NULL); + ret = request_firmware(&fw, name, etdev ? etdev->etiface->etcdev : NULL); if (ret) goto out; diff --git a/drivers/edgetpu/edgetpu-thermal.h b/drivers/edgetpu/edgetpu-thermal.h index 2b4dd09..8d4b23f 100644 --- a/drivers/edgetpu/edgetpu-thermal.h +++ b/drivers/edgetpu/edgetpu-thermal.h @@ -42,6 +42,19 @@ struct edgetpu_thermal *devm_tpu_thermal_create(struct device *dev, struct edgetpu_dev *etdev); /* + * Marks the TPU is suspended and informs TPU device if it's powered. + * + * Returns 0 on success. + */ +int edgetpu_thermal_suspend(struct device *dev); +/* + * Resumes the TPU from the suspend state and informs TPU CPU if it's powered. + * + * Returns 0 on success. + */ +int edgetpu_thermal_resume(struct device *dev); + +/* * Holds thermal->lock. * * Does nothing if the thermal management is not supported. |