cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tc6393xb.c (24077B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Toshiba TC6393XB SoC support
      4 *
      5 * Copyright(c) 2005-2006 Chris Humbert
      6 * Copyright(c) 2005 Dirk Opfer
      7 * Copyright(c) 2005 Ian Molton <spyro@f2s.com>
      8 * Copyright(c) 2007 Dmitry Baryshkov
      9 *
     10 * Based on code written by Sharp/Lineo for 2.4 kernels
     11 * Based on locomo.c
     12 */
     13
     14#include <linux/kernel.h>
     15#include <linux/module.h>
     16#include <linux/io.h>
     17#include <linux/irq.h>
     18#include <linux/platform_device.h>
     19#include <linux/clk.h>
     20#include <linux/err.h>
     21#include <linux/mfd/core.h>
     22#include <linux/mfd/tmio.h>
     23#include <linux/mfd/tc6393xb.h>
     24#include <linux/gpio/driver.h>
     25#include <linux/gpio/machine.h>
     26#include <linux/gpio/consumer.h>
     27#include <linux/slab.h>
     28
     29#define SCR_REVID	0x08		/* b Revision ID	*/
     30#define SCR_ISR		0x50		/* b Interrupt Status	*/
     31#define SCR_IMR		0x52		/* b Interrupt Mask	*/
     32#define SCR_IRR		0x54		/* b Interrupt Routing	*/
     33#define SCR_GPER	0x60		/* w GP Enable		*/
     34#define SCR_GPI_SR(i)	(0x64 + (i))	/* b3 GPI Status	*/
     35#define SCR_GPI_IMR(i)	(0x68 + (i))	/* b3 GPI INT Mask	*/
     36#define SCR_GPI_EDER(i)	(0x6c + (i))	/* b3 GPI Edge Detect Enable */
     37#define SCR_GPI_LIR(i)	(0x70 + (i))	/* b3 GPI Level Invert	*/
     38#define SCR_GPO_DSR(i)	(0x78 + (i))	/* b3 GPO Data Set	*/
     39#define SCR_GPO_DOECR(i) (0x7c + (i))	/* b3 GPO Data OE Control */
     40#define SCR_GP_IARCR(i)	(0x80 + (i))	/* b3 GP Internal Active Register Control */
     41#define SCR_GP_IARLCR(i) (0x84 + (i))	/* b3 GP INTERNAL Active Register Level Control */
     42#define SCR_GPI_BCR(i)	(0x88 + (i))	/* b3 GPI Buffer Control */
     43#define SCR_GPA_IARCR	0x8c		/* w GPa Internal Active Register Control */
     44#define SCR_GPA_IARLCR	0x90		/* w GPa Internal Active Register Level Control */
     45#define SCR_GPA_BCR	0x94		/* w GPa Buffer Control */
     46#define SCR_CCR		0x98		/* w Clock Control	*/
     47#define SCR_PLL2CR	0x9a		/* w PLL2 Control	*/
     48#define SCR_PLL1CR	0x9c		/* l PLL1 Control	*/
     49#define SCR_DIARCR	0xa0		/* b Device Internal Active Register Control */
     50#define SCR_DBOCR	0xa1		/* b Device Buffer Off Control */
     51#define SCR_FER		0xe0		/* b Function Enable	*/
     52#define SCR_MCR		0xe4		/* w Mode Control	*/
     53#define SCR_CONFIG	0xfc		/* b Configuration Control */
     54#define SCR_DEBUG	0xff		/* b Debug		*/
     55
     56#define SCR_CCR_CK32K	BIT(0)
     57#define SCR_CCR_USBCK	BIT(1)
     58#define SCR_CCR_UNK1	BIT(4)
     59#define SCR_CCR_MCLK_MASK	(7 << 8)
     60#define SCR_CCR_MCLK_OFF	(0 << 8)
     61#define SCR_CCR_MCLK_12	(1 << 8)
     62#define SCR_CCR_MCLK_24	(2 << 8)
     63#define SCR_CCR_MCLK_48	(3 << 8)
     64#define SCR_CCR_HCLK_MASK	(3 << 12)
     65#define SCR_CCR_HCLK_24	(0 << 12)
     66#define SCR_CCR_HCLK_48	(1 << 12)
     67
     68#define SCR_FER_USBEN		BIT(0)	/* USB host enable */
     69#define SCR_FER_LCDCVEN		BIT(1)	/* polysilicon TFT enable */
     70#define SCR_FER_SLCDEN		BIT(2)	/* SLCD enable */
     71
     72#define SCR_MCR_RDY_MASK		(3 << 0)
     73#define SCR_MCR_RDY_OPENDRAIN	(0 << 0)
     74#define SCR_MCR_RDY_TRISTATE	(1 << 0)
     75#define SCR_MCR_RDY_PUSHPULL	(2 << 0)
     76#define SCR_MCR_RDY_UNK		BIT(2)
     77#define SCR_MCR_RDY_EN		BIT(3)
     78#define SCR_MCR_INT_MASK		(3 << 4)
     79#define SCR_MCR_INT_OPENDRAIN	(0 << 4)
     80#define SCR_MCR_INT_TRISTATE	(1 << 4)
     81#define SCR_MCR_INT_PUSHPULL	(2 << 4)
     82#define SCR_MCR_INT_UNK		BIT(6)
     83#define SCR_MCR_INT_EN		BIT(7)
     84/* bits 8 - 16 are unknown */
     85
     86#define TC_GPIO_BIT(i)		(1 << (i & 0x7))
     87
     88/*--------------------------------------------------------------------------*/
     89
     90struct tc6393xb {
     91	void __iomem		*scr;
     92	struct device		*dev;
     93
     94	struct gpio_chip	gpio;
     95	struct gpio_desc	*vcc_on;
     96
     97	struct clk		*clk; /* 3,6 Mhz */
     98
     99	raw_spinlock_t		lock; /* protects RMW cycles */
    100
    101	struct {
    102		u8		fer;
    103		u16		ccr;
    104		u8		gpi_bcr[3];
    105		u8		gpo_dsr[3];
    106		u8		gpo_doecr[3];
    107	} suspend_state;
    108
    109	struct resource		rscr;
    110	struct resource		*iomem;
    111	int			irq;
    112	int			irq_base;
    113};
    114
    115enum {
    116	TC6393XB_CELL_NAND,
    117	TC6393XB_CELL_MMC,
    118	TC6393XB_CELL_OHCI,
    119	TC6393XB_CELL_FB,
    120};
    121
    122/*--------------------------------------------------------------------------*/
    123
    124static int tc6393xb_nand_enable(struct platform_device *nand)
    125{
    126	struct tc6393xb *tc6393xb = dev_get_drvdata(nand->dev.parent);
    127	unsigned long flags;
    128
    129	raw_spin_lock_irqsave(&tc6393xb->lock, flags);
    130
    131	/* SMD buffer on */
    132	dev_dbg(nand->dev.parent, "SMD buffer on\n");
    133	tmio_iowrite8(0xff, tc6393xb->scr + SCR_GPI_BCR(1));
    134
    135	raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
    136
    137	return 0;
    138}
    139
    140static const struct resource tc6393xb_nand_resources[] = {
    141	{
    142		.start	= 0x1000,
    143		.end	= 0x1007,
    144		.flags	= IORESOURCE_MEM,
    145	},
    146	{
    147		.start	= 0x0100,
    148		.end	= 0x01ff,
    149		.flags	= IORESOURCE_MEM,
    150	},
    151	{
    152		.start	= IRQ_TC6393_NAND,
    153		.end	= IRQ_TC6393_NAND,
    154		.flags	= IORESOURCE_IRQ,
    155	},
    156};
    157
    158static const struct resource tc6393xb_mmc_resources[] = {
    159	{
    160		.start	= 0x800,
    161		.end	= 0x9ff,
    162		.flags	= IORESOURCE_MEM,
    163	},
    164	{
    165		.start	= IRQ_TC6393_MMC,
    166		.end	= IRQ_TC6393_MMC,
    167		.flags	= IORESOURCE_IRQ,
    168	},
    169};
    170
    171static const struct resource tc6393xb_ohci_resources[] = {
    172	{
    173		.start	= 0x3000,
    174		.end	= 0x31ff,
    175		.flags	= IORESOURCE_MEM,
    176	},
    177	{
    178		.start	= 0x0300,
    179		.end	= 0x03ff,
    180		.flags	= IORESOURCE_MEM,
    181	},
    182	{
    183		.start	= 0x010000,
    184		.end	= 0x017fff,
    185		.flags	= IORESOURCE_MEM,
    186	},
    187	{
    188		.start	= 0x018000,
    189		.end	= 0x01ffff,
    190		.flags	= IORESOURCE_MEM,
    191	},
    192	{
    193		.start	= IRQ_TC6393_OHCI,
    194		.end	= IRQ_TC6393_OHCI,
    195		.flags	= IORESOURCE_IRQ,
    196	},
    197};
    198
    199static const struct resource tc6393xb_fb_resources[] = {
    200	{
    201		.start	= 0x5000,
    202		.end	= 0x51ff,
    203		.flags	= IORESOURCE_MEM,
    204	},
    205	{
    206		.start	= 0x0500,
    207		.end	= 0x05ff,
    208		.flags	= IORESOURCE_MEM,
    209	},
    210	{
    211		.start	= 0x100000,
    212		.end	= 0x1fffff,
    213		.flags	= IORESOURCE_MEM,
    214	},
    215	{
    216		.start	= IRQ_TC6393_FB,
    217		.end	= IRQ_TC6393_FB,
    218		.flags	= IORESOURCE_IRQ,
    219	},
    220};
    221
    222static int tc6393xb_ohci_enable(struct platform_device *dev)
    223{
    224	struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
    225	unsigned long flags;
    226	u16 ccr;
    227	u8 fer;
    228
    229	raw_spin_lock_irqsave(&tc6393xb->lock, flags);
    230
    231	ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
    232	ccr |= SCR_CCR_USBCK;
    233	tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
    234
    235	fer = tmio_ioread8(tc6393xb->scr + SCR_FER);
    236	fer |= SCR_FER_USBEN;
    237	tmio_iowrite8(fer, tc6393xb->scr + SCR_FER);
    238
    239	raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
    240
    241	return 0;
    242}
    243
    244static int tc6393xb_ohci_disable(struct platform_device *dev)
    245{
    246	struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
    247	unsigned long flags;
    248	u16 ccr;
    249	u8 fer;
    250
    251	raw_spin_lock_irqsave(&tc6393xb->lock, flags);
    252
    253	fer = tmio_ioread8(tc6393xb->scr + SCR_FER);
    254	fer &= ~SCR_FER_USBEN;
    255	tmio_iowrite8(fer, tc6393xb->scr + SCR_FER);
    256
    257	ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
    258	ccr &= ~SCR_CCR_USBCK;
    259	tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
    260
    261	raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
    262
    263	return 0;
    264}
    265
    266static int tc6393xb_ohci_suspend(struct platform_device *dev)
    267{
    268	struct tc6393xb_platform_data *tcpd = dev_get_platdata(dev->dev.parent);
    269
    270	/* We can't properly store/restore OHCI state, so fail here */
    271	if (tcpd->resume_restore)
    272		return -EBUSY;
    273
    274	return tc6393xb_ohci_disable(dev);
    275}
    276
    277static int tc6393xb_fb_enable(struct platform_device *dev)
    278{
    279	struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
    280	unsigned long flags;
    281	u16 ccr;
    282
    283	raw_spin_lock_irqsave(&tc6393xb->lock, flags);
    284
    285	ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
    286	ccr &= ~SCR_CCR_MCLK_MASK;
    287	ccr |= SCR_CCR_MCLK_48;
    288	tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
    289
    290	raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
    291
    292	return 0;
    293}
    294
    295static int tc6393xb_fb_disable(struct platform_device *dev)
    296{
    297	struct tc6393xb *tc6393xb = dev_get_drvdata(dev->dev.parent);
    298	unsigned long flags;
    299	u16 ccr;
    300
    301	raw_spin_lock_irqsave(&tc6393xb->lock, flags);
    302
    303	ccr = tmio_ioread16(tc6393xb->scr + SCR_CCR);
    304	ccr &= ~SCR_CCR_MCLK_MASK;
    305	ccr |= SCR_CCR_MCLK_OFF;
    306	tmio_iowrite16(ccr, tc6393xb->scr + SCR_CCR);
    307
    308	raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
    309
    310	return 0;
    311}
    312
    313int tc6393xb_lcd_set_power(struct platform_device *fb, bool on)
    314{
    315	struct tc6393xb *tc6393xb = dev_get_drvdata(fb->dev.parent);
    316	u8 fer;
    317	unsigned long flags;
    318
    319	raw_spin_lock_irqsave(&tc6393xb->lock, flags);
    320
    321	fer = ioread8(tc6393xb->scr + SCR_FER);
    322	if (on)
    323		fer |= SCR_FER_SLCDEN;
    324	else
    325		fer &= ~SCR_FER_SLCDEN;
    326	iowrite8(fer, tc6393xb->scr + SCR_FER);
    327
    328	raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
    329
    330	return 0;
    331}
    332EXPORT_SYMBOL(tc6393xb_lcd_set_power);
    333
    334int tc6393xb_lcd_mode(struct platform_device *fb,
    335					const struct fb_videomode *mode) {
    336	struct tc6393xb *tc6393xb = dev_get_drvdata(fb->dev.parent);
    337	unsigned long flags;
    338
    339	raw_spin_lock_irqsave(&tc6393xb->lock, flags);
    340
    341	iowrite16(mode->pixclock, tc6393xb->scr + SCR_PLL1CR + 0);
    342	iowrite16(mode->pixclock >> 16, tc6393xb->scr + SCR_PLL1CR + 2);
    343
    344	raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
    345
    346	return 0;
    347}
    348EXPORT_SYMBOL(tc6393xb_lcd_mode);
    349
    350static int tc6393xb_mmc_enable(struct platform_device *mmc)
    351{
    352	struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent);
    353
    354	tmio_core_mmc_enable(tc6393xb->scr + 0x200, 0,
    355		tc6393xb_mmc_resources[0].start & 0xfffe);
    356
    357	return 0;
    358}
    359
    360static int tc6393xb_mmc_resume(struct platform_device *mmc)
    361{
    362	struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent);
    363
    364	tmio_core_mmc_resume(tc6393xb->scr + 0x200, 0,
    365		tc6393xb_mmc_resources[0].start & 0xfffe);
    366
    367	return 0;
    368}
    369
    370static void tc6393xb_mmc_pwr(struct platform_device *mmc, int state)
    371{
    372	struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent);
    373
    374	tmio_core_mmc_pwr(tc6393xb->scr + 0x200, 0, state);
    375}
    376
    377static void tc6393xb_mmc_clk_div(struct platform_device *mmc, int state)
    378{
    379	struct tc6393xb *tc6393xb = dev_get_drvdata(mmc->dev.parent);
    380
    381	tmio_core_mmc_clk_div(tc6393xb->scr + 0x200, 0, state);
    382}
    383
    384static struct tmio_mmc_data tc6393xb_mmc_data = {
    385	.hclk = 24000000,
    386	.set_pwr = tc6393xb_mmc_pwr,
    387	.set_clk_div = tc6393xb_mmc_clk_div,
    388};
    389
    390static struct mfd_cell tc6393xb_cells[] = {
    391	[TC6393XB_CELL_NAND] = {
    392		.name = "tmio-nand",
    393		.enable = tc6393xb_nand_enable,
    394		.num_resources = ARRAY_SIZE(tc6393xb_nand_resources),
    395		.resources = tc6393xb_nand_resources,
    396	},
    397	[TC6393XB_CELL_MMC] = {
    398		.name = "tmio-mmc",
    399		.enable = tc6393xb_mmc_enable,
    400		.resume = tc6393xb_mmc_resume,
    401		.platform_data = &tc6393xb_mmc_data,
    402		.pdata_size    = sizeof(tc6393xb_mmc_data),
    403		.num_resources = ARRAY_SIZE(tc6393xb_mmc_resources),
    404		.resources = tc6393xb_mmc_resources,
    405	},
    406	[TC6393XB_CELL_OHCI] = {
    407		.name = "tmio-ohci",
    408		.num_resources = ARRAY_SIZE(tc6393xb_ohci_resources),
    409		.resources = tc6393xb_ohci_resources,
    410		.enable = tc6393xb_ohci_enable,
    411		.suspend = tc6393xb_ohci_suspend,
    412		.resume = tc6393xb_ohci_enable,
    413		.disable = tc6393xb_ohci_disable,
    414	},
    415	[TC6393XB_CELL_FB] = {
    416		.name = "tmio-fb",
    417		.num_resources = ARRAY_SIZE(tc6393xb_fb_resources),
    418		.resources = tc6393xb_fb_resources,
    419		.enable = tc6393xb_fb_enable,
    420		.suspend = tc6393xb_fb_disable,
    421		.resume = tc6393xb_fb_enable,
    422		.disable = tc6393xb_fb_disable,
    423	},
    424};
    425
    426/*--------------------------------------------------------------------------*/
    427
    428static int tc6393xb_gpio_get(struct gpio_chip *chip,
    429		unsigned offset)
    430{
    431	struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
    432
    433	/* XXX: does dsr also represent inputs? */
    434	return !!(tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8))
    435		  & TC_GPIO_BIT(offset));
    436}
    437
    438static void __tc6393xb_gpio_set(struct gpio_chip *chip,
    439		unsigned offset, int value)
    440{
    441	struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
    442	u8  dsr;
    443
    444	dsr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DSR(offset / 8));
    445	if (value)
    446		dsr |= TC_GPIO_BIT(offset);
    447	else
    448		dsr &= ~TC_GPIO_BIT(offset);
    449
    450	tmio_iowrite8(dsr, tc6393xb->scr + SCR_GPO_DSR(offset / 8));
    451}
    452
    453static void tc6393xb_gpio_set(struct gpio_chip *chip,
    454		unsigned offset, int value)
    455{
    456	struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
    457	unsigned long flags;
    458
    459	raw_spin_lock_irqsave(&tc6393xb->lock, flags);
    460
    461	__tc6393xb_gpio_set(chip, offset, value);
    462
    463	raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
    464}
    465
    466static int tc6393xb_gpio_direction_input(struct gpio_chip *chip,
    467			unsigned offset)
    468{
    469	struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
    470	unsigned long flags;
    471	u8 doecr;
    472
    473	raw_spin_lock_irqsave(&tc6393xb->lock, flags);
    474
    475	doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
    476	doecr &= ~TC_GPIO_BIT(offset);
    477	tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
    478
    479	raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
    480
    481	return 0;
    482}
    483
    484static int tc6393xb_gpio_direction_output(struct gpio_chip *chip,
    485			unsigned offset, int value)
    486{
    487	struct tc6393xb *tc6393xb = gpiochip_get_data(chip);
    488	unsigned long flags;
    489	u8 doecr;
    490
    491	raw_spin_lock_irqsave(&tc6393xb->lock, flags);
    492
    493	__tc6393xb_gpio_set(chip, offset, value);
    494
    495	doecr = tmio_ioread8(tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
    496	doecr |= TC_GPIO_BIT(offset);
    497	tmio_iowrite8(doecr, tc6393xb->scr + SCR_GPO_DOECR(offset / 8));
    498
    499	raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
    500
    501	return 0;
    502}
    503
    504/*
    505 * TC6393XB GPIOs as used on TOSA, are the only user of this chip.
    506 * GPIOs 2, 5, 8 and 13 are not connected.
    507 */
    508#define TOSA_GPIO_TG_ON			0
    509#define TOSA_GPIO_L_MUTE		1
    510#define TOSA_GPIO_BL_C20MA		3
    511#define TOSA_GPIO_CARD_VCC_ON		4
    512#define TOSA_GPIO_CHARGE_OFF		6
    513#define TOSA_GPIO_CHARGE_OFF_JC		7
    514#define TOSA_GPIO_BAT0_V_ON		9
    515#define TOSA_GPIO_BAT1_V_ON		10
    516#define TOSA_GPIO_BU_CHRG_ON		11
    517#define TOSA_GPIO_BAT_SW_ON		12
    518#define TOSA_GPIO_BAT0_TH_ON		14
    519#define TOSA_GPIO_BAT1_TH_ON		15
    520
    521
    522GPIO_LOOKUP_SINGLE(tosa_lcd_gpio_lookup, "spi2.0", "tc6393xb",
    523		   TOSA_GPIO_TG_ON, "tg #pwr", GPIO_ACTIVE_HIGH);
    524
    525GPIO_LOOKUP_SINGLE(tosa_lcd_bl_gpio_lookup, "i2c-tos-bl", "tc6393xb",
    526		   TOSA_GPIO_BL_C20MA, "backlight", GPIO_ACTIVE_HIGH);
    527
    528GPIO_LOOKUP_SINGLE(tosa_audio_gpio_lookup, "tosa-audio", "tc6393xb",
    529		   TOSA_GPIO_L_MUTE, NULL, GPIO_ACTIVE_HIGH);
    530
    531static struct gpiod_lookup_table tosa_battery_gpio_lookup = {
    532	.dev_id = "wm97xx-battery",
    533	.table = {
    534		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF,
    535			    "main charge off", GPIO_ACTIVE_HIGH),
    536		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF_JC,
    537			    "jacket charge off", GPIO_ACTIVE_HIGH),
    538		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_V_ON,
    539			    "main battery", GPIO_ACTIVE_HIGH),
    540		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_V_ON,
    541			    "jacket battery", GPIO_ACTIVE_HIGH),
    542		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BU_CHRG_ON,
    543			    "backup battery", GPIO_ACTIVE_HIGH),
    544		/* BAT1 and BAT0 thermistors appear to be swapped */
    545		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_TH_ON,
    546			    "main battery temp", GPIO_ACTIVE_HIGH),
    547		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_TH_ON,
    548			    "jacket battery temp", GPIO_ACTIVE_HIGH),
    549		GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT_SW_ON,
    550			    "battery switch", GPIO_ACTIVE_HIGH),
    551		{ },
    552	},
    553};
    554
    555static struct gpiod_lookup_table *tc6393xb_gpio_lookups[] = {
    556	&tosa_lcd_gpio_lookup,
    557	&tosa_lcd_bl_gpio_lookup,
    558	&tosa_audio_gpio_lookup,
    559	&tosa_battery_gpio_lookup,
    560};
    561
    562static int tc6393xb_register_gpio(struct tc6393xb *tc6393xb)
    563{
    564	struct gpio_chip *gc = &tc6393xb->gpio;
    565	struct device *dev = tc6393xb->dev;
    566	int ret;
    567
    568	gc->label = "tc6393xb";
    569	gc->base = -1; /* Dynamic allocation */
    570	gc->ngpio = 16;
    571	gc->set = tc6393xb_gpio_set;
    572	gc->get = tc6393xb_gpio_get;
    573	gc->direction_input = tc6393xb_gpio_direction_input;
    574	gc->direction_output = tc6393xb_gpio_direction_output;
    575
    576	ret = devm_gpiochip_add_data(dev, gc, tc6393xb);
    577	if (ret)
    578		return dev_err_probe(dev, ret, "failed to add GPIO chip\n");
    579
    580	/* Register descriptor look-ups for consumers */
    581	gpiod_add_lookup_tables(tc6393xb_gpio_lookups, ARRAY_SIZE(tc6393xb_gpio_lookups));
    582
    583	/* Request some of our own GPIOs */
    584	tc6393xb->vcc_on = gpiochip_request_own_desc(gc, TOSA_GPIO_CARD_VCC_ON, "VCC ON",
    585						     GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH);
    586	if (IS_ERR(tc6393xb->vcc_on))
    587		return dev_err_probe(dev, PTR_ERR(tc6393xb->vcc_on),
    588				     "failed to request VCC ON GPIO\n");
    589
    590	return 0;
    591}
    592
    593/*--------------------------------------------------------------------------*/
    594
    595static void tc6393xb_irq(struct irq_desc *desc)
    596{
    597	struct tc6393xb *tc6393xb = irq_desc_get_handler_data(desc);
    598	unsigned int isr;
    599	unsigned int i, irq_base;
    600
    601	irq_base = tc6393xb->irq_base;
    602
    603	while ((isr = tmio_ioread8(tc6393xb->scr + SCR_ISR) &
    604				~tmio_ioread8(tc6393xb->scr + SCR_IMR)))
    605		for (i = 0; i < TC6393XB_NR_IRQS; i++) {
    606			if (isr & (1 << i))
    607				generic_handle_irq(irq_base + i);
    608		}
    609}
    610
    611static void tc6393xb_irq_ack(struct irq_data *data)
    612{
    613}
    614
    615static void tc6393xb_irq_mask(struct irq_data *data)
    616{
    617	struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data);
    618	unsigned long flags;
    619	u8 imr;
    620
    621	raw_spin_lock_irqsave(&tc6393xb->lock, flags);
    622	imr = tmio_ioread8(tc6393xb->scr + SCR_IMR);
    623	imr |= 1 << (data->irq - tc6393xb->irq_base);
    624	tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR);
    625	raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
    626}
    627
    628static void tc6393xb_irq_unmask(struct irq_data *data)
    629{
    630	struct tc6393xb *tc6393xb = irq_data_get_irq_chip_data(data);
    631	unsigned long flags;
    632	u8 imr;
    633
    634	raw_spin_lock_irqsave(&tc6393xb->lock, flags);
    635	imr = tmio_ioread8(tc6393xb->scr + SCR_IMR);
    636	imr &= ~(1 << (data->irq - tc6393xb->irq_base));
    637	tmio_iowrite8(imr, tc6393xb->scr + SCR_IMR);
    638	raw_spin_unlock_irqrestore(&tc6393xb->lock, flags);
    639}
    640
    641static struct irq_chip tc6393xb_chip = {
    642	.name		= "tc6393xb",
    643	.irq_ack	= tc6393xb_irq_ack,
    644	.irq_mask	= tc6393xb_irq_mask,
    645	.irq_unmask	= tc6393xb_irq_unmask,
    646};
    647
    648static void tc6393xb_attach_irq(struct platform_device *dev)
    649{
    650	struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
    651	unsigned int irq, irq_base;
    652
    653	irq_base = tc6393xb->irq_base;
    654
    655	for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
    656		irq_set_chip_and_handler(irq, &tc6393xb_chip, handle_edge_irq);
    657		irq_set_chip_data(irq, tc6393xb);
    658		irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
    659	}
    660
    661	irq_set_irq_type(tc6393xb->irq, IRQ_TYPE_EDGE_FALLING);
    662	irq_set_chained_handler_and_data(tc6393xb->irq, tc6393xb_irq,
    663					 tc6393xb);
    664}
    665
    666static void tc6393xb_detach_irq(struct platform_device *dev)
    667{
    668	struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
    669	unsigned int irq, irq_base;
    670
    671	irq_set_chained_handler_and_data(tc6393xb->irq, NULL, NULL);
    672
    673	irq_base = tc6393xb->irq_base;
    674
    675	for (irq = irq_base; irq < irq_base + TC6393XB_NR_IRQS; irq++) {
    676		irq_set_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
    677		irq_set_chip(irq, NULL);
    678		irq_set_chip_data(irq, NULL);
    679	}
    680}
    681
    682/*--------------------------------------------------------------------------*/
    683
    684static int tc6393xb_probe(struct platform_device *dev)
    685{
    686	struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
    687	struct tc6393xb *tc6393xb;
    688	struct resource *iomem, *rscr;
    689	int ret;
    690
    691	iomem = platform_get_resource(dev, IORESOURCE_MEM, 0);
    692	if (!iomem)
    693		return -EINVAL;
    694
    695	tc6393xb = kzalloc(sizeof *tc6393xb, GFP_KERNEL);
    696	if (!tc6393xb) {
    697		ret = -ENOMEM;
    698		goto err_kzalloc;
    699	}
    700	tc6393xb->dev = &dev->dev;
    701
    702	raw_spin_lock_init(&tc6393xb->lock);
    703
    704	platform_set_drvdata(dev, tc6393xb);
    705
    706	ret = platform_get_irq(dev, 0);
    707	if (ret >= 0)
    708		tc6393xb->irq = ret;
    709	else
    710		goto err_noirq;
    711
    712	tc6393xb->iomem = iomem;
    713	tc6393xb->irq_base = tcpd->irq_base;
    714
    715	tc6393xb->clk = clk_get(&dev->dev, "CLK_CK3P6MI");
    716	if (IS_ERR(tc6393xb->clk)) {
    717		ret = PTR_ERR(tc6393xb->clk);
    718		goto err_clk_get;
    719	}
    720
    721	rscr = &tc6393xb->rscr;
    722	rscr->name = "tc6393xb-core";
    723	rscr->start = iomem->start;
    724	rscr->end = iomem->start + 0xff;
    725	rscr->flags = IORESOURCE_MEM;
    726
    727	ret = request_resource(iomem, rscr);
    728	if (ret)
    729		goto err_request_scr;
    730
    731	tc6393xb->scr = ioremap(rscr->start, resource_size(rscr));
    732	if (!tc6393xb->scr) {
    733		ret = -ENOMEM;
    734		goto err_ioremap;
    735	}
    736
    737	ret = clk_prepare_enable(tc6393xb->clk);
    738	if (ret)
    739		goto err_clk_enable;
    740
    741	ret = tcpd->enable(dev);
    742	if (ret)
    743		goto err_enable;
    744
    745	iowrite8(0,				tc6393xb->scr + SCR_FER);
    746	iowrite16(tcpd->scr_pll2cr,		tc6393xb->scr + SCR_PLL2CR);
    747	iowrite16(SCR_CCR_UNK1 | SCR_CCR_HCLK_48,
    748						tc6393xb->scr + SCR_CCR);
    749	iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN |
    750		  SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN |
    751		  BIT(15),			tc6393xb->scr + SCR_MCR);
    752	iowrite16(tcpd->scr_gper,		tc6393xb->scr + SCR_GPER);
    753	iowrite8(0,				tc6393xb->scr + SCR_IRR);
    754	iowrite8(0xbf,				tc6393xb->scr + SCR_IMR);
    755
    756	printk(KERN_INFO "Toshiba tc6393xb revision %d at 0x%08lx, irq %d\n",
    757			tmio_ioread8(tc6393xb->scr + SCR_REVID),
    758			(unsigned long) iomem->start, tc6393xb->irq);
    759
    760	ret = tc6393xb_register_gpio(tc6393xb);
    761	if (ret)
    762		goto err_gpio_add;
    763
    764	tc6393xb_attach_irq(dev);
    765
    766	tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = tcpd->nand_data;
    767	tc6393xb_cells[TC6393XB_CELL_NAND].pdata_size =
    768						sizeof(*tcpd->nand_data);
    769	tc6393xb_cells[TC6393XB_CELL_FB].platform_data = tcpd->fb_data;
    770	tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data);
    771
    772	ret = mfd_add_devices(&dev->dev, dev->id,
    773			      tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
    774			      iomem, tcpd->irq_base, NULL);
    775
    776	if (!ret)
    777		return 0;
    778
    779	tc6393xb_detach_irq(dev);
    780err_gpio_add:
    781	tcpd->disable(dev);
    782err_enable:
    783	clk_disable_unprepare(tc6393xb->clk);
    784err_clk_enable:
    785	iounmap(tc6393xb->scr);
    786err_ioremap:
    787	release_resource(&tc6393xb->rscr);
    788err_request_scr:
    789	clk_put(tc6393xb->clk);
    790err_noirq:
    791err_clk_get:
    792	kfree(tc6393xb);
    793err_kzalloc:
    794	return ret;
    795}
    796
    797static int tc6393xb_remove(struct platform_device *dev)
    798{
    799	struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
    800	struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
    801	int ret;
    802
    803	mfd_remove_devices(&dev->dev);
    804
    805	tc6393xb_detach_irq(dev);
    806
    807	ret = tcpd->disable(dev);
    808	clk_disable_unprepare(tc6393xb->clk);
    809	iounmap(tc6393xb->scr);
    810	release_resource(&tc6393xb->rscr);
    811	clk_put(tc6393xb->clk);
    812	kfree(tc6393xb);
    813
    814	return ret;
    815}
    816
    817#ifdef CONFIG_PM
    818static int tc6393xb_suspend(struct platform_device *dev, pm_message_t state)
    819{
    820	struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
    821	struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
    822	int i, ret;
    823
    824	tc6393xb->suspend_state.ccr = ioread16(tc6393xb->scr + SCR_CCR);
    825	tc6393xb->suspend_state.fer = ioread8(tc6393xb->scr + SCR_FER);
    826
    827	for (i = 0; i < 3; i++) {
    828		tc6393xb->suspend_state.gpo_dsr[i] =
    829			ioread8(tc6393xb->scr + SCR_GPO_DSR(i));
    830		tc6393xb->suspend_state.gpo_doecr[i] =
    831			ioread8(tc6393xb->scr + SCR_GPO_DOECR(i));
    832		tc6393xb->suspend_state.gpi_bcr[i] =
    833			ioread8(tc6393xb->scr + SCR_GPI_BCR(i));
    834	}
    835	ret = tcpd->suspend(dev);
    836	clk_disable_unprepare(tc6393xb->clk);
    837
    838	return ret;
    839}
    840
    841static int tc6393xb_resume(struct platform_device *dev)
    842{
    843	struct tc6393xb_platform_data *tcpd = dev_get_platdata(&dev->dev);
    844	struct tc6393xb *tc6393xb = platform_get_drvdata(dev);
    845	int ret;
    846	int i;
    847
    848	ret = clk_prepare_enable(tc6393xb->clk);
    849	if (ret)
    850		return ret;
    851
    852	ret = tcpd->resume(dev);
    853	if (ret)
    854		return ret;
    855
    856	if (!tcpd->resume_restore)
    857		return 0;
    858
    859	iowrite8(tc6393xb->suspend_state.fer,	tc6393xb->scr + SCR_FER);
    860	iowrite16(tcpd->scr_pll2cr,		tc6393xb->scr + SCR_PLL2CR);
    861	iowrite16(tc6393xb->suspend_state.ccr,	tc6393xb->scr + SCR_CCR);
    862	iowrite16(SCR_MCR_RDY_OPENDRAIN | SCR_MCR_RDY_UNK | SCR_MCR_RDY_EN |
    863		  SCR_MCR_INT_OPENDRAIN | SCR_MCR_INT_UNK | SCR_MCR_INT_EN |
    864		  BIT(15),			tc6393xb->scr + SCR_MCR);
    865	iowrite16(tcpd->scr_gper,		tc6393xb->scr + SCR_GPER);
    866	iowrite8(0,				tc6393xb->scr + SCR_IRR);
    867	iowrite8(0xbf,				tc6393xb->scr + SCR_IMR);
    868
    869	for (i = 0; i < 3; i++) {
    870		iowrite8(tc6393xb->suspend_state.gpo_dsr[i],
    871					tc6393xb->scr + SCR_GPO_DSR(i));
    872		iowrite8(tc6393xb->suspend_state.gpo_doecr[i],
    873					tc6393xb->scr + SCR_GPO_DOECR(i));
    874		iowrite8(tc6393xb->suspend_state.gpi_bcr[i],
    875					tc6393xb->scr + SCR_GPI_BCR(i));
    876	}
    877
    878	return 0;
    879}
    880#else
    881#define tc6393xb_suspend NULL
    882#define tc6393xb_resume NULL
    883#endif
    884
    885static struct platform_driver tc6393xb_driver = {
    886	.probe = tc6393xb_probe,
    887	.remove = tc6393xb_remove,
    888	.suspend = tc6393xb_suspend,
    889	.resume = tc6393xb_resume,
    890
    891	.driver = {
    892		.name = "tc6393xb",
    893	},
    894};
    895
    896static int __init tc6393xb_init(void)
    897{
    898	return platform_driver_register(&tc6393xb_driver);
    899}
    900
    901static void __exit tc6393xb_exit(void)
    902{
    903	platform_driver_unregister(&tc6393xb_driver);
    904}
    905
    906subsys_initcall(tc6393xb_init);
    907module_exit(tc6393xb_exit);
    908
    909MODULE_LICENSE("GPL v2");
    910MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov and Dirk Opfer");
    911MODULE_DESCRIPTION("tc6393xb Toshiba Mobile IO Controller");
    912MODULE_ALIAS("platform:tc6393xb");
    913