Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions drivers/nvme/host/apple.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#include "nvme.h"

#define APPLE_ANS_BOOT_TIMEOUT USEC_PER_SEC
/* RTKit handshake timeout for the T6050 ANS, see apple_nvme_alloc() */
#define APPLE_NVME_T6050_HANDSHAKE_TIMEOUT_MS 10000

#define APPLE_ANS_COPROC_CPU_CONTROL 0x44
#define APPLE_ANS_COPROC_CPU_CONTROL_RUN BIT(4)
Expand Down Expand Up @@ -2470,6 +2472,14 @@ static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev)
goto out_detach_genpd;
}

/*
* The T6050 ANS firmware handed over by iBoot can take about 3 s to
* answer the power-state and endpoint-map handshake.
*/
if (of_device_is_compatible(dev->of_node, "apple,t6050-nvme-ans2"))
apple_rtkit_set_handshake_timeout(anv->rtk,
APPLE_NVME_T6050_HANDSHAKE_TIMEOUT_MS);

ret = devm_add_action_or_reset(dev, apple_nvme_free_rtkit, anv);
if (ret)
goto out_detach_genpd;
Expand Down
2 changes: 2 additions & 0 deletions drivers/soc/apple/rtkit-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ struct apple_rtkit {

int boot_result;
int version;
/* How long to wait for each handshake reply from the co-processor. */
unsigned int handshake_timeout_ms;

unsigned int iop_power_state;
unsigned int ap_power_state;
Expand Down
28 changes: 21 additions & 7 deletions drivers/soc/apple/rtkit.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ enum {
#define APPLE_RTKIT_MIN_SUPPORTED_VERSION 11
#define APPLE_RTKIT_MAX_SUPPORTED_VERSION 12

/* Default wait for each handshake reply, see apple_rtkit_set_handshake_timeout() */
#define APPLE_RTKIT_HANDSHAKE_TIMEOUT_MS 1000

struct apple_rtkit_rx_work {
struct apple_rtkit *rtk;
u8 ep;
Expand Down Expand Up @@ -1401,6 +1404,7 @@ static struct apple_rtkit *__apple_rtkit_init(struct device *dev, void *cookie,
rtk->dev = dev;
rtk->cookie = cookie;
rtk->ops = ops;
rtk->handshake_timeout_ms = APPLE_RTKIT_HANDSHAKE_TIMEOUT_MS;
rtk->sync_syslog_ack =
of_property_read_bool(dev->of_node, "apple,sync-syslog-ack");
INIT_KFIFO(rtk->sync_ack_fifo);
Expand Down Expand Up @@ -1480,7 +1484,8 @@ struct apple_rtkit *apple_rtkit_init_adopted(struct device *dev, void *cookie,
}
EXPORT_SYMBOL_GPL(apple_rtkit_init_adopted);

static int apple_rtkit_wait_for_completion(struct completion *c);
static int apple_rtkit_wait_for_completion(struct apple_rtkit *rtk,
struct completion *c);

/*
* apple,sync-syslog-ack (AsahiLinux/linux#607): the mailbox can leave
Expand All @@ -1494,9 +1499,9 @@ static int apple_rtkit_wait(struct apple_rtkit *rtk, struct completion *c)
int ret;

if (!rtk->sync_syslog_ack)
return apple_rtkit_wait_for_completion(c);
return apple_rtkit_wait_for_completion(rtk, c);

timeout = jiffies + msecs_to_jiffies(1000);
timeout = jiffies + msecs_to_jiffies(rtk->handshake_timeout_ms);
do {
ret = apple_rtkit_poll(rtk);
if (ret < 0)
Expand Down Expand Up @@ -1524,12 +1529,13 @@ struct apple_rtkit *apple_rtkit_init_adopted_with_buffers(
}
EXPORT_SYMBOL_GPL(apple_rtkit_init_adopted_with_buffers);

static int apple_rtkit_wait_for_completion(struct completion *c)
static int apple_rtkit_wait_for_completion(struct apple_rtkit *rtk,
struct completion *c)
{
unsigned long timeout = msecs_to_jiffies(rtk->handshake_timeout_ms);
long t;

t = wait_for_completion_interruptible_timeout(c,
msecs_to_jiffies(1000));
t = wait_for_completion_interruptible_timeout(c, timeout);
if (t < 0)
return t;
else if (t == 0)
Expand All @@ -1538,6 +1544,13 @@ static int apple_rtkit_wait_for_completion(struct completion *c)
return 0;
}

void apple_rtkit_set_handshake_timeout(struct apple_rtkit *rtk,
unsigned int timeout_ms)
{
rtk->handshake_timeout_ms = timeout_ms ?: APPLE_RTKIT_HANDSHAKE_TIMEOUT_MS;
}
EXPORT_SYMBOL_GPL(apple_rtkit_set_handshake_timeout);

int apple_rtkit_reinit(struct apple_rtkit *rtk)
{
unsigned long flags;
Expand Down Expand Up @@ -1661,7 +1674,8 @@ static int apple_rtkit_boot_common(struct apple_rtkit *rtk, bool early_ap_power)
/* PMP waits for CoreAnalytics setup before acknowledging IOP power. */
if (apple_rtkit_needs_coreanalytics(rtk) &&
test_bit(APPLE_RTKIT_EP_COREANALYTICS, rtk->endpoints)) {
ret = apple_rtkit_wait_for_completion(&rtk->coreanalytics_completion);
ret = apple_rtkit_wait_for_completion(rtk,
&rtk->coreanalytics_completion);
if (ret) {
dev_err(rtk->dev, "RTKit: CoreAnalytics readiness failed: %d\n", ret);
return ret;
Expand Down
12 changes: 12 additions & 0 deletions include/linux/soc/apple/rtkit.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,18 @@ void apple_rtkit_free_retaining_buffers(struct apple_rtkit *rtk);
*/
int apple_rtkit_reinit(struct apple_rtkit *rtk);

/*
* Set how long each handshake step (power state and endpoint map replies)
* waits for the co-processor, for one that is known to answer slowly. Call
* before apple_rtkit_boot() or apple_rtkit_wake(). Zero restores the default
* of 1000 ms.
*
* @rtk: Internal RTKit state initialized by apple_rtkit_init()
* @timeout_ms: Timeout in milliseconds
*/
void apple_rtkit_set_handshake_timeout(struct apple_rtkit *rtk,
unsigned int timeout_ms);

/*
* Handle RTKit's boot process. Should be called after the CPU of the
* co-processor has been started.
Expand Down
Loading