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. -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQSByI3Ki0mXziclZJcd+FPLCI8zYgUCY9kAQwAKCRAd+FPLCI8z YhQYAP4km7JfYWsQYKjGSqHounJqgzFnaGFyN3xBmUH3cpyEaQD+IP3vl9PBBWqw /rrpVlSwfZ6E1VclFTpaE6/KJPDZwwA= =tXq9 -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmPg3mQACgkQmmx57+YA GNkhQg/+INoPNTCkN3iAOVbcYG9AfluK7tHsYXsr/yBxuSJgehGKWWLBDlloANSJ ry7tOxlThT+SIuLTTyVTCw18A38eZmbHmBexSxJQek1BDC6BXsVsnWIV8DCSB461 9kaVxrFgIjSe1vh+SDgRmQeEvf8qXJRBe8TLm8G2F4Wnf2hxiD5j7Kq0lIj2QC/L /ITzB0LE3DbEMvvTdXW2drDzwz1zne0SNolFmPtVo8fDyQbStSURpcR41kzcXodk j4PXy0PxGe31eOxkEVyVIo9+bJMGSzLOjgraFBosbfi0n8NfgnPy+NjD5lm2aqz1 h5zYrFYPqvkwsQMBPsqO3zMk0Q4x/uU0QmSUZfYte3uYMHstEdtG/y+8x6ELUWXr /LFtAwYfntj54GbiU1YAP6xXaJpYluCF1ICW10GZTOlprNgSB3rrb3G8HLJChOxb /KDtG+O0mVtyS45FZjvBJJ8GAU0FCs17YInUCDQV64XCSa7SV4X7Rw4D/dHrhDL5 u6yrKlYqLKh/6Nom27a5C7F8L7XIreMu7PK6Hc9lrdQoMBOKd9CQT54G8nEEQHNx Hrzk/aXJ5USwREawlDltHnZz2mcXzXCFBhXTJNL/3Tj0qV3QXtP4tHxaW/NFcNaZ WX8YpCP0MErPrkvy5VX5H9S3qJKXP6b66pM+rF6c7LoxP9JgURk= =HucU -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
7d47f6ffa5
|
@ -116,8 +116,9 @@ static int apple_pmgr_ps_power_off(struct generic_pm_domain *genpd)
|
|||
static int apple_pmgr_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
{
|
||||
struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&ps->genpd.mlock);
|
||||
spin_lock_irqsave(&ps->genpd.slock, flags);
|
||||
|
||||
if (ps->genpd.status == GENPD_STATE_OFF)
|
||||
dev_err(ps->dev, "PS 0x%x: asserting RESET while powered down\n", ps->offset);
|
||||
|
@ -129,7 +130,7 @@ static int apple_pmgr_reset_assert(struct reset_controller_dev *rcdev, unsigned
|
|||
regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_RESET,
|
||||
APPLE_PMGR_RESET);
|
||||
|
||||
mutex_unlock(&ps->genpd.mlock);
|
||||
spin_unlock_irqrestore(&ps->genpd.slock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -137,8 +138,9 @@ static int apple_pmgr_reset_assert(struct reset_controller_dev *rcdev, unsigned
|
|||
static int apple_pmgr_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
{
|
||||
struct apple_pmgr_ps *ps = rcdev_to_apple_pmgr_ps(rcdev);
|
||||
unsigned long flags;
|
||||
|
||||
mutex_lock(&ps->genpd.mlock);
|
||||
spin_lock_irqsave(&ps->genpd.slock, flags);
|
||||
|
||||
dev_dbg(ps->dev, "PS 0x%x: deassert reset\n", ps->offset);
|
||||
regmap_update_bits(ps->regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_RESET, 0);
|
||||
|
@ -147,7 +149,7 @@ static int apple_pmgr_reset_deassert(struct reset_controller_dev *rcdev, unsigne
|
|||
if (ps->genpd.status == GENPD_STATE_OFF)
|
||||
dev_err(ps->dev, "PS 0x%x: RESET was deasserted while powered down\n", ps->offset);
|
||||
|
||||
mutex_unlock(&ps->genpd.mlock);
|
||||
spin_unlock_irqrestore(&ps->genpd.slock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -222,6 +224,7 @@ static int apple_pmgr_ps_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ps->genpd.flags |= GENPD_FLAG_IRQ_SAFE;
|
||||
ps->genpd.name = name;
|
||||
ps->genpd.power_on = apple_pmgr_ps_power_on;
|
||||
ps->genpd.power_off = apple_pmgr_ps_power_off;
|
||||
|
|
|
@ -13,6 +13,17 @@
|
|||
#define APPLE_RTKIT_CRASHLOG_VERSION FOURCC('C', 'v', 'e', 'r')
|
||||
#define APPLE_RTKIT_CRASHLOG_MBOX FOURCC('C', 'm', 'b', 'x')
|
||||
#define APPLE_RTKIT_CRASHLOG_TIME FOURCC('C', 't', 'i', 'm')
|
||||
#define APPLE_RTKIT_CRASHLOG_REGS FOURCC('C', 'r', 'g', '8')
|
||||
|
||||
/* For COMPILE_TEST on non-ARM64 architectures */
|
||||
#ifndef PSR_MODE_EL0t
|
||||
#define PSR_MODE_EL0t 0x00000000
|
||||
#define PSR_MODE_EL1t 0x00000004
|
||||
#define PSR_MODE_EL1h 0x00000005
|
||||
#define PSR_MODE_EL2t 0x00000008
|
||||
#define PSR_MODE_EL2h 0x00000009
|
||||
#define PSR_MODE_MASK 0x0000000f
|
||||
#endif
|
||||
|
||||
struct apple_rtkit_crashlog_header {
|
||||
u32 fourcc;
|
||||
|
@ -31,6 +42,24 @@ struct apple_rtkit_crashlog_mbox_entry {
|
|||
};
|
||||
static_assert(sizeof(struct apple_rtkit_crashlog_mbox_entry) == 0x18);
|
||||
|
||||
struct apple_rtkit_crashlog_regs {
|
||||
u32 unk_0;
|
||||
u32 unk_4;
|
||||
u64 regs[31];
|
||||
u64 sp;
|
||||
u64 pc;
|
||||
u64 psr;
|
||||
u64 cpacr;
|
||||
u64 fpsr;
|
||||
u64 fpcr;
|
||||
u64 unk[64];
|
||||
u64 far;
|
||||
u64 unk_X;
|
||||
u64 esr;
|
||||
u64 unk_Z;
|
||||
};
|
||||
static_assert(sizeof(struct apple_rtkit_crashlog_regs) == 0x350);
|
||||
|
||||
static void apple_rtkit_crashlog_dump_str(struct apple_rtkit *rtk, u8 *bfr,
|
||||
size_t size)
|
||||
{
|
||||
|
@ -94,6 +123,66 @@ static void apple_rtkit_crashlog_dump_mailbox(struct apple_rtkit *rtk, u8 *bfr,
|
|||
}
|
||||
}
|
||||
|
||||
static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr,
|
||||
size_t size)
|
||||
{
|
||||
struct apple_rtkit_crashlog_regs regs;
|
||||
const char *el;
|
||||
int i;
|
||||
|
||||
if (size < sizeof(regs)) {
|
||||
dev_warn(rtk->dev, "RTKit: Regs section too small: 0x%zx", size);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(®s, bfr, sizeof(regs));
|
||||
|
||||
switch (regs.psr & PSR_MODE_MASK) {
|
||||
case PSR_MODE_EL0t:
|
||||
el = "EL0t";
|
||||
break;
|
||||
case PSR_MODE_EL1t:
|
||||
el = "EL1t";
|
||||
break;
|
||||
case PSR_MODE_EL1h:
|
||||
el = "EL1h";
|
||||
break;
|
||||
case PSR_MODE_EL2t:
|
||||
el = "EL2t";
|
||||
break;
|
||||
case PSR_MODE_EL2h:
|
||||
el = "EL2h";
|
||||
break;
|
||||
default:
|
||||
el = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
dev_warn(rtk->dev, "RTKit: Exception dump:");
|
||||
dev_warn(rtk->dev, " == Exception taken from %s ==", el);
|
||||
dev_warn(rtk->dev, " PSR = 0x%llx", regs.psr);
|
||||
dev_warn(rtk->dev, " PC = 0x%llx\n", regs.pc);
|
||||
dev_warn(rtk->dev, " ESR = 0x%llx\n", regs.esr);
|
||||
dev_warn(rtk->dev, " FAR = 0x%llx\n", regs.far);
|
||||
dev_warn(rtk->dev, " SP = 0x%llx\n", regs.sp);
|
||||
dev_warn(rtk->dev, "\n");
|
||||
|
||||
for (i = 0; i < 31; i += 4) {
|
||||
if (i < 28)
|
||||
dev_warn(rtk->dev,
|
||||
" x%02d-x%02d = %016llx %016llx %016llx %016llx\n",
|
||||
i, i + 3,
|
||||
regs.regs[i], regs.regs[i + 1],
|
||||
regs.regs[i + 2], regs.regs[i + 3]);
|
||||
else
|
||||
dev_warn(rtk->dev,
|
||||
" x%02d-x%02d = %016llx %016llx %016llx\n", i, i + 3,
|
||||
regs.regs[i], regs.regs[i + 1], regs.regs[i + 2]);
|
||||
}
|
||||
|
||||
dev_warn(rtk->dev, "\n");
|
||||
}
|
||||
|
||||
void apple_rtkit_crashlog_dump(struct apple_rtkit *rtk, u8 *bfr, size_t size)
|
||||
{
|
||||
size_t offset;
|
||||
|
@ -140,6 +229,10 @@ void apple_rtkit_crashlog_dump(struct apple_rtkit *rtk, u8 *bfr, size_t size)
|
|||
apple_rtkit_crashlog_dump_time(rtk, bfr + offset + 16,
|
||||
section_size);
|
||||
break;
|
||||
case APPLE_RTKIT_CRASHLOG_REGS:
|
||||
apple_rtkit_crashlog_dump_regs(rtk, bfr + offset + 16,
|
||||
section_size);
|
||||
break;
|
||||
default:
|
||||
dev_warn(rtk->dev,
|
||||
"RTKit: Unknown crashlog section: %x",
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
enum {
|
||||
APPLE_RTKIT_PWR_STATE_OFF = 0x00, /* power off, cannot be restarted */
|
||||
APPLE_RTKIT_PWR_STATE_SLEEP = 0x01, /* sleeping, can be restarted */
|
||||
APPLE_RTKIT_PWR_STATE_IDLE = 0x201, /* sleeping, retain state */
|
||||
APPLE_RTKIT_PWR_STATE_QUIESCED = 0x10, /* running but no communication */
|
||||
APPLE_RTKIT_PWR_STATE_ON = 0x20, /* normal operating state */
|
||||
};
|
||||
|
@ -698,7 +699,7 @@ static int apple_rtkit_request_mbox_chan(struct apple_rtkit *rtk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie,
|
||||
struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie,
|
||||
const char *mbox_name, int mbox_idx,
|
||||
const struct apple_rtkit_ops *ops)
|
||||
{
|
||||
|
@ -750,6 +751,7 @@ free_rtk:
|
|||
kfree(rtk);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(apple_rtkit_init);
|
||||
|
||||
static int apple_rtkit_wait_for_completion(struct completion *c)
|
||||
{
|
||||
|
@ -881,6 +883,26 @@ int apple_rtkit_shutdown(struct apple_rtkit *rtk)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(apple_rtkit_shutdown);
|
||||
|
||||
int apple_rtkit_idle(struct apple_rtkit *rtk)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* if OFF is used here the co-processor will not wake up again */
|
||||
ret = apple_rtkit_set_ap_power_state(rtk,
|
||||
APPLE_RTKIT_PWR_STATE_IDLE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = apple_rtkit_set_iop_power_state(rtk, APPLE_RTKIT_PWR_STATE_IDLE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
rtk->iop_power_state = APPLE_RTKIT_PWR_STATE_IDLE;
|
||||
rtk->ap_power_state = APPLE_RTKIT_PWR_STATE_IDLE;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(apple_rtkit_idle);
|
||||
|
||||
int apple_rtkit_quiesce(struct apple_rtkit *rtk)
|
||||
{
|
||||
int ret;
|
||||
|
@ -926,10 +948,8 @@ int apple_rtkit_wake(struct apple_rtkit *rtk)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(apple_rtkit_wake);
|
||||
|
||||
static void apple_rtkit_free(void *data)
|
||||
void apple_rtkit_free(struct apple_rtkit *rtk)
|
||||
{
|
||||
struct apple_rtkit *rtk = data;
|
||||
|
||||
mbox_free_channel(rtk->mbox_chan);
|
||||
destroy_workqueue(rtk->wq);
|
||||
|
||||
|
@ -940,6 +960,12 @@ static void apple_rtkit_free(void *data)
|
|||
kfree(rtk->syslog_msg_buffer);
|
||||
kfree(rtk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(apple_rtkit_free);
|
||||
|
||||
static void apple_rtkit_free_wrapper(void *data)
|
||||
{
|
||||
apple_rtkit_free(data);
|
||||
}
|
||||
|
||||
struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie,
|
||||
const char *mbox_name, int mbox_idx,
|
||||
|
@ -952,7 +978,7 @@ struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie,
|
|||
if (IS_ERR(rtk))
|
||||
return rtk;
|
||||
|
||||
ret = devm_add_action_or_reset(dev, apple_rtkit_free, rtk);
|
||||
ret = devm_add_action_or_reset(dev, apple_rtkit_free_wrapper, rtk);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
* @size: Size of the shared memory buffer.
|
||||
* @iova: Device VA of shared memory buffer.
|
||||
* @is_mapped: Shared memory buffer is managed by the co-processor.
|
||||
* @private: Private data pointer for the parent driver.
|
||||
*/
|
||||
|
||||
struct apple_rtkit_shmem {
|
||||
|
@ -30,6 +31,7 @@ struct apple_rtkit_shmem {
|
|||
size_t size;
|
||||
dma_addr_t iova;
|
||||
bool is_mapped;
|
||||
void *private;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -77,6 +79,25 @@ struct apple_rtkit *devm_apple_rtkit_init(struct device *dev, void *cookie,
|
|||
const char *mbox_name, int mbox_idx,
|
||||
const struct apple_rtkit_ops *ops);
|
||||
|
||||
/*
|
||||
* Non-devm version of devm_apple_rtkit_init. Must be freed with
|
||||
* apple_rtkit_free.
|
||||
*
|
||||
* @dev: Pointer to the device node this coprocessor is assocated with
|
||||
* @cookie: opaque cookie passed to all functions defined in rtkit_ops
|
||||
* @mbox_name: mailbox name used to communicate with the co-processor
|
||||
* @mbox_idx: mailbox index to be used if mbox_name is NULL
|
||||
* @ops: pointer to rtkit_ops to be used for this co-processor
|
||||
*/
|
||||
struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie,
|
||||
const char *mbox_name, int mbox_idx,
|
||||
const struct apple_rtkit_ops *ops);
|
||||
|
||||
/*
|
||||
* Free an instance of apple_rtkit.
|
||||
*/
|
||||
void apple_rtkit_free(struct apple_rtkit *rtk);
|
||||
|
||||
/*
|
||||
* Reinitialize internal structures. Must only be called with the co-processor
|
||||
* is held in reset.
|
||||
|
@ -104,6 +125,11 @@ int apple_rtkit_wake(struct apple_rtkit *rtk);
|
|||
*/
|
||||
int apple_rtkit_shutdown(struct apple_rtkit *rtk);
|
||||
|
||||
/*
|
||||
* Put the co-processor into idle mode
|
||||
*/
|
||||
int apple_rtkit_idle(struct apple_rtkit *rtk);
|
||||
|
||||
/*
|
||||
* Checks if RTKit is running and ready to handle messages.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue