#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
-#include <linux/wait.h>
#include <linux/platform_device.h>
#include <linux/kernel_stat.h>
#include <linux/spinlock.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/glamo.h>
+#include <linux/spi/glamo.h>
+#include <linux/glamo-gpio.h>
#include <linux/glamofb.h>
-#include <linux/mmc/mmc.h>
-#include <linux/mmc/host.h>
+#include <linux/io.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
#include <asm/div64.h>
-//#include <mach/regs-irq.h>
-
-#ifdef CONFIG_PM
#include <linux/pm.h>
-#endif
#include "glamo-regs.h"
#include "glamo-core.h"
-#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
-
#define GLAMO_MEM_REFRESH_COUNT 0x100
-
/*
* Glamo internal settings
*
char *name;
char dump;
};
+
struct reg_range reg_range[] = {
{ 0x0000, 0x76, "General", 1 },
- { 0x0200, 0x16, "Host Bus", 1 },
+ { 0x0200, 0x18, "Host Bus", 1 },
{ 0x0300, 0x38, "Memory", 1 },
/* { 0x0400, 0x100, "Sensor", 0 }, */
/* { 0x0500, 0x300, "ISP", 0 }, */
/* { 0x0c00, 0xcc, "MPEG", 0 }, */
{ 0x1100, 0xb2, "LCD 1", 1 },
{ 0x1200, 0x64, "LCD 2", 1 },
- { 0x1400, 0x40, "MMC", 1 },
+ { 0x1400, 0x42, "MMC", 1 },
/* { 0x1500, 0x080, "MPU 0", 0 },
{ 0x1580, 0x080, "MPU 1", 0 },
{ 0x1600, 0x080, "Cmd Queue", 0 },
- { 0x1680, 0x080, "RISC CPU", 0 },
+ { 0x1680, 0x080, "RISC CPU", 0 },*/
{ 0x1700, 0x400, "2D Unit", 0 },
- { 0x1b00, 0x900, "3D Unit", 0 }, */
+/* { 0x1b00, 0x900, "3D Unit", 0 }, */
};
-static struct glamo_core *glamo_handle;
-
static inline void __reg_write(struct glamo_core *glamo,
u_int16_t reg, u_int16_t val)
{
__reg_set_bit_mask(glamo, reg, bit, 0);
}
-static inline void glamo_vmem_write(struct glamo_core *glamo, u_int32_t addr,
- u_int16_t *src, int len)
-{
- if (addr & 0x0001 || (unsigned long)src & 0x0001 || len & 0x0001) {
- dev_err(&glamo->pdev->dev, "unaligned write(0x%08x, 0x%p, "
- "0x%x)!!\n", addr, src, len);
- }
-
-}
-
-static inline void glamo_vmem_read(struct glamo_core *glamo, u_int16_t *buf,
- u_int32_t addr, int len)
-{
- if (addr & 0x0001 || (unsigned long) buf & 0x0001 || len & 0x0001) {
- dev_err(&glamo->pdev->dev, "unaligned read(0x%p, 0x08%x, "
- "0x%x)!!\n", buf, addr, len);
- }
-
-
-}
-
/***********************************************************************
* resources of sibling devices
***********************************************************************/
-#if 0
-static struct resource glamo_core_resources[] = {
- {
- .start = GLAMO_REGOFS_GENERIC,
- .end = GLAMO_REGOFS_GENERIC + 0x400,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 0,
- .end = 0,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device glamo_core_dev = {
- .name = "glamo-core",
- .resource = &glamo_core_resources,
- .num_resources = ARRAY_SIZE(glamo_core_resources),
-};
-#endif
-
-static struct resource glamo_jpeg_resources[] = {
- {
- .start = GLAMO_REGOFS_JPEG,
- .end = GLAMO_REGOFS_MPEG - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = IRQ_GLAMO_JPEG,
- .end = IRQ_GLAMO_JPEG,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device glamo_jpeg_dev = {
- .name = "glamo-jpeg",
- .resource = glamo_jpeg_resources,
- .num_resources = ARRAY_SIZE(glamo_jpeg_resources),
-};
-
-static struct resource glamo_mpeg_resources[] = {
- {
- .start = GLAMO_REGOFS_MPEG,
- .end = GLAMO_REGOFS_LCD - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = IRQ_GLAMO_MPEG,
- .end = IRQ_GLAMO_MPEG,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device glamo_mpeg_dev = {
- .name = "glamo-mpeg",
- .resource = glamo_mpeg_resources,
- .num_resources = ARRAY_SIZE(glamo_mpeg_resources),
-};
-
-static struct resource glamo_2d_resources[] = {
- {
- .start = GLAMO_REGOFS_2D,
- .end = GLAMO_REGOFS_3D - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = IRQ_GLAMO_2D,
- .end = IRQ_GLAMO_2D,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device glamo_2d_dev = {
- .name = "glamo-2d",
- .resource = glamo_2d_resources,
- .num_resources = ARRAY_SIZE(glamo_2d_resources),
-};
-
-static struct resource glamo_3d_resources[] = {
- {
- .start = GLAMO_REGOFS_3D,
- .end = GLAMO_REGOFS_END - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct platform_device glamo_3d_dev = {
- .name = "glamo-3d",
- .resource = glamo_3d_resources,
- .num_resources = ARRAY_SIZE(glamo_3d_resources),
-};
-
-static struct platform_device glamo_spigpio_dev = {
- .name = "glamo-spi-gpio",
-};
-
static struct resource glamo_fb_resources[] = {
- /* FIXME: those need to be incremented by parent base */
{
.name = "glamo-fb-regs",
.start = GLAMO_REGOFS_LCD,
},
};
-static struct platform_device glamo_fb_dev = {
- .name = "glamo-fb",
- .resource = glamo_fb_resources,
- .num_resources = ARRAY_SIZE(glamo_fb_resources),
-};
-
static struct resource glamo_mmc_resources[] = {
{
- /* FIXME: those need to be incremented by parent base */
.start = GLAMO_REGOFS_MMC,
.end = GLAMO_REGOFS_MPROC0 - 1,
.flags = IORESOURCE_MEM
},
};
-struct glamo_mci_pdata glamo_mci_def_pdata = {
- .gpio_detect = 0,
- .glamo_can_set_mci_power = NULL, /* filled in from MFD platform data */
- .ocr_avail = MMC_VDD_20_21 |
- MMC_VDD_21_22 |
- MMC_VDD_22_23 |
- MMC_VDD_23_24 |
- MMC_VDD_24_25 |
- MMC_VDD_25_26 |
- MMC_VDD_26_27 |
- MMC_VDD_27_28 |
- MMC_VDD_28_29 |
- MMC_VDD_29_30 |
- MMC_VDD_30_31 |
- MMC_VDD_32_33,
- .glamo_irq_is_wired = NULL, /* filled in from MFD platform data */
- .mci_suspending = NULL, /* filled in from MFD platform data */
- .mci_all_dependencies_resumed = NULL, /* filled in from MFD platform data */
+enum glamo_cells {
+ GLAMO_CELL_FB,
+ GLAMO_CELL_MMC,
+ GLAMO_CELL_GPIO,
};
-EXPORT_SYMBOL_GPL(glamo_mci_def_pdata);
-
+static struct mfd_cell glamo_cells[] = {
+ [GLAMO_CELL_FB] = {
+ .name = "glamo-fb",
+ .num_resources = ARRAY_SIZE(glamo_fb_resources),
+ .resources = glamo_fb_resources,
+ },
+ [GLAMO_CELL_MMC] = {
+ .name = "glamo-mci",
+ .num_resources = ARRAY_SIZE(glamo_mmc_resources),
+ .resources = glamo_mmc_resources,
+ },
+ [GLAMO_CELL_GPIO] = {
+ .name = "glamo-gpio",
+ },
+};
-static void mangle_mem_resources(struct resource *res, int num_res,
- struct resource *parent)
-{
- int i;
-
- for (i = 0; i < num_res; i++) {
- if (res[i].flags != IORESOURCE_MEM)
- continue;
- res[i].start += parent->start;
- res[i].end += parent->start;
- res[i].parent = parent;
- }
-}
/***********************************************************************
* IRQ demultiplexer
static void glamo_ack_irq(unsigned int irq)
{
+ struct glamo_core *glamo = (struct glamo_core*)get_irq_chip_data(irq);
/* clear interrupt source */
- __reg_write(glamo_handle, GLAMO_REG_IRQ_CLEAR,
+ __reg_write(glamo, GLAMO_REG_IRQ_CLEAR,
1 << irq2glamo(irq));
}
static void glamo_mask_irq(unsigned int irq)
{
+ struct glamo_core *glamo = (struct glamo_core*)get_irq_chip_data(irq);
u_int16_t tmp;
/* clear bit in enable register */
- tmp = __reg_read(glamo_handle, GLAMO_REG_IRQ_ENABLE);
+ tmp = __reg_read(glamo, GLAMO_REG_IRQ_ENABLE);
tmp &= ~(1 << irq2glamo(irq));
- __reg_write(glamo_handle, GLAMO_REG_IRQ_ENABLE, tmp);
+ __reg_write(glamo, GLAMO_REG_IRQ_ENABLE, tmp);
}
static void glamo_unmask_irq(unsigned int irq)
{
+ struct glamo_core *glamo = (struct glamo_core*)get_irq_chip_data(irq);
u_int16_t tmp;
/* set bit in enable register */
- tmp = __reg_read(glamo_handle, GLAMO_REG_IRQ_ENABLE);
+ tmp = __reg_read(glamo, GLAMO_REG_IRQ_ENABLE);
tmp |= (1 << irq2glamo(irq));
- __reg_write(glamo_handle, GLAMO_REG_IRQ_ENABLE, tmp);
+ __reg_write(glamo, GLAMO_REG_IRQ_ENABLE, tmp);
}
static struct irq_chip glamo_irq_chip = {
+ .name = "glamo",
.ack = glamo_ack_irq,
.mask = glamo_mask_irq,
.unmask = glamo_unmask_irq,
static void glamo_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
{
+ struct glamo_core *glamo = get_irq_desc_chip_data(desc);
desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
if (unlikely(desc->status & IRQ_INPROGRESS)) {
desc->chip->ack(irq);
return;
}
- kstat_incr_irqs_this_cpu(irq, desc);
+ kstat_incr_irqs_this_cpu(irq, desc);
desc->chip->ack(irq);
desc->status |= IRQ_INPROGRESS;
desc->status &= ~IRQ_PENDING;
/* read IRQ status register */
- irqstatus = __reg_read(glamo_handle, GLAMO_REG_IRQ_STATUS);
+ irqstatus = __reg_read(glamo, GLAMO_REG_IRQ_STATUS);
for (i = 0; i < 9; i++)
if (irqstatus & (1 << i))
desc_handle_irq(IRQ_GLAMO(i),
GLAMO_CLOCK_MMC_EN_M9CLK |
GLAMO_CLOCK_MMC_EN_TCLK |
GLAMO_CLOCK_MMC_DG_M9CLK |
- GLAMO_CLOCK_MMC_DG_TCLK, 0xffff);
+ GLAMO_CLOCK_MMC_DG_TCLK,
+ 0xffff);
/* enable the TCLK divider clk input */
__reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
GLAMO_CLOCK_GEN51_EN_DIV_TCLK,
__reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
GLAMO_HOSTBUS2_MMIO_EN_2D,
GLAMO_HOSTBUS2_MMIO_EN_2D);
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_GCLK,
+ 0xffff);
break;
case GLAMO_ENGINE_CMDQ:
__reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_2D,
__reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
GLAMO_HOSTBUS2_MMIO_EN_CQ,
GLAMO_HOSTBUS2_MMIO_EN_CQ);
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_MCLK,
+ 0xffff);
break;
/* FIXME: Implementation */
default:
- break;
+ return -EINVAL;
}
glamo->engine_enabled_bitfield |= 1 << engine;
break;
case GLAMO_ENGINE_MMC:
-// __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MMC,
-// GLAMO_CLOCK_MMC_EN_M9CLK |
-// GLAMO_CLOCK_MMC_EN_TCLK |
-// GLAMO_CLOCK_MMC_DG_M9CLK |
-// GLAMO_CLOCK_MMC_DG_TCLK, 0);
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MMC,
+ GLAMO_CLOCK_MMC_EN_M9CLK |
+ GLAMO_CLOCK_MMC_EN_TCLK |
+ GLAMO_CLOCK_MMC_DG_M9CLK |
+ GLAMO_CLOCK_MMC_DG_TCLK, 0);
/* disable the TCLK divider clk input */
-// __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
-// GLAMO_CLOCK_GEN51_EN_DIV_TCLK, 0);
-
- default:
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_TCLK, 0);
+ break;
+ case GLAMO_ENGINE_CMDQ:
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_2D,
+ GLAMO_CLOCK_2D_EN_M6CLK,
+ 0);
+ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_CQ,
+ GLAMO_HOSTBUS2_MMIO_EN_CQ);
+/* __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_MCLK,
+ 0);*/
+ break;
+ case GLAMO_ENGINE_2D:
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_2D,
+ GLAMO_CLOCK_2D_EN_M7CLK |
+ GLAMO_CLOCK_2D_EN_GCLK |
+ GLAMO_CLOCK_2D_DG_M7CLK |
+ GLAMO_CLOCK_2D_DG_GCLK,
+ 0);
+ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_2D,
+ GLAMO_HOSTBUS2_MMIO_EN_2D);
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_GCLK,
+ 0);
break;
+ default:
+ return -EINVAL;
}
glamo->engine_enabled_bitfield &= ~(1 << engine);
}
EXPORT_SYMBOL_GPL(glamo_engine_clkreg_get);
-struct glamo_script reset_regs[] = {
+static const struct glamo_script engine_div_regs[__NUM_GLAMO_ENGINES] = {
+ [GLAMO_ENGINE_LCD] = {GLAMO_REG_CLOCK_GEN5_1, GLAMO_CLOCK_GEN51_EN_DIV_DCLK},
+ [GLAMO_ENGINE_MMC] = {GLAMO_REG_CLOCK_GEN5_1, GLAMO_CLOCK_GEN51_EN_DIV_TCLK},
+ [GLAMO_ENGINE_2D] = {GLAMO_REG_CLOCK_GEN5_1, GLAMO_CLOCK_GEN51_EN_DIV_GCLK},
+};
+
+void glamo_engine_div_enable(struct glamo_core *glamo, enum glamo_engine engine)
+{
+ uint16_t reg = engine_div_regs[engine].reg;
+ uint16_t bit = engine_div_regs[engine].val;
+ uint16_t val;
+
+ spin_lock(&glamo->lock);
+ val = __reg_read(glamo, reg);
+ __reg_write(glamo, reg, val | bit);
+ spin_unlock(&glamo->lock);
+ mdelay(5);
+}
+EXPORT_SYMBOL_GPL(glamo_engine_div_enable);
+
+void glamo_engine_div_disable(struct glamo_core *glamo, enum glamo_engine engine)
+{
+ uint16_t reg = engine_div_regs[engine].reg;
+ uint16_t bit = engine_div_regs[engine].val;
+ uint16_t val;
+
+ spin_lock(&glamo->lock);
+ val = __reg_read(glamo, reg);
+ __reg_write(glamo, reg, val & ~bit);
+ spin_unlock(&glamo->lock);
+}
+EXPORT_SYMBOL_GPL(glamo_engine_div_disable);
+
+static const struct glamo_script reset_regs[] = {
[GLAMO_ENGINE_LCD] = {
GLAMO_REG_CLOCK_LCD, GLAMO_CLOCK_LCD_RESET
},
[GLAMO_ENGINE_MMC] = {
GLAMO_REG_CLOCK_MMC, GLAMO_CLOCK_MMC_RESET
},
+ [GLAMO_ENGINE_CMDQ] = {
+ GLAMO_REG_CLOCK_2D, GLAMO_CLOCK_2D_CQ_RESET
+ },
[GLAMO_ENGINE_2D] = {
GLAMO_REG_CLOCK_2D, GLAMO_CLOCK_2D_RESET
},
void glamo_engine_reset(struct glamo_core *glamo, enum glamo_engine engine)
{
- struct glamo_script *rst;
+ uint16_t reg = reset_regs[engine].reg;
+ uint16_t val = reset_regs[engine].val;
if (engine >= ARRAY_SIZE(reset_regs)) {
dev_warn(&glamo->pdev->dev, "unknown engine %u ", engine);
return;
}
- rst = &reset_regs[engine];
spin_lock(&glamo->lock);
- __reg_set_bit(glamo, rst->reg, rst->val);
- __reg_clear_bit(glamo, rst->reg, rst->val);
+ __reg_set_bit(glamo, reg, val);
+ __reg_clear_bit(glamo, reg, val);
spin_unlock(&glamo->lock);
}
EXPORT_SYMBOL_GPL(glamo_engine_reset);
-void glamo_lcm_reset(int level)
-{
- if (!glamo_handle)
- return;
-
- glamo_gpio_setpin(glamo_handle, GLAMO_GPIO4, level);
- glamo_gpio_cfgpin(glamo_handle, GLAMO_GPIO4_OUTPUT);
-
-}
-EXPORT_SYMBOL_GPL(glamo_lcm_reset);
-
-enum glamo_pll {
- GLAMO_PLL1,
- GLAMO_PLL2,
-};
-
-static int glamo_pll_rate(struct glamo_core *glamo,
+int glamo_pll_rate(struct glamo_core *glamo,
enum glamo_pll pll)
{
u_int16_t reg;
- unsigned int div = 512;
- /* FIXME: move osci into platform_data */
- unsigned int osci = 32768;
-
- if (osci == 32768)
- div = 1;
+ unsigned int osci = glamo->pdata->osci_clock_rate;
switch (pll) {
case GLAMO_PLL1:
default:
return -EINVAL;
}
- return (osci/div)*reg;
+ return osci*reg;
}
+EXPORT_SYMBOL_GPL(glamo_pll_rate);
int glamo_engine_reclock(struct glamo_core *glamo,
enum glamo_engine engine,
- int ps)
+ int hz)
{
- int pll, khz;
- u_int16_t reg, mask, val = 0;
+ int pll;
+ u_int16_t reg, mask, div;
- if (!ps)
- return 0;
+ if (!hz)
+ return -EINVAL;
switch (engine) {
case GLAMO_ENGINE_LCD:
reg = GLAMO_REG_CLOCK_GEN7;
mask = 0xff;
break;
+ case GLAMO_ENGINE_MMC:
+ pll = GLAMO_PLL1;
+ reg = GLAMO_REG_CLOCK_GEN8;
+ mask = 0xff;
+ break;
default:
dev_warn(&glamo->pdev->dev,
"reclock of engine 0x%x not supported\n", engine);
}
pll = glamo_pll_rate(glamo, pll);
- khz = 1000000000UL / ps;
- if (khz)
- val = (pll / khz) / 1000;
+ div = pll / hz;
+
+ if (div != 0 && pll / div <= hz)
+ --div;
+
+ if (div > mask)
+ div = mask;
dev_dbg(&glamo->pdev->dev,
- "PLL %d, kHZ %d, div %d\n", pll, khz, val);
+ "PLL %d, kHZ %d, div %d\n", pll, hz / 1000, div);
- if (val) {
- val--;
- reg_set_bit_mask(glamo, reg, mask, val);
- mdelay(5); /* wait some time to stabilize */
+ reg_set_bit_mask(glamo, reg, mask, div);
+ mdelay(5); /* wait some time to stabilize */
- return 0;
- } else {
- return -EINVAL;
- }
+ return pll / (div + 1);
}
EXPORT_SYMBOL_GPL(glamo_engine_reclock);
* script support
***********************************************************************/
-int glamo_run_script(struct glamo_core *glamo, struct glamo_script *script,
+int glamo_run_script(struct glamo_core *glamo, const struct glamo_script *script,
int len, int may_sleep)
{
int i;
+ const struct glamo_script *line = script;
- for (i = 0; i < len; i++) {
- struct glamo_script *line = &script[i];
-
+ for (i = 0; i < len; ++i, ++line) {
switch (line->reg) {
case 0xffff:
return 0;
}
EXPORT_SYMBOL(glamo_run_script);
-static struct glamo_script glamo_init_script[] = {
+static const struct glamo_script glamo_init_script[] = {
{ GLAMO_REG_CLOCK_HOST, 0x1000 },
{ 0xfffe, 2 },
{ GLAMO_REG_CLOCK_MEMORY, 0x1000 },
{ GLAMO_REG_MEM_DRAM1, 0xe100 },
{ GLAMO_REG_MEM_DRAM2, 0x01d6 },
{ GLAMO_REG_CLOCK_MEMORY, 0x000b },
- { GLAMO_REG_GPIO_GEN1, 0x000f },
- { GLAMO_REG_GPIO_GEN2, 0x111e },
- { GLAMO_REG_GPIO_GEN3, 0xccc3 },
- { GLAMO_REG_GPIO_GEN4, 0x111e },
- { GLAMO_REG_GPIO_GEN5, 0x000f },
};
#if 0
static struct glamo_script glamo_resume_script[] = {
{
int n;
unsigned long flags;
-
+
spin_lock_irqsave(&glamo->lock, flags);
dev_info(&glamo->pdev->dev, "***** glamo_power -> %d\n", new_state);
{
int rc = 0, irq;
struct glamo_core *glamo;
- struct platform_device *glamo_mmc_dev;
-
- if (glamo_handle) {
- dev_err(&pdev->dev,
- "This driver supports only one instance\n");
- return -EBUSY;
- }
glamo = kmalloc(GFP_KERNEL, sizeof(*glamo));
if (!glamo)
return -ENOMEM;
spin_lock_init(&glamo->lock);
- glamo_handle = glamo;
glamo->pdev = pdev;
glamo->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
glamo->irq = platform_get_irq(pdev, 0);
/* register a number of sibling devices whoise IOMEM resources
* are siblings of pdev's IOMEM resource */
-#if 0
- glamo_core_dev.dev.parent = &pdev.dev;
- mangle_mem_resources(glamo_core_dev.resources,
- glamo_core_dev.num_resources, glamo->mem);
- glamo_core_dev.resources[1].start = glamo->irq;
- glamo_core_dev.resources[1].end = glamo->irq;
- platform_device_register(&glamo_core_dev);
-#endif
+
/* only remap the generic, hostbus and memory controller registers */
glamo->base = ioremap(glamo->mem->start, 0x4000 /*GLAMO_REGOFS_VIDCAP*/);
if (!glamo->base) {
*/
for (irq = IRQ_GLAMO(0); irq <= IRQ_GLAMO(8); irq++) {
- set_irq_chip(irq, &glamo_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ set_irq_chip_and_handler(irq, &glamo_irq_chip, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
+ set_irq_chip_data(irq, glamo);
}
if (glamo->pdata->glamo_irq_is_wired &&
!glamo->pdata->glamo_irq_is_wired()) {
set_irq_chained_handler(glamo->irq, glamo_irq_demux_handler);
set_irq_type(glamo->irq, IRQ_TYPE_EDGE_FALLING);
+ set_irq_chip_data(glamo->irq, glamo);
dev_info(&pdev->dev, "Glamo interrupt registered\n");
glamo->irq_works = 1;
} else {
glamo->irq_works = 0;
}
-
/* confirm it isn't insane version */
if (!glamo_supported(glamo)) {
dev_err(&pdev->dev, "This Glamo is not supported\n");
glamo_pll_rate(glamo, GLAMO_PLL1),
glamo_pll_rate(glamo, GLAMO_PLL2));
- /* bring MCI specific stuff over from our MFD platform data */
- glamo_mci_def_pdata.glamo_can_set_mci_power =
- glamo->pdata->glamo_can_set_mci_power;
- glamo_mci_def_pdata.glamo_mci_use_slow =
- glamo->pdata->glamo_mci_use_slow;
- glamo_mci_def_pdata.glamo_irq_is_wired =
- glamo->pdata->glamo_irq_is_wired;
-
- /* start creating the siblings */
-
- glamo_2d_dev.dev.parent = &pdev->dev;
- mangle_mem_resources(glamo_2d_dev.resource,
- glamo_2d_dev.num_resources, glamo->mem);
- platform_device_register(&glamo_2d_dev);
-
- glamo_3d_dev.dev.parent = &pdev->dev;
- mangle_mem_resources(glamo_3d_dev.resource,
- glamo_3d_dev.num_resources, glamo->mem);
- platform_device_register(&glamo_3d_dev);
-
- glamo_jpeg_dev.dev.parent = &pdev->dev;
- mangle_mem_resources(glamo_jpeg_dev.resource,
- glamo_jpeg_dev.num_resources, glamo->mem);
- platform_device_register(&glamo_jpeg_dev);
-
- glamo_mpeg_dev.dev.parent = &pdev->dev;
- mangle_mem_resources(glamo_mpeg_dev.resource,
- glamo_mpeg_dev.num_resources, glamo->mem);
- platform_device_register(&glamo_mpeg_dev);
-
- glamo->pdata->glamo = glamo;
- glamo_fb_dev.dev.parent = &pdev->dev;
- glamo_fb_dev.dev.platform_data = glamo->pdata;
- mangle_mem_resources(glamo_fb_dev.resource,
- glamo_fb_dev.num_resources, glamo->mem);
- platform_device_register(&glamo_fb_dev);
-
- glamo->pdata->spigpio_info->glamo = glamo;
- glamo_spigpio_dev.dev.parent = &pdev->dev;
- glamo_spigpio_dev.dev.platform_data = glamo->pdata->spigpio_info;
- platform_device_register(&glamo_spigpio_dev);
-
- glamo_mmc_dev = glamo->pdata->mmc_dev;
- glamo_mmc_dev->name = "glamo-mci";
- glamo_mmc_dev->dev.parent = &pdev->dev;
- glamo_mmc_dev->resource = glamo_mmc_resources;
- glamo_mmc_dev->num_resources = ARRAY_SIZE(glamo_mmc_resources);
-
- /* we need it later to give to the engine enable and disable */
- glamo_mci_def_pdata.pglamo = glamo;
- mangle_mem_resources(glamo_mmc_dev->resource,
- glamo_mmc_dev->num_resources, glamo->mem);
- platform_device_register(glamo_mmc_dev);
+ /* register siblings */
+ glamo->pdata->mmc_data->core = glamo;
+ glamo_cells[GLAMO_CELL_MMC].platform_data = glamo->pdata->mmc_data;
+ glamo_cells[GLAMO_CELL_MMC].data_size =
+ sizeof(struct glamo_mmc_platform_data);
+
+ glamo->pdata->fb_data->core = glamo;
+ glamo_cells[GLAMO_CELL_FB].platform_data = glamo->pdata->fb_data;
+ glamo_cells[GLAMO_CELL_FB].data_size = sizeof(struct glamo_fb_platform_data);
+
+ mfd_add_devices(&pdev->dev, pdev->id, glamo_cells,
+ ARRAY_SIZE(glamo_cells),
+ glamo->mem, 0);
/* only request the generic, hostbus and memory controller MMIO */
glamo->mem = request_mem_region(glamo->mem->start,
bail_irq:
disable_irq(glamo->irq);
set_irq_chained_handler(glamo->irq, NULL);
+ set_irq_chip_data(glamo->irq, NULL);
for (irq = IRQ_GLAMO(0); irq <= IRQ_GLAMO(8); irq++) {
set_irq_flags(irq, 0);
set_irq_chip(irq, NULL);
+ set_irq_chip_data(irq, NULL);
}
iounmap(glamo->base);
bail_free:
platform_set_drvdata(pdev, NULL);
- glamo_handle = NULL;
kfree(glamo);
return rc;
disable_irq(glamo->irq);
set_irq_chained_handler(glamo->irq, NULL);
+ set_irq_chip_data(glamo->irq, NULL);
for (irq = IRQ_GLAMO(0); irq <= IRQ_GLAMO(8); irq++) {
set_irq_flags(irq, 0);
set_irq_chip(irq, NULL);
+ set_irq_chip_data(irq, NULL);
}
platform_set_drvdata(pdev, NULL);
- platform_device_unregister(&glamo_fb_dev);
- platform_device_unregister(glamo->pdata->mmc_dev);
+ mfd_remove_devices(&pdev->dev);
iounmap(glamo->base);
release_mem_region(glamo->mem->start, GLAMO_REGOFS_VIDCAP);
- glamo_handle = NULL;
kfree(glamo);
return 0;
#ifdef CONFIG_PM
-static int glamo_suspend(struct platform_device *pdev, pm_message_t state)
+static int glamo_suspend(struct device *dev)
{
- glamo_handle->suspending = 1;
- glamo_power(glamo_handle, GLAMO_POWER_SUSPEND);
+ struct glamo_core *glamo = dev_get_drvdata(dev);
+ glamo->suspending = 1;
+ glamo_power(glamo, GLAMO_POWER_SUSPEND);
return 0;
}
-static int glamo_resume(struct platform_device *pdev)
+static int glamo_resume(struct device *dev)
{
- glamo_power(glamo_handle, GLAMO_POWER_ON);
- glamo_handle->suspending = 0;
-
+ struct glamo_core *glamo = dev_get_drvdata(dev);
+ glamo_power(glamo, GLAMO_POWER_ON);
+ glamo->suspending = 0;
return 0;
}
+static struct dev_pm_ops glamo_pm_ops = {
+ .suspend = glamo_suspend,
+ .resume = glamo_resume,
+};
+
+#define GLAMO_PM_OPS (&glamo_pm_ops)
+
#else
-#define glamo_suspend NULL
-#define glamo_resume NULL
+#define GLAMO_PM_OPS NULL
#endif
static struct platform_driver glamo_driver = {
.probe = glamo_probe,
.remove = glamo_remove,
- .suspend = glamo_suspend,
- .resume = glamo_resume,
.driver = {
.name = "glamo3362",
.owner = THIS_MODULE,
+ .pm = GLAMO_PM_OPS,
},
};