diff options
Diffstat (limited to 'drivers/mfd/asic3.c')
-rw-r--r-- | drivers/mfd/asic3.c | 83 |
1 files changed, 74 insertions, 9 deletions
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 0b4d5b23bec9..c27fd1fc3b86 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -88,19 +88,19 @@ struct asic3 { static int asic3_gpio_get(struct gpio_chip *chip, unsigned offset); -static inline void asic3_write_register(struct asic3 *asic, - unsigned int reg, u32 value) +void asic3_write_register(struct asic3 *asic, unsigned int reg, u32 value) { iowrite16(value, asic->mapping + (reg >> asic->bus_shift)); } +EXPORT_SYMBOL_GPL(asic3_write_register); -static inline u32 asic3_read_register(struct asic3 *asic, - unsigned int reg) +u32 asic3_read_register(struct asic3 *asic, unsigned int reg) { return ioread16(asic->mapping + (reg >> asic->bus_shift)); } +EXPORT_SYMBOL_GPL(asic3_read_register); static void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set) { @@ -676,7 +676,8 @@ static struct mfd_cell asic3_cell_ds1wm = { .name = "ds1wm", .enable = ds1wm_enable, .disable = ds1wm_disable, - .mfd_data = &ds1wm_pdata, + .platform_data = &ds1wm_pdata, + .pdata_size = sizeof(ds1wm_pdata), .num_resources = ARRAY_SIZE(ds1wm_resources), .resources = ds1wm_resources, }; @@ -777,12 +778,61 @@ static struct mfd_cell asic3_cell_mmc = { .name = "tmio-mmc", .enable = asic3_mmc_enable, .disable = asic3_mmc_disable, - .mfd_data = &asic3_mmc_data, + .platform_data = &asic3_mmc_data, + .pdata_size = sizeof(asic3_mmc_data), .num_resources = ARRAY_SIZE(asic3_mmc_resources), .resources = asic3_mmc_resources, }; +static const int clock_ledn[ASIC3_NUM_LEDS] = { + [0] = ASIC3_CLOCK_LED0, + [1] = ASIC3_CLOCK_LED1, + [2] = ASIC3_CLOCK_LED2, +}; + +static int asic3_leds_enable(struct platform_device *pdev) +{ + const struct mfd_cell *cell = mfd_get_cell(pdev); + struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); + + asic3_clk_enable(asic, &asic->clocks[clock_ledn[cell->id]]); + + return 0; +} + +static int asic3_leds_disable(struct platform_device *pdev) +{ + const struct mfd_cell *cell = mfd_get_cell(pdev); + struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); + + asic3_clk_disable(asic, &asic->clocks[clock_ledn[cell->id]]); + + return 0; +} + +static struct mfd_cell asic3_cell_leds[ASIC3_NUM_LEDS] = { + [0] = { + .name = "leds-asic3", + .id = 0, + .enable = asic3_leds_enable, + .disable = asic3_leds_disable, + }, + [1] = { + .name = "leds-asic3", + .id = 1, + .enable = asic3_leds_enable, + .disable = asic3_leds_disable, + }, + [2] = { + .name = "leds-asic3", + .id = 2, + .enable = asic3_leds_enable, + .disable = asic3_leds_disable, + }, +}; + static int __init asic3_mfd_probe(struct platform_device *pdev, + struct asic3_platform_data *pdata, struct resource *mem) { struct asic3 *asic = platform_get_drvdata(pdev); @@ -806,7 +856,8 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, /* MMC */ asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) + - mem_sdio->start, 0x400 >> asic->bus_shift); + mem_sdio->start, + ASIC3_SD_CONFIG_SIZE >> asic->bus_shift); if (!asic->tmio_cnf) { ret = -ENOMEM; dev_dbg(asic->dev, "Couldn't ioremap SD_CONFIG\n"); @@ -820,9 +871,23 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, if (ret < 0) goto out; - if (mem_sdio && (irq >= 0)) + if (mem_sdio && (irq >= 0)) { ret = mfd_add_devices(&pdev->dev, pdev->id, &asic3_cell_mmc, 1, mem_sdio, irq); + if (ret < 0) + goto out; + } + + if (pdata->leds) { + int i; + + for (i = 0; i < ASIC3_NUM_LEDS; ++i) { + asic3_cell_leds[i].platform_data = &pdata->leds[i]; + asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]); + } + ret = mfd_add_devices(&pdev->dev, 0, + asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0); + } out: return ret; @@ -903,7 +968,7 @@ static int __init asic3_probe(struct platform_device *pdev) */ memcpy(asic->clocks, asic3_clk_init, sizeof(asic3_clk_init)); - asic3_mfd_probe(pdev, mem); + asic3_mfd_probe(pdev, pdata, mem); dev_info(asic->dev, "ASIC3 Core driver\n"); |