Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d033e078 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branch 'pm-domains' into pm-for-linus

* pm-domains:
  ARM: mach-shmobile: sh7372 A4R support (v4)
  ARM: mach-shmobile: sh7372 A3SP support (v4)
  PM / Sleep: Mark devices involved in wakeup signaling during suspend
parents 081a9d04 382414b9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1409,6 +1409,11 @@ static void __init ap4evb_init(void)
	sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc_device);
	sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device);

	sh7372_add_device_to_domain(&sh7372_a3sp, &sh_mmcif_device);
	sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi0_device);
	sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi1_device);
	sh7372_add_device_to_domain(&sh7372_a4r, &ceu_device);

	hdmi_init_pm_clock();
	fsi_init_pm_clock();
	sh7372_pm_init();
+9 −0
Original line number Diff line number Diff line
@@ -1588,6 +1588,15 @@ static void __init mackerel_init(void)
	sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc_device);
	sh7372_add_device_to_domain(&sh7372_a4lc, &hdmi_lcdc_device);
	sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device);
	sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs0_device);
	sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs1_device);
	sh7372_add_device_to_domain(&sh7372_a3sp, &sh_mmcif_device);
	sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi0_device);
#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
	sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi1_device);
#endif
	sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi2_device);
	sh7372_add_device_to_domain(&sh7372_a4r, &ceu_device);

	hdmi_init_pm_clock();
	sh7372_pm_init();
+10 −0
Original line number Diff line number Diff line
@@ -479,7 +479,12 @@ struct platform_device;

struct sh7372_pm_domain {
	struct generic_pm_domain genpd;
	struct dev_power_governor *gov;
	void (*suspend)(void);
	void (*resume)(void);
	unsigned int bit_shift;
	bool no_debug;
	bool stay_on;
};

static inline struct sh7372_pm_domain *to_sh7372_pd(struct generic_pm_domain *d)
@@ -491,8 +496,10 @@ static inline struct sh7372_pm_domain *to_sh7372_pd(struct generic_pm_domain *d)
extern struct sh7372_pm_domain sh7372_a4lc;
extern struct sh7372_pm_domain sh7372_a4mp;
extern struct sh7372_pm_domain sh7372_d4;
extern struct sh7372_pm_domain sh7372_a4r;
extern struct sh7372_pm_domain sh7372_a3rv;
extern struct sh7372_pm_domain sh7372_a3ri;
extern struct sh7372_pm_domain sh7372_a3sp;
extern struct sh7372_pm_domain sh7372_a3sg;

extern void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd);
@@ -506,4 +513,7 @@ extern void sh7372_pm_add_subdomain(struct sh7372_pm_domain *sh7372_pd,
#define sh7372_pm_add_subdomain(pd, sd) do { } while(0)
#endif /* CONFIG_PM */

extern void sh7372_intcs_suspend(void);
extern void sh7372_intcs_resume(void);

#endif /* __ASM_SH7372_H__ */
+51 −1
Original line number Diff line number Diff line
@@ -606,9 +606,16 @@ static void intcs_demux(unsigned int irq, struct irq_desc *desc)
	generic_handle_irq(intcs_evt2irq(evtcodeas));
}

static void __iomem *intcs_ffd2;
static void __iomem *intcs_ffd5;

void __init sh7372_init_irq(void)
{
	void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
	void __iomem *intevtsa;

	intcs_ffd2 = ioremap_nocache(0xffd20000, PAGE_SIZE);
	intevtsa = intcs_ffd2 + 0x100;
	intcs_ffd5 = ioremap_nocache(0xffd50000, PAGE_SIZE);

	register_intc_controller(&intca_desc);
	register_intc_controller(&intcs_desc);
@@ -617,3 +624,46 @@ void __init sh7372_init_irq(void)
	irq_set_handler_data(evt2irq(0xf80), (void *)intevtsa);
	irq_set_chained_handler(evt2irq(0xf80), intcs_demux);
}

static unsigned short ffd2[0x200];
static unsigned short ffd5[0x100];

void sh7372_intcs_suspend(void)
{
	int k;

	for (k = 0x00; k <= 0x30; k += 4)
		ffd2[k] = __raw_readw(intcs_ffd2 + k);

	for (k = 0x80; k <= 0xb0; k += 4)
		ffd2[k] = __raw_readb(intcs_ffd2 + k);

	for (k = 0x180; k <= 0x188; k += 4)
		ffd2[k] = __raw_readb(intcs_ffd2 + k);

	for (k = 0x00; k <= 0x3c; k += 4)
		ffd5[k] = __raw_readw(intcs_ffd5 + k);

	for (k = 0x80; k <= 0x9c; k += 4)
		ffd5[k] = __raw_readb(intcs_ffd5 + k);
}

void sh7372_intcs_resume(void)
{
	int k;

	for (k = 0x00; k <= 0x30; k += 4)
		__raw_writew(ffd2[k], intcs_ffd2 + k);

	for (k = 0x80; k <= 0xb0; k += 4)
		__raw_writeb(ffd2[k], intcs_ffd2 + k);

	for (k = 0x180; k <= 0x188; k += 4)
		__raw_writeb(ffd2[k], intcs_ffd2 + k);

	for (k = 0x00; k <= 0x3c; k += 4)
		__raw_writew(ffd5[k], intcs_ffd5 + k);

	for (k = 0x80; k <= 0x9c; k += 4)
		__raw_writeb(ffd5[k], intcs_ffd5 + k);
}
+52 −5
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
#define SPDCR 0xe6180008
#define SWUCR 0xe6180014
#define SBAR 0xe6180020
#define WUPRMSK 0xe6180028
#define WUPSMSK 0xe618002c
#define WUPSMSK2 0xe6180048
#define PSTR 0xe6180080
@@ -80,6 +81,12 @@ static int pd_power_down(struct generic_pm_domain *genpd)
	struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd);
	unsigned int mask = 1 << sh7372_pd->bit_shift;

	if (sh7372_pd->suspend)
		sh7372_pd->suspend();

	if (sh7372_pd->stay_on)
		return 0;

	if (__raw_readl(PSTR) & mask) {
		unsigned int retry_count;

@@ -92,6 +99,7 @@ static int pd_power_down(struct generic_pm_domain *genpd)
		}
	}

	if (!sh7372_pd->no_debug)
		pr_debug("sh7372 power domain down 0x%08x -> PSTR = 0x%08x\n",
			 mask, __raw_readl(PSTR));

@@ -105,6 +113,9 @@ static int pd_power_up(struct generic_pm_domain *genpd)
	unsigned int retry_count;
	int ret = 0;

	if (sh7372_pd->stay_on)
		goto out;

	if (__raw_readl(PSTR) & mask)
		goto out;

@@ -121,23 +132,42 @@ static int pd_power_up(struct generic_pm_domain *genpd)
	if (__raw_readl(SWUCR) & mask)
		ret = -EIO;

 out:
	if (!sh7372_pd->no_debug)
		pr_debug("sh7372 power domain up 0x%08x -> PSTR = 0x%08x\n",
			 mask, __raw_readl(PSTR));

 out:
	if (ret == 0 && sh7372_pd->resume)
		sh7372_pd->resume();

	return ret;
}

static void sh7372_a4r_suspend(void)
{
	sh7372_intcs_suspend();
	__raw_writel(0x300fffff, WUPRMSK); /* avoid wakeup */
}

static bool pd_active_wakeup(struct device *dev)
{
	return true;
}

static bool sh7372_power_down_forbidden(struct dev_pm_domain *domain)
{
	return false;
}

struct dev_power_governor sh7372_always_on_gov = {
	.power_down_ok = sh7372_power_down_forbidden,
};

void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd)
{
	struct generic_pm_domain *genpd = &sh7372_pd->genpd;

	pm_genpd_init(genpd, NULL, false);
	pm_genpd_init(genpd, sh7372_pd->gov, false);
	genpd->stop_device = pm_clk_suspend;
	genpd->start_device = pm_clk_resume;
	genpd->dev_irq_safe = true;
@@ -175,6 +205,14 @@ struct sh7372_pm_domain sh7372_d4 = {
	.bit_shift = 3,
};

struct sh7372_pm_domain sh7372_a4r = {
	.bit_shift = 5,
	.gov = &sh7372_always_on_gov,
	.suspend = sh7372_a4r_suspend,
	.resume = sh7372_intcs_resume,
	.stay_on = true,
};

struct sh7372_pm_domain sh7372_a3rv = {
	.bit_shift = 6,
};
@@ -183,6 +221,12 @@ struct sh7372_pm_domain sh7372_a3ri = {
	.bit_shift = 8,
};

struct sh7372_pm_domain sh7372_a3sp = {
	.bit_shift = 11,
	.gov = &sh7372_always_on_gov,
	.no_debug = true,
};

struct sh7372_pm_domain sh7372_a3sg = {
	.bit_shift = 13,
};
@@ -422,6 +466,9 @@ void __init sh7372_pm_init(void)
	__raw_writel(0x0000a501, DBGREG9);
	__raw_writel(0x00000000, DBGREG1);

	/* do not convert A3SM, A3SP, A3SG, A4R power down into A4S */
	__raw_writel(0, PDNSEL);

	sh7372_suspend_init();
	sh7372_cpuidle_init();
}
Loading