123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- #include <linux/pm_domain.h>
- #include <linux/slab.h>
- #include <linux/io.h>
- #include "clk.h"
- #define to_mmp_pm_domain(genpd) container_of(genpd, struct mmp_pm_domain, genpd)
- struct mmp_pm_domain {
- struct generic_pm_domain genpd;
- void __iomem *reg;
- spinlock_t *lock;
- u32 power_on;
- u32 reset;
- u32 clock_enable;
- unsigned int flags;
- };
- static int mmp_pm_domain_power_on(struct generic_pm_domain *genpd)
- {
- struct mmp_pm_domain *pm_domain = to_mmp_pm_domain(genpd);
- unsigned long flags = 0;
- u32 val;
- if (pm_domain->lock)
- spin_lock_irqsave(pm_domain->lock, flags);
- val = readl(pm_domain->reg);
-
- val |= pm_domain->power_on;
- writel(val, pm_domain->reg);
-
- val |= 0x100;
- writel(val, pm_domain->reg);
-
- if (pm_domain->reset || pm_domain->clock_enable) {
- u32 after_power_on = val;
- val &= ~pm_domain->reset;
- writel(val, pm_domain->reg);
- val |= pm_domain->clock_enable;
- writel(val, pm_domain->reg);
- val |= pm_domain->reset;
- writel(val, pm_domain->reg);
- writel(after_power_on, pm_domain->reg);
- }
- if (pm_domain->lock)
- spin_unlock_irqrestore(pm_domain->lock, flags);
- return 0;
- }
- static int mmp_pm_domain_power_off(struct generic_pm_domain *genpd)
- {
- struct mmp_pm_domain *pm_domain = to_mmp_pm_domain(genpd);
- unsigned long flags = 0;
- u32 val;
- if (pm_domain->flags & MMP_PM_DOMAIN_NO_DISABLE)
- return 0;
- if (pm_domain->lock)
- spin_lock_irqsave(pm_domain->lock, flags);
-
- val = readl(pm_domain->reg);
- val &= ~pm_domain->power_on;
- val &= ~0x100;
- writel(val, pm_domain->reg);
- if (pm_domain->lock)
- spin_unlock_irqrestore(pm_domain->lock, flags);
- return 0;
- }
- struct generic_pm_domain *mmp_pm_domain_register(const char *name,
- void __iomem *reg,
- u32 power_on, u32 reset, u32 clock_enable,
- unsigned int flags, spinlock_t *lock)
- {
- struct mmp_pm_domain *pm_domain;
- pm_domain = kzalloc(sizeof(*pm_domain), GFP_KERNEL);
- if (!pm_domain)
- return ERR_PTR(-ENOMEM);
- pm_domain->reg = reg;
- pm_domain->power_on = power_on;
- pm_domain->reset = reset;
- pm_domain->clock_enable = clock_enable;
- pm_domain->flags = flags;
- pm_domain->lock = lock;
- pm_genpd_init(&pm_domain->genpd, NULL, true);
- pm_domain->genpd.name = name;
- pm_domain->genpd.power_on = mmp_pm_domain_power_on;
- pm_domain->genpd.power_off = mmp_pm_domain_power_off;
- return &pm_domain->genpd;
- }
|