Skip to content

Commit 700fa87

Browse files
Boris Brezillonclaudiubeznea
authored andcommitted
HACK (do not mainline): mtd: nand: atmel: Save/restore SMC regs
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com> [claudiu.beznea@microchip.com: conform with latest version of driver] Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
1 parent 998aaa4 commit 700fa87

3 files changed

Lines changed: 58 additions & 16 deletions

File tree

drivers/mtd/nand/atmel/nand-controller.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2525,11 +2525,35 @@ static int atmel_nand_controller_remove(struct platform_device *pdev)
25252525
return nc->caps->ops->remove(nc);
25262526
}
25272527

2528+
static __maybe_unused int atmel_nand_controller_suspend(struct device *dev)
2529+
{
2530+
struct atmel_nand_controller *nc = dev_get_drvdata(dev);
2531+
struct atmel_pmecc *pmecc = nc->pmecc;
2532+
2533+
if (pmecc && pmecc->regs.timing) {
2534+
pmecc->suspend.setup = readl(pmecc->regs.timing);
2535+
pmecc->suspend.pulse = readl(pmecc->regs.timing + 0x4);
2536+
pmecc->suspend.cycle = readl(pmecc->regs.timing + 0x8);
2537+
pmecc->suspend.timings = readl(pmecc->regs.timing + 0xc);
2538+
pmecc->suspend.mode = readl(pmecc->regs.timing + 0x10);
2539+
}
2540+
2541+
return 0;
2542+
}
25282543
static __maybe_unused int atmel_nand_controller_resume(struct device *dev)
25292544
{
25302545
struct atmel_nand_controller *nc = dev_get_drvdata(dev);
2546+
struct atmel_pmecc *pmecc = nc->pmecc;
25312547
struct atmel_nand *nand;
25322548

2549+
if (pmecc && pmecc->regs.timing) {
2550+
writel(pmecc->suspend.setup, pmecc->regs.timing);
2551+
writel(pmecc->suspend.pulse, pmecc->regs.timing + 0x4);
2552+
writel(pmecc->suspend.cycle, pmecc->regs.timing + 0x8);
2553+
writel(pmecc->suspend.timings, pmecc->regs.timing + 0xc);
2554+
writel(pmecc->suspend.mode, pmecc->regs.timing + 0x10);
2555+
}
2556+
25332557
list_for_each_entry(nand, &nc->chips, node) {
25342558
int i;
25352559

@@ -2540,7 +2564,8 @@ static __maybe_unused int atmel_nand_controller_resume(struct device *dev)
25402564
return 0;
25412565
}
25422566

2543-
static SIMPLE_DEV_PM_OPS(atmel_nand_controller_pm_ops, NULL,
2567+
static SIMPLE_DEV_PM_OPS(atmel_nand_controller_pm_ops,
2568+
atmel_nand_controller_suspend,
25442569
atmel_nand_controller_resume);
25452570

25462571
static struct platform_driver atmel_nand_controller_driver = {

drivers/mtd/nand/atmel/pmecc.c

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -148,18 +148,6 @@ struct atmel_pmecc_caps {
148148
bool correct_erased_chunks;
149149
};
150150

151-
struct atmel_pmecc {
152-
struct device *dev;
153-
const struct atmel_pmecc_caps *caps;
154-
155-
struct {
156-
void __iomem *base;
157-
void __iomem *errloc;
158-
} regs;
159-
160-
struct mutex lock;
161-
};
162-
163151
struct atmel_pmecc_user_conf_cache {
164152
u32 cfg;
165153
u32 sarea;
@@ -829,7 +817,8 @@ EXPORT_SYMBOL_GPL(atmel_pmecc_wait_rdy);
829817

830818
static struct atmel_pmecc *atmel_pmecc_create(struct platform_device *pdev,
831819
const struct atmel_pmecc_caps *caps,
832-
int pmecc_res_idx, int errloc_res_idx)
820+
int pmecc_res_idx, int errloc_res_idx,
821+
int timing_res_idx)
833822
{
834823
struct device *dev = &pdev->dev;
835824
struct atmel_pmecc *pmecc;
@@ -853,6 +842,11 @@ static struct atmel_pmecc *atmel_pmecc_create(struct platform_device *pdev,
853842
if (IS_ERR(pmecc->regs.errloc))
854843
return ERR_CAST(pmecc->regs.errloc);
855844

845+
res = platform_get_resource(pdev, IORESOURCE_MEM, timing_res_idx);
846+
pmecc->regs.timing = devm_ioremap_resource(dev, res);
847+
if (IS_ERR(pmecc->regs.timing))
848+
return ERR_CAST(pmecc->regs.timing);
849+
856850
/* Disable all interrupts before registering the PMECC handler. */
857851
writel(0xffffffff, pmecc->regs.base + ATMEL_PMECC_IDR);
858852

@@ -960,7 +954,7 @@ struct atmel_pmecc *devm_atmel_pmecc_get(struct device *userdev)
960954
if (match && match->data)
961955
caps = match->data;
962956

963-
pmecc = atmel_pmecc_create(pdev, caps, 1, 2);
957+
pmecc = atmel_pmecc_create(pdev, caps, 1, 2, 4);
964958
}
965959

966960
return pmecc;
@@ -987,7 +981,7 @@ static int atmel_pmecc_probe(struct platform_device *pdev)
987981
return -EINVAL;
988982
}
989983

990-
pmecc = atmel_pmecc_create(pdev, caps, 0, 1);
984+
pmecc = atmel_pmecc_create(pdev, caps, 0, 1, 2);
991985
if (IS_ERR(pmecc))
992986
return PTR_ERR(pmecc);
993987

drivers/mtd/nand/atmel/pmecc.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,29 @@ struct atmel_pmecc_user_req {
5454
} ecc;
5555
};
5656

57+
struct atmel_pmecc_suspend_ctx {
58+
u32 setup;
59+
u32 pulse;
60+
u32 cycle;
61+
u32 timings;
62+
u32 mode;
63+
};
64+
65+
struct atmel_pmecc {
66+
struct device *dev;
67+
const struct atmel_pmecc_caps *caps;
68+
69+
struct {
70+
void __iomem *base;
71+
void __iomem *errloc;
72+
void __iomem *timing;
73+
} regs;
74+
75+
struct mutex lock;
76+
77+
struct atmel_pmecc_suspend_ctx suspend;
78+
};
79+
5780
struct atmel_pmecc *devm_atmel_pmecc_get(struct device *dev);
5881

5982
struct atmel_pmecc_user *

0 commit comments

Comments
 (0)