Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'asahi-soc-rtkit-pmgr-6.3' of https://github.com/AsahiLinux/linux into soc/drivers

Apple SoC RTKit/PMGR updates for 6.3.

This time around we have a PMGR change to allow IRQ-safe usage, RTKit
crash register dump decoding, and a bunch of RTKit API changes used by
upcoming drivers.

* tag 'asahi-soc-rtkit-pmgr-6.3' of https://github.com/AsahiLinux/linux:
soc: apple: rtkit: Add register dump decoding to crashlog
soc: apple: rtkit: Export non-devm init/free functions
soc: apple: rtkit: Add a private pointer to apple_rtkit_shmem
soc: apple: apple-pmgr-pwrstate: Switch to IRQ-safe mode
soc: apple: rtkit: Add apple_rtkit_idle() function

Link: https://lore.kernel.org/r/4790bdc4-b6e2-228b-771f-023363f65fb3@marcan.st
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+157 -9
+7 -4
drivers/soc/apple/apple-pmgr-pwrstate.c
··· 116 116 static int apple_pmgr_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) 117 117 { 118 118 struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev); 119 + unsigned long flags; 119 120 120 - mutex_lock(&ps->genpd.mlock); 121 + spin_lock_irqsave(&ps->genpd.slock, flags); 121 122 122 123 if (ps->genpd.status == GENPD_STATE_OFF) 123 124 dev_err(ps->dev, "PS 0x%x: asserting RESET while powered down\n", ps->offset); ··· 130 129 regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_RESET, 131 130 APPLE_PMGR_RESET); 132 131 133 - mutex_unlock(&ps->genpd.mlock); 132 + spin_unlock_irqrestore(&ps->genpd.slock, flags); 134 133 135 134 return 0; 136 135 } ··· 138 137 static int apple_pmgr_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) 139 138 { 140 139 struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev); 140 + unsigned long flags; 141 141 142 - mutex_lock(&ps->genpd.mlock); 142 + spin_lock_irqsave(&ps->genpd.slock, flags); 143 143 144 144 dev_dbg(ps->dev, "PS 0x%x: deassert reset\n", ps->offset); 145 145 regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_RESET, 0); ··· 149 147 if (ps->genpd.status == GENPD_STATE_OFF) 150 148 dev_err(ps->dev, "PS 0x%x: RESET was deasserted while powered down\n", ps->offset); 151 149 152 - mutex_unlock(&ps->genpd.mlock); 150 + spin_unlock_irqrestore(&ps->genpd.slock, flags); 153 151 154 152 return 0; 155 153 } ··· 224 222 return ret; 225 223 } 226 224 225 + ps->genpd.flags |= GENPD_FLAG_IRQ_SAFE; 227 226 ps->genpd.name = name; 228 227 ps->genpd.power_on = apple_pmgr_ps_power_on; 229 228 ps->genpd.power_off = apple_pmgr_ps_power_off;
+93
drivers/soc/apple/rtkit-crashlog.c
··· 13 13 #define APPLE_RTKIT_CRASHLOG_VERSION FOURCC('C', 'v', 'e', 'r') 14 14 #define APPLE_RTKIT_CRASHLOG_MBOX FOURCC('C', 'm', 'b', 'x') 15 15 #define APPLE_RTKIT_CRASHLOG_TIME FOURCC('C', 't', 'i', 'm') 16 + #define APPLE_RTKIT_CRASHLOG_REGS FOURCC('C', 'r', 'g', '8') 17 + 18 + /* For COMPILE_TEST on non-ARM64 architectures */ 19 + #ifndef PSR_MODE_EL0t 20 + #define PSR_MODE_EL0t 0x00000000 21 + #define PSR_MODE_EL1t 0x00000004 22 + #define PSR_MODE_EL1h 0x00000005 23 + #define PSR_MODE_EL2t 0x00000008 24 + #define PSR_MODE_EL2h 0x00000009 25 + #define PSR_MODE_MASK 0x0000000f 26 + #endif 16 27 17 28 struct apple_rtkit_crashlog_header { 18 29 u32 fourcc; ··· 41 30 u8 _unk[4]; 42 31 }; 43 32 static_assert(sizeof(struct apple_rtkit_crashlog_mbox_entry) == 0x18); 33 + 34 + struct apple_rtkit_crashlog_regs { 35 + u32 unk_0; 36 + u32 unk_4; 37 + u64 regs[31]; 38 + u64 sp; 39 + u64 pc; 40 + u64 psr; 41 + u64 cpacr; 42 + u64 fpsr; 43 + u64 fpcr; 44 + u64 unk[64]; 45 + u64 far; 46 + u64 unk_X; 47 + u64 esr; 48 + u64 unk_Z; 49 + }; 50 + static_assert(sizeof(struct apple_rtkit_crashlog_regs) == 0x350); 44 51 45 52 static void apple_rtkit_crashlog_dump_str(struct apple_rtkit *rtk, u8 *bfr, 46 53 size_t size) ··· 123 94 } 124 95 } 125 96 97 + static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr, 98 + size_t size) 99 + { 100 + struct apple_rtkit_crashlog_regs regs; 101 + const char *el; 102 + int i; 103 + 104 + if (size < sizeof(regs)) { 105 + dev_warn(rtk->dev, "RTKit: Regs section too small: 0x%zx", size); 106 + return; 107 + } 108 + 109 + memcpy(&regs, bfr, sizeof(regs)); 110 + 111 + switch (regs.psr & PSR_MODE_MASK) { 112 + case PSR_MODE_EL0t: 113 + el = "EL0t"; 114 + break; 115 + case PSR_MODE_EL1t: 116 + el = "EL1t"; 117 + break; 118 + case PSR_MODE_EL1h: 119 + el = "EL1h"; 120 + break; 121 + case PSR_MODE_EL2t: 122 + el = "EL2t"; 123 + break; 124 + case PSR_MODE_EL2h: 125 + el = "EL2h"; 126 + break; 127 + default: 128 + el = "unknown"; 129 + break; 130 + } 131 + 132 + dev_warn(rtk->dev, "RTKit: Exception dump:"); 133 + dev_warn(rtk->dev, " == Exception taken from %s ==", el); 134 + dev_warn(rtk->dev, " PSR = 0x%llx", regs.psr); 135 + dev_warn(rtk->dev, " PC = 0x%llx\n", regs.pc); 136 + dev_warn(rtk->dev, " ESR = 0x%llx\n", regs.esr); 137 + dev_warn(rtk->dev, " FAR = 0x%llx\n", regs.far); 138 + dev_warn(rtk->dev, " SP = 0x%llx\n", regs.sp); 139 + dev_warn(rtk->dev, "\n"); 140 + 141 + for (i = 0; i < 31; i += 4) { 142 + if (i < 28) 143 + dev_warn(rtk->dev, 144 + " x%02d-x%02d = %016llx %016llx %016llx %016llx\n", 145 + i, i + 3, 146 + regs.regs[i], regs.regs[i + 1], 147 + regs.regs[i + 2], regs.regs[i + 3]); 148 + else 149 + dev_warn(rtk->dev, 150 + " x%02d-x%02d = %016llx %016llx %016llx\n", i, i + 3, 151 + regs.regs[i], regs.regs[i + 1], regs.regs[i + 2]); 152 + } 153 + 154 + dev_warn(rtk->dev, "\n"); 155 + } 156 + 126 157 void apple_rtkit_crashlog_dump(struct apple_rtkit *rtk, u8 *bfr, size_t size) 127 158 { 128 159 size_t offset; ··· 227 138 break; 228 139 case APPLE_RTKIT_CRASHLOG_TIME: 229 140 apple_rtkit_crashlog_dump_time(rtk, bfr + offset + 16, 141 + section_size); 142 + break; 143 + case APPLE_RTKIT_CRASHLOG_REGS: 144 + apple_rtkit_crashlog_dump_regs(rtk, bfr + offset + 16, 230 145 section_size); 231 146 break; 232 147 default:
+31 -5
drivers/soc/apple/rtkit.c
··· 9 9 enum { 10 10 APPLE_RTKIT_PWR_STATE_OFF = 0x00, /* power off, cannot be restarted */ 11 11 APPLE_RTKIT_PWR_STATE_SLEEP = 0x01, /* sleeping, can be restarted */ 12 + APPLE_RTKIT_PWR_STATE_IDLE = 0x201, /* sleeping, retain state */ 12 13 APPLE_RTKIT_PWR_STATE_QUIESCED = 0x10, /* running but no communication */ 13 14 APPLE_RTKIT_PWR_STATE_ON = 0x20, /* normal operating state */ 14 15 }; ··· 699 698 return 0; 700 699 } 701 700 702 - static struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie, 701 + struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie, 703 702 const char *mbox_name, int mbox_idx, 704 703 const struct apple_rtkit_ops *ops) 705 704 { ··· 751 750 kfree(rtk); 752 751 return ERR_PTR(ret); 753 752 } 753 + EXPORT_SYMBOL_GPL(apple_rtkit_init); 754 754 755 755 static int apple_rtkit_wait_for_completion(struct completion *c) 756 756 { ··· 883 881 } 884 882 EXPORT_SYMBOL_GPL(apple_rtkit_shutdown); 885 883 884 + int apple_rtkit_idle(struct apple_rtkit *rtk) 885 + { 886 + int ret; 887 + 888 + /* if OFF is used here the co-processor will not wake up again */ 889 + ret = apple_rtkit_set_ap_power_state(rtk, 890 + APPLE_RTKIT_PWR_STATE_IDLE); 891 + if (ret) 892 + return ret; 893 + 894 + ret = apple_rtkit_set_iop_power_state(rtk, APPLE_RTKIT_PWR_STATE_IDLE); 895 + if (ret) 896 + return ret; 897 + 898 + rtk->iop_power_state = APPLE_RTKIT_PWR_STATE_IDLE; 899 + rtk->ap_power_state = APPLE_RTKIT_PWR_STATE_IDLE; 900 + return 0; 901 + } 902 + EXPORT_SYMBOL_GPL(apple_rtkit_idle); 903 + 886 904 int apple_rtkit_quiesce(struct apple_rtkit *rtk) 887 905 { 888 906 int ret; ··· 948 926 } 949 927 EXPORT_SYMBOL_GPL(apple_rtkit_wake); 950 928 951 - static void apple_rtkit_free(void *data) 929 + void apple_rtkit_free(struct apple_rtkit *rtk) 952 930 { 953 - struct apple_rtkit *rtk = data; 954 - 955 931 mbox_free_channel(rtk->mbox_chan); 956 932 destroy_workqueue(rtk->wq); 957 933 ··· 959 939 960 940 kfree(rtk->syslog_msg_buffer); 961 941 kfree(rtk); 942 + } 943 + EXPORT_SYMBOL_GPL(apple_rtkit_free); 944 + 945 + static void apple_rtkit_free_wrapper(void *data) 946 + { 947 + apple_rtkit_free(data); 962 948 } 963 949 964 950 struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie, ··· 978 952 if (IS_ERR(rtk)) 979 953 return rtk; 980 954 981 - ret = devm_add_action_or_reset(dev, apple_rtkit_free, rtk); 955 + ret = devm_add_action_or_reset(dev, apple_rtkit_free_wrapper, rtk); 982 956 if (ret) 983 957 return ERR_PTR(ret); 984 958
+26
include/linux/soc/apple/rtkit.h
··· 22 22 * @size: Size of the shared memory buffer. 23 23 * @iova: Device VA of shared memory buffer. 24 24 * @is_mapped: Shared memory buffer is managed by the co-processor. 25 + * @private: Private data pointer for the parent driver. 25 26 */ 26 27 27 28 struct apple_rtkit_shmem { ··· 31 30 size_t size; 32 31 dma_addr_t iova; 33 32 bool is_mapped; 33 + void *private; 34 34 }; 35 35 36 36 /* ··· 80 78 const struct apple_rtkit_ops *ops); 81 79 82 80 /* 81 + * Non-devm version of devm_apple_rtkit_init. Must be freed with 82 + * apple_rtkit_free. 83 + * 84 + * @dev: Pointer to the device node this coprocessor is assocated with 85 + * @cookie: opaque cookie passed to all functions defined in rtkit_ops 86 + * @mbox_name: mailbox name used to communicate with the co-processor 87 + * @mbox_idx: mailbox index to be used if mbox_name is NULL 88 + * @ops: pointer to rtkit_ops to be used for this co-processor 89 + */ 90 + struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie, 91 + const char *mbox_name, int mbox_idx, 92 + const struct apple_rtkit_ops *ops); 93 + 94 + /* 95 + * Free an instance of apple_rtkit. 96 + */ 97 + void apple_rtkit_free(struct apple_rtkit *rtk); 98 + 99 + /* 83 100 * Reinitialize internal structures. Must only be called with the co-processor 84 101 * is held in reset. 85 102 */ ··· 124 103 * Shutdown the co-processor 125 104 */ 126 105 int apple_rtkit_shutdown(struct apple_rtkit *rtk); 106 + 107 + /* 108 + * Put the co-processor into idle mode 109 + */ 110 + int apple_rtkit_idle(struct apple_rtkit *rtk); 127 111 128 112 /* 129 113 * Checks if RTKit is running and ready to handle messages.