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