Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /* linux/drivers/mfd/sm501.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Copyright (C) 2006 Simtec Electronics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *	Ben Dooks <ben@simtec.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *	Vincent Sanders <vince@simtec.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * SM501 MFD driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/platform_data/i2c-gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/gpio/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/sm501.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/sm501-regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/serial_8250.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) struct sm501_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) 	struct list_head		list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 	struct platform_device		pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) struct sm501_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #ifdef CONFIG_MFD_SM501_GPIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) struct sm501_gpio_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	struct gpio_chip	gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	struct sm501_gpio	*ourgpio;	/* to get back to parent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	void __iomem		*regbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	void __iomem		*control;	/* address of control reg. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) struct sm501_gpio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	struct sm501_gpio_chip	low;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	struct sm501_gpio_chip	high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	spinlock_t		lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	unsigned int		 registered : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	void __iomem		*regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	struct resource		*regs_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) struct sm501_gpio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 	/* no gpio support, empty definition for sm501_devdata. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) struct sm501_devdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	spinlock_t			 reg_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	struct mutex			 clock_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	struct list_head		 devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	struct sm501_gpio		 gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	struct device			*dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 	struct resource			*io_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 	struct resource			*mem_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	struct resource			*regs_claim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	struct sm501_platdata		*platdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 	unsigned int			 in_suspend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	unsigned long			 pm_misc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	int				 unit_power[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	unsigned int			 pdev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	unsigned int			 irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	void __iomem			*regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	unsigned int			 rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define MHZ (1000 * 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) static const unsigned int div_tab[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	[0]		= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	[1]		= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	[2]		= 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	[3]		= 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	[4]		= 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	[5]		= 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	[6]		= 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	[7]		= 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	[8]		= 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	[9]		= 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	[10]	        = 12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	[11]		= 24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	[12]		= 48,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	[13]		= 96,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	[14]		= 192,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	[15]		= 384,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	[16]		= 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	[17]		= 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	[18]		= 20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	[19]		= 40,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	[20]		= 80,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	[21]		= 160,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	[22]		= 320,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	[23]		= 604,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) static unsigned long decode_div(unsigned long pll2, unsigned long val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 				unsigned int lshft, unsigned int selbit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 				unsigned long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	if (val & selbit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		pll2 = 288 * MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	return pll2 / div_tab[(val >> lshft) & mask];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) #define fmt_freq(x) ((x) / MHZ), ((x) % MHZ), (x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) /* sm501_dump_clk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130)  * Print out the current clock configuration for the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) static void sm501_dump_clk(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	unsigned long misct = smc501_readl(sm->regs + SM501_MISC_TIMING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	unsigned long pm0 = smc501_readl(sm->regs + SM501_POWER_MODE_0_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	unsigned long pm1 = smc501_readl(sm->regs + SM501_POWER_MODE_1_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	unsigned long pmc = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	unsigned long sdclk0, sdclk1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	unsigned long pll2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	switch (misct & 0x30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	case 0x00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 		pll2 = 336 * MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	case 0x10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		pll2 = 288 * MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	case 0x20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 		pll2 = 240 * MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	case 0x30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 		pll2 = 192 * MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	sdclk0 = (misct & (1<<12)) ? pll2 : 288 * MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	sdclk0 /= div_tab[((misct >> 8) & 0xf)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	sdclk1 = (misct & (1<<20)) ? pll2 : 288 * MHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	sdclk1 /= div_tab[((misct >> 16) & 0xf)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	dev_dbg(sm->dev, "MISCT=%08lx, PM0=%08lx, PM1=%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		misct, pm0, pm1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	dev_dbg(sm->dev, "PLL2 = %ld.%ld MHz (%ld), SDCLK0=%08lx, SDCLK1=%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		fmt_freq(pll2), sdclk0, sdclk1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	dev_dbg(sm->dev, "SDRAM: PM0=%ld, PM1=%ld\n", sdclk0, sdclk1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	dev_dbg(sm->dev, "PM0[%c]: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 		 "P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		 "M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 		 (pmc & 3 ) == 0 ? '*' : '-',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 		 fmt_freq(decode_div(pll2, pm0, 24, 1<<29, 31)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 		 fmt_freq(decode_div(pll2, pm0, 16, 1<<20, 15)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		 fmt_freq(decode_div(pll2, pm0, 8,  1<<12, 15)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 		 fmt_freq(decode_div(pll2, pm0, 0,  1<<4,  15)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	dev_dbg(sm->dev, "PM1[%c]: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		"P2 %ld.%ld MHz (%ld), V2 %ld.%ld (%ld), "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		"M %ld.%ld (%ld), MX1 %ld.%ld (%ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		(pmc & 3 ) == 1 ? '*' : '-',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		fmt_freq(decode_div(pll2, pm1, 24, 1<<29, 31)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		fmt_freq(decode_div(pll2, pm1, 16, 1<<20, 15)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		fmt_freq(decode_div(pll2, pm1, 8,  1<<12, 15)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		fmt_freq(decode_div(pll2, pm1, 0,  1<<4,  15)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) static void sm501_dump_regs(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	void __iomem *regs = sm->regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	dev_info(sm->dev, "System Control   %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 			smc501_readl(regs + SM501_SYSTEM_CONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	dev_info(sm->dev, "Misc Control     %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 			smc501_readl(regs + SM501_MISC_CONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	dev_info(sm->dev, "GPIO Control Low %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 			smc501_readl(regs + SM501_GPIO31_0_CONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	dev_info(sm->dev, "GPIO Control Hi  %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 			smc501_readl(regs + SM501_GPIO63_32_CONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	dev_info(sm->dev, "DRAM Control     %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 			smc501_readl(regs + SM501_DRAM_CONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	dev_info(sm->dev, "Arbitration Ctrl %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 			smc501_readl(regs + SM501_ARBTRTN_CONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	dev_info(sm->dev, "Misc Timing      %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 			smc501_readl(regs + SM501_MISC_TIMING));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) static void sm501_dump_gate(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	dev_info(sm->dev, "CurrentGate      %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 			smc501_readl(sm->regs + SM501_CURRENT_GATE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	dev_info(sm->dev, "CurrentClock     %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 			smc501_readl(sm->regs + SM501_CURRENT_CLOCK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	dev_info(sm->dev, "PowerModeControl %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 			smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) static inline void sm501_dump_gate(struct sm501_devdata *sm) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) static inline void sm501_dump_regs(struct sm501_devdata *sm) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) static inline void sm501_dump_clk(struct sm501_devdata *sm) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) /* sm501_sync_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228)  * ensure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) static void sm501_sync_regs(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	smc501_readl(sm->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) static inline void sm501_mdelay(struct sm501_devdata *sm, unsigned int delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	/* during suspend/resume, we are currently not allowed to sleep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	 * so change to using mdelay() instead of msleep() if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	 * are in one of these paths */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	if (sm->in_suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		mdelay(delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		msleep(delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) /* sm501_misc_control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250)  * alters the miscellaneous control parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) int sm501_misc_control(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		       unsigned long set, unsigned long clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	struct sm501_devdata *sm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	unsigned long misc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	unsigned long save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	unsigned long to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	spin_lock_irqsave(&sm->reg_lock, save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	misc = smc501_readl(sm->regs + SM501_MISC_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	to = (misc & ~clear) | set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	if (to != misc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		smc501_writel(to, sm->regs + SM501_MISC_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		sm501_sync_regs(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		dev_dbg(sm->dev, "MISC_CONTROL %08lx\n", misc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	spin_unlock_irqrestore(&sm->reg_lock, save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	return to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) EXPORT_SYMBOL_GPL(sm501_misc_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) /* sm501_modify_reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281)  * Modify a register in the SM501 which may be shared with other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282)  * drivers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) unsigned long sm501_modify_reg(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 			       unsigned long reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 			       unsigned long set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 			       unsigned long clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	struct sm501_devdata *sm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	unsigned long data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	unsigned long save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	spin_lock_irqsave(&sm->reg_lock, save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	data = smc501_readl(sm->regs + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	data |= set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	data &= ~clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	smc501_writel(data, sm->regs + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	sm501_sync_regs(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	spin_unlock_irqrestore(&sm->reg_lock, save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) EXPORT_SYMBOL_GPL(sm501_modify_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) /* sm501_unit_power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312)  * alters the power active gate to set specific units on or off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) int sm501_unit_power(struct device *dev, unsigned int unit, unsigned int to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	struct sm501_devdata *sm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	unsigned long mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	unsigned long gate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	unsigned long clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	mutex_lock(&sm->clock_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	mode &= 3;		/* get current power mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	if (unit >= ARRAY_SIZE(sm->unit_power)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		dev_err(dev, "%s: bad unit %d\n", __func__, unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		goto already;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	dev_dbg(sm->dev, "%s: unit %d, cur %d, to %d\n", __func__, unit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		sm->unit_power[unit], to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	if (to == 0 && sm->unit_power[unit] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		dev_err(sm->dev, "unit %d is already shutdown\n", unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		goto already;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	sm->unit_power[unit] += to ? 1 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	to = sm->unit_power[unit] ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	if (to) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		if (gate & (1 << unit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 			goto already;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		gate |= (1 << unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		if (!(gate & (1 << unit)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 			goto already;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		gate &= ~(1 << unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 		smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 		gate = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		goto already;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	sm501_sync_regs(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		gate, clock, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	sm501_mdelay(sm, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382)  already:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	mutex_unlock(&sm->clock_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	return gate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) EXPORT_SYMBOL_GPL(sm501_unit_power);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) /* clock value structure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) struct sm501_clock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	unsigned long mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	int divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	unsigned int m, n, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) /* sm501_calc_clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399)  * Calculates the nearest discrete clock frequency that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400)  * can be achieved with the specified input clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401)  *   the maximum divisor is 3 or 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) static int sm501_calc_clock(unsigned long freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 			    struct sm501_clock *clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 			    int max_div,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 			    unsigned long mclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			    long *best_diff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	int divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	int shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	long diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	/* try dividers 1 and 3 for CRT and for panel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	   try divider 5 for panel only.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	for (divider = 1; divider <= max_div; divider += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		/* try all 8 shift values.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 		for (shift = 0; shift < 8; shift++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 			/* Calculate difference to requested clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 			diff = DIV_ROUND_CLOSEST(mclk, divider << shift) - freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 			if (diff < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 				diff = -diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			/* If it is less than the current, use it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 			if (diff < *best_diff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 				*best_diff = diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 				clock->mclk = mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 				clock->divider = divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 				clock->shift = shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 				ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) /* sm501_calc_pll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443)  * Calculates the nearest discrete clock frequency that can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444)  * achieved using the programmable PLL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445)  *   the maximum divisor is 3 or 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) static unsigned long sm501_calc_pll(unsigned long freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 					struct sm501_clock *clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 					int max_div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	unsigned long mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	unsigned int m, n, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	long best_diff = 999999999;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	 * The SM502 datasheet doesn't specify the min/max values for M and N.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	 * N = 1 at least doesn't work in practice.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	for (m = 2; m <= 255; m++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		for (n = 2; n <= 127; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 			for (k = 0; k <= 1; k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 				mclk = (24000000UL * m / n) >> k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 				if (sm501_calc_clock(freq, clock, max_div,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 						     mclk, &best_diff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 					clock->m = m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 					clock->n = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 					clock->k = k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	/* Return best clock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	return clock->mclk / (clock->divider << clock->shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) /* sm501_select_clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481)  * Calculates the nearest discrete clock frequency that can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482)  * achieved using the 288MHz and 336MHz PLLs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483)  *   the maximum divisor is 3 or 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) static unsigned long sm501_select_clock(unsigned long freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 					struct sm501_clock *clock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 					int max_div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 	unsigned long mclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	long best_diff = 999999999;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	/* Try 288MHz and 336MHz clocks. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 	for (mclk = 288000000; mclk <= 336000000; mclk += 48000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		sm501_calc_clock(freq, clock, max_div, mclk, &best_diff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	/* Return best clock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	return clock->mclk / (clock->divider << clock->shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) /* sm501_set_clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504)  * set one of the four clock sources to the closest available frequency to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505)  *  the one specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) unsigned long sm501_set_clock(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 			      int clksrc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 			      unsigned long req_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	struct sm501_devdata *sm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	unsigned long mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	unsigned long gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	unsigned long clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	unsigned int pll_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	unsigned long sm501_freq; /* the actual frequency achieved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	u64 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	struct sm501_clock to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	/* find achivable discrete frequency and setup register value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	 * accordingly, V2XCLK, MCLK and M1XCLK are the same P2XCLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 	 * has an extra bit for the divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	switch (clksrc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	case SM501_CLOCK_P2XCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		/* This clock is divided in half so to achieve the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		 * requested frequency the value must be multiplied by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		 * 2. This clock also has an additional pre divisor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		if (sm->rev >= 0xC0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 			/* SM502 -> use the programmable PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 			sm501_freq = (sm501_calc_pll(2 * req_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 						     &to, 5) / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 			reg = to.shift & 0x07;/* bottom 3 bits are shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 			if (to.divider == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 				reg |= 0x08; /* /3 divider required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 			else if (to.divider == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 				reg |= 0x10; /* /5 divider required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 			reg |= 0x40; /* select the programmable PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 			pll_reg = 0x20000 | (to.k << 15) | (to.n << 8) | to.m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 			sm501_freq = (sm501_select_clock(2 * req_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 							 &to, 5) / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 			reg = to.shift & 0x07;/* bottom 3 bits are shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 			if (to.divider == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 				reg |= 0x08; /* /3 divider required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 			else if (to.divider == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 				reg |= 0x10; /* /5 divider required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 			if (to.mclk != 288000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 				reg |= 0x20; /* which mclk pll is source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	case SM501_CLOCK_V2XCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		/* This clock is divided in half so to achieve the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		 * requested frequency the value must be multiplied by 2. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 		sm501_freq = (sm501_select_clock(2 * req_freq, &to, 3) / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		reg=to.shift & 0x07;	/* bottom 3 bits are shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 		if (to.divider == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 			reg |= 0x08;	/* /3 divider required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 		if (to.mclk != 288000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 			reg |= 0x10;	/* which mclk pll is source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	case SM501_CLOCK_MCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	case SM501_CLOCK_M1XCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 		/* These clocks are the same and not further divided */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		sm501_freq = sm501_select_clock( req_freq, &to, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		reg=to.shift & 0x07;	/* bottom 3 bits are shift */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		if (to.divider == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 			reg |= 0x08;	/* /3 divider required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		if (to.mclk != 288000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 			reg |= 0x10;	/* which mclk pll is source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		return 0; /* this is bad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	mutex_lock(&sm->clock_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	mode = smc501_readl(sm->regs + SM501_POWER_MODE_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	gate = smc501_readl(sm->regs + SM501_CURRENT_GATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	clock = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	clock = clock & ~(0xFF << clksrc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	clock |= reg<<clksrc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	mode &= 3;	/* find current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	switch (mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		smc501_writel(gate, sm->regs + SM501_POWER_MODE_0_GATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		smc501_writel(clock, sm->regs + SM501_POWER_MODE_0_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		smc501_writel(gate, sm->regs + SM501_POWER_MODE_1_GATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		smc501_writel(clock, sm->regs + SM501_POWER_MODE_1_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		mode = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		mutex_unlock(&sm->clock_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	smc501_writel(mode, sm->regs + SM501_POWER_MODE_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	if (pll_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		smc501_writel(pll_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 				sm->regs + SM501_PROGRAMMABLE_PLL_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	sm501_sync_regs(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	dev_dbg(sm->dev, "gate %08lx, clock %08lx, mode %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		gate, clock, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	sm501_mdelay(sm, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	mutex_unlock(&sm->clock_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	sm501_dump_clk(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	return sm501_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) EXPORT_SYMBOL_GPL(sm501_set_clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) /* sm501_find_clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636)  * finds the closest available frequency for a given clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) unsigned long sm501_find_clock(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 			       int clksrc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 			       unsigned long req_freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	struct sm501_devdata *sm = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	unsigned long sm501_freq; /* the frequency achieveable by the 501 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	struct sm501_clock to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	switch (clksrc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	case SM501_CLOCK_P2XCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		if (sm->rev >= 0xC0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 			/* SM502 -> use the programmable PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 			sm501_freq = (sm501_calc_pll(2 * req_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 						     &to, 5) / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 			sm501_freq = (sm501_select_clock(2 * req_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 							 &to, 5) / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	case SM501_CLOCK_V2XCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		sm501_freq = (sm501_select_clock(2 * req_freq, &to, 3) / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	case SM501_CLOCK_MCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	case SM501_CLOCK_M1XCLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		sm501_freq = sm501_select_clock(req_freq, &to, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		sm501_freq = 0;		/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	return sm501_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) EXPORT_SYMBOL_GPL(sm501_find_clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) static struct sm501_device *to_sm_device(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	return container_of(pdev, struct sm501_device, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) /* sm501_device_release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684)  * A release function for the platform devices we create to allow us to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685)  * free any items we allocated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) static void sm501_device_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	kfree(to_sm_device(to_platform_device(dev)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) /* sm501_create_subdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695)  * Create a skeleton platform device with resources for passing to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696)  * sub-driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) static struct platform_device *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) sm501_create_subdev(struct sm501_devdata *sm, char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		    unsigned int res_count, unsigned int platform_data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	struct sm501_device *smdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	smdev = kzalloc(sizeof(struct sm501_device) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			(sizeof(struct resource) * res_count) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			platform_data_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	if (!smdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	smdev->pdev.dev.release = sm501_device_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	smdev->pdev.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	smdev->pdev.id = sm->pdev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	smdev->pdev.dev.parent = sm->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	smdev->pdev.dev.coherent_dma_mask = 0xffffffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	if (res_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		smdev->pdev.resource = (struct resource *)(smdev+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		smdev->pdev.num_resources = res_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	if (platform_data_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		smdev->pdev.dev.platform_data = (void *)(smdev+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	return &smdev->pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) /* sm501_register_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730)  * Register a platform device created with sm501_create_subdev()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) static int sm501_register_device(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 				 struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	struct sm501_device *smdev = to_sm_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	int ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	for (ptr = 0; ptr < pdev->num_resources; ptr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		printk(KERN_DEBUG "%s[%d] %pR\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		       pdev->name, ptr, &pdev->resource[ptr]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	ret = platform_device_register(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		dev_dbg(sm->dev, "registered %s\n", pdev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 		list_add_tail(&smdev->list, &sm->devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		dev_err(sm->dev, "error registering %s (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 			pdev->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) /* sm501_create_subio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759)  * Fill in an IO resource for a sub device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) static void sm501_create_subio(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 			       struct resource *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 			       resource_size_t offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 			       resource_size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	res->flags = IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	res->parent = sm->io_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	res->start = sm->io_res->start + offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	res->end = res->start + size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) /* sm501_create_mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775)  * Fill in an MEM resource for a sub device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) static void sm501_create_mem(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 			     struct resource *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			     resource_size_t *offs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 			     resource_size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	*offs -= size;		/* adjust memory size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	res->flags = IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	res->parent = sm->mem_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	res->start = sm->mem_res->start + *offs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	res->end = res->start + size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) /* sm501_create_irq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793)  * Fill in an IRQ resource for a sub device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) static void sm501_create_irq(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 			     struct resource *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	res->flags = IORESOURCE_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	res->parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	res->start = res->end = sm->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) static int sm501_register_usbhost(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 				  resource_size_t *mem_avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	pdev = sm501_create_subdev(sm, "sm501-usb", 3, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	if (!pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	sm501_create_subio(sm, &pdev->resource[0], 0x40000, 0x20000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	sm501_create_mem(sm, &pdev->resource[1], mem_avail, 256*1024);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	sm501_create_irq(sm, &pdev->resource[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	return sm501_register_device(sm, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) static void sm501_setup_uart_data(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 				  struct plat_serial8250_port *uart_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 				  unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	uart_data->membase = sm->regs + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	uart_data->mapbase = sm->io_res->start + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	uart_data->iotype = UPIO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	uart_data->irq = sm->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	uart_data->flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	uart_data->regshift = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	uart_data->uartclk = (9600 * 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) static int sm501_register_uart(struct sm501_devdata *sm, int devices)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	struct plat_serial8250_port *uart_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	pdev = sm501_create_subdev(sm, "serial8250", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 				   sizeof(struct plat_serial8250_port) * 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	if (!pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	uart_data = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	if (devices & SM501_USE_UART0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 		sm501_setup_uart_data(sm, uart_data++, 0x30000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		sm501_unit_power(sm->dev, SM501_GATE_UART0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		sm501_modify_reg(sm->dev, SM501_IRQ_MASK, 1 << 12, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		sm501_modify_reg(sm->dev, SM501_GPIO63_32_CONTROL, 0x01e0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	if (devices & SM501_USE_UART1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		sm501_setup_uart_data(sm, uart_data++, 0x30020);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 		sm501_unit_power(sm->dev, SM501_GATE_UART1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		sm501_modify_reg(sm->dev, SM501_IRQ_MASK, 1 << 13, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 		sm501_modify_reg(sm->dev, SM501_GPIO63_32_CONTROL, 0x1e00, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	pdev->id = PLAT8250_DEV_SM501;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	return sm501_register_device(sm, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) static int sm501_register_display(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 				  resource_size_t *mem_avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	pdev = sm501_create_subdev(sm, "sm501-fb", 4, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	if (!pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	sm501_create_subio(sm, &pdev->resource[0], 0x80000, 0x10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	sm501_create_subio(sm, &pdev->resource[1], 0x100000, 0x50000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	sm501_create_mem(sm, &pdev->resource[2], mem_avail, *mem_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	sm501_create_irq(sm, &pdev->resource[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	return sm501_register_device(sm, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) #ifdef CONFIG_MFD_SM501_GPIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) static inline struct sm501_devdata *sm501_gpio_to_dev(struct sm501_gpio *gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	return container_of(gpio, struct sm501_devdata, gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) static int sm501_gpio_get(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	struct sm501_gpio_chip *smgpio = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	unsigned long result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	result = smc501_readl(smgpio->regbase + SM501_GPIO_DATA_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	result >>= offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	return result & 1UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) static void sm501_gpio_ensure_gpio(struct sm501_gpio_chip *smchip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 				   unsigned long bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	unsigned long ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	/* check and modify if this pin is not set as gpio. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	if (smc501_readl(smchip->control) & bit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		dev_info(sm501_gpio_to_dev(smchip->ourgpio)->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 			 "changing mode of gpio, bit %08lx\n", bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		ctrl = smc501_readl(smchip->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 		ctrl &= ~bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		smc501_writel(ctrl, smchip->control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		sm501_sync_regs(sm501_gpio_to_dev(smchip->ourgpio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	struct sm501_gpio *smgpio = smchip->ourgpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	unsigned long bit = 1 << offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	void __iomem *regs = smchip->regbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	unsigned long save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	dev_dbg(sm501_gpio_to_dev(smgpio)->dev, "%s(%p,%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		__func__, chip, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	spin_lock_irqsave(&smgpio->lock, save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	val = smc501_readl(regs + SM501_GPIO_DATA_LOW) & ~bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		val |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	smc501_writel(val, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	sm501_sync_regs(sm501_gpio_to_dev(smgpio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	sm501_gpio_ensure_gpio(smchip, bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	spin_unlock_irqrestore(&smgpio->lock, save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	struct sm501_gpio *smgpio = smchip->ourgpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	void __iomem *regs = smchip->regbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	unsigned long bit = 1 << offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	unsigned long save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	unsigned long ddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	dev_dbg(sm501_gpio_to_dev(smgpio)->dev, "%s(%p,%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		__func__, chip, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	spin_lock_irqsave(&smgpio->lock, save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	smc501_writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	sm501_sync_regs(sm501_gpio_to_dev(smgpio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	sm501_gpio_ensure_gpio(smchip, bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	spin_unlock_irqrestore(&smgpio->lock, save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) static int sm501_gpio_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			     unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	struct sm501_gpio_chip *smchip = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	struct sm501_gpio *smgpio = smchip->ourgpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	unsigned long bit = 1 << offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	void __iomem *regs = smchip->regbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	unsigned long save;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	unsigned long ddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	dev_dbg(sm501_gpio_to_dev(smgpio)->dev, "%s(%p,%d,%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		__func__, chip, offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	spin_lock_irqsave(&smgpio->lock, save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	val = smc501_readl(regs + SM501_GPIO_DATA_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		val |= bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		val &= ~bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	smc501_writel(val, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	ddr = smc501_readl(regs + SM501_GPIO_DDR_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	smc501_writel(ddr | bit, regs + SM501_GPIO_DDR_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	sm501_sync_regs(sm501_gpio_to_dev(smgpio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	smc501_writel(val, regs + SM501_GPIO_DATA_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	sm501_sync_regs(sm501_gpio_to_dev(smgpio));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	spin_unlock_irqrestore(&smgpio->lock, save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) static const struct gpio_chip gpio_chip_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	.ngpio			= 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	.direction_input	= sm501_gpio_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	.direction_output	= sm501_gpio_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	.set			= sm501_gpio_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	.get			= sm501_gpio_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) static int sm501_gpio_register_chip(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 					      struct sm501_gpio *gpio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 					      struct sm501_gpio_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	struct sm501_platdata *pdata = sm->platdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	struct gpio_chip *gchip = &chip->gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	int base = pdata->gpio_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	chip->gpio = gpio_chip_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	if (chip == &gpio->high) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		if (base > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 			base += 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		chip->regbase = gpio->regs + SM501_GPIO_DATA_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 		chip->control = sm->regs + SM501_GPIO63_32_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		gchip->label  = "SM501-HIGH";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		chip->regbase = gpio->regs + SM501_GPIO_DATA_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		chip->control = sm->regs + SM501_GPIO31_0_CONTROL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 		gchip->label  = "SM501-LOW";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	gchip->base   = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	chip->ourgpio = gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	return gpiochip_add_data(gchip, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static int sm501_register_gpio(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	struct sm501_gpio *gpio = &sm->gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	resource_size_t iobase = sm->io_res->start + SM501_GPIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	dev_dbg(sm->dev, "registering gpio block %08llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 		(unsigned long long)iobase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	spin_lock_init(&gpio->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	gpio->regs_res = request_mem_region(iobase, 0x20, "sm501-gpio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	if (!gpio->regs_res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		dev_err(sm->dev, "gpio: failed to request region\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	gpio->regs = ioremap(iobase, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	if (!gpio->regs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		dev_err(sm->dev, "gpio: failed to remap registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		ret = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		goto err_claimed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	/* Register both our chips. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	ret = sm501_gpio_register_chip(sm, gpio, &gpio->low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		dev_err(sm->dev, "failed to add low chip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		goto err_mapped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	ret = sm501_gpio_register_chip(sm, gpio, &gpio->high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		dev_err(sm->dev, "failed to add high chip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		goto err_low_chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	gpio->registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)  err_low_chip:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	gpiochip_remove(&gpio->low.gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)  err_mapped:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	iounmap(gpio->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)  err_claimed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	release_mem_region(iobase, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) static void sm501_gpio_remove(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	struct sm501_gpio *gpio = &sm->gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	resource_size_t iobase = sm->io_res->start + SM501_GPIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	if (!sm->gpio.registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	gpiochip_remove(&gpio->low.gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	gpiochip_remove(&gpio->high.gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	iounmap(gpio->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	release_mem_region(iobase, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static inline int sm501_gpio_isregistered(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	return sm->gpio.registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) static inline int sm501_register_gpio(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) static inline void sm501_gpio_remove(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) static inline int sm501_gpio_isregistered(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) static int sm501_register_gpio_i2c_instance(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 					    struct sm501_platdata_gpio_i2c *iic)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	struct i2c_gpio_platform_data *icd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	struct gpiod_lookup_table *lookup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	pdev = sm501_create_subdev(sm, "i2c-gpio", 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 				   sizeof(struct i2c_gpio_platform_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	if (!pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	/* Create a gpiod lookup using gpiochip-local offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	lookup = devm_kzalloc(&pdev->dev, struct_size(lookup, table, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 			      GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	if (!lookup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	lookup->dev_id = "i2c-gpio";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	lookup->table[0] = (struct gpiod_lookup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		GPIO_LOOKUP_IDX(iic->pin_sda < 32 ? "SM501-LOW" : "SM501-HIGH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 				iic->pin_sda % 32, NULL, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 				GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	lookup->table[1] = (struct gpiod_lookup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		GPIO_LOOKUP_IDX(iic->pin_scl < 32 ? "SM501-LOW" : "SM501-HIGH",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 				iic->pin_scl % 32, NULL, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 				GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	gpiod_add_lookup_table(lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	icd = dev_get_platdata(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	icd->timeout = iic->timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	icd->udelay = iic->udelay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	/* note, we can't use either of the pin numbers, as the i2c-gpio
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	 * driver uses the platform.id field to generate the bus number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	 * to register with the i2c core; The i2c core doesn't have enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	 * entries to deal with anything we currently use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	pdev->id = iic->bus_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	dev_info(sm->dev, "registering i2c-%d: sda=%d, scl=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		 iic->bus_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		 iic->pin_sda, iic->pin_scl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	return sm501_register_device(sm, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) static int sm501_register_gpio_i2c(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 				   struct sm501_platdata *pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	struct sm501_platdata_gpio_i2c *iic = pdata->gpio_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	for (index = 0; index < pdata->gpio_i2c_nr; index++, iic++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		ret = sm501_register_gpio_i2c_instance(sm, iic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /* sm501_dbg_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)  * Debug attribute to attach to parent device to show core registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) static ssize_t sm501_dbg_regs(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 			      struct device_attribute *attr, char *buff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	struct sm501_devdata *sm = dev_get_drvdata(dev)	;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	unsigned int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	char *ptr = buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	for (reg = 0x00; reg < 0x70; reg += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		ret = sprintf(ptr, "%08x = %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 			      reg, smc501_readl(sm->regs + reg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		ptr += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 	return ptr - buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) static DEVICE_ATTR(dbg_regs, 0444, sm501_dbg_regs, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) /* sm501_init_reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)  * Helper function for the init code to setup a register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)  * clear the bits which are set in r->mask, and then set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)  * the bits set in r->set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static inline void sm501_init_reg(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 				  unsigned long reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 				  struct sm501_reg_init *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	tmp = smc501_readl(sm->regs + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	tmp &= ~r->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	tmp |= r->set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	smc501_writel(tmp, sm->regs + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) /* sm501_init_regs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)  * Setup core register values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) static void sm501_init_regs(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 			    struct sm501_initdata *init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 	sm501_misc_control(sm->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 			   init->misc_control.set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 			   init->misc_control.mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	sm501_init_reg(sm, SM501_MISC_TIMING, &init->misc_timing);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	sm501_init_reg(sm, SM501_GPIO31_0_CONTROL, &init->gpio_low);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	sm501_init_reg(sm, SM501_GPIO63_32_CONTROL, &init->gpio_high);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	if (init->m1xclk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		dev_info(sm->dev, "setting M1XCLK to %ld\n", init->m1xclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 		sm501_set_clock(sm->dev, SM501_CLOCK_M1XCLK, init->m1xclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	if (init->mclk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 		dev_info(sm->dev, "setting MCLK to %ld\n", init->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		sm501_set_clock(sm->dev, SM501_CLOCK_MCLK, init->mclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) /* Check the PLL sources for the M1CLK and M1XCLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)  * If the M1CLK and M1XCLKs are not sourced from the same PLL, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)  * there is a risk (see errata AB-5) that the SM501 will cease proper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)  * function. If this happens, then it is likely the SM501 will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)  * hang the system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) static int sm501_check_clocks(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	unsigned long pwrmode = smc501_readl(sm->regs + SM501_CURRENT_CLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	unsigned long msrc = (pwrmode & SM501_POWERMODE_M_SRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	unsigned long m1src = (pwrmode & SM501_POWERMODE_M1_SRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	return ((msrc == 0 && m1src != 0) || (msrc != 0 && m1src == 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) static unsigned int sm501_mem_local[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	[0]	= 4*1024*1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	[1]	= 8*1024*1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	[2]	= 16*1024*1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	[3]	= 32*1024*1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	[4]	= 64*1024*1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	[5]	= 2*1024*1024,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) /* sm501_init_dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)  * Common init code for an SM501
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static int sm501_init_dev(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	struct sm501_initdata *idata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	struct sm501_platdata *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	resource_size_t mem_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	unsigned long dramctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	unsigned long devid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	mutex_init(&sm->clock_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	spin_lock_init(&sm->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	INIT_LIST_HEAD(&sm->devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	devid = smc501_readl(sm->regs + SM501_DEVICEID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	if ((devid & SM501_DEVICEID_IDMASK) != SM501_DEVICEID_SM501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 		dev_err(sm->dev, "incorrect device id %08lx\n", devid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	/* disable irqs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	smc501_writel(0, sm->regs + SM501_IRQ_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	dramctrl = smc501_readl(sm->regs + SM501_DRAM_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	mem_avail = sm501_mem_local[(dramctrl >> 13) & 0x7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	dev_info(sm->dev, "SM501 At %p: Version %08lx, %ld Mb, IRQ %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 		 sm->regs, devid, (unsigned long)mem_avail >> 20, sm->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	sm->rev = devid & SM501_DEVICEID_REVMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	sm501_dump_gate(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	ret = device_create_file(sm->dev, &dev_attr_dbg_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 		dev_err(sm->dev, "failed to create debug regs file\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	sm501_dump_clk(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	/* check to see if we have some device initialisation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 	pdata = sm->platdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	idata = pdata ? pdata->init : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	if (idata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		sm501_init_regs(sm, idata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 		if (idata->devices & SM501_USE_USB_HOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 			sm501_register_usbhost(sm, &mem_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 		if (idata->devices & (SM501_USE_UART0 | SM501_USE_UART1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 			sm501_register_uart(sm, idata->devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 		if (idata->devices & SM501_USE_GPIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 			sm501_register_gpio(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	if (pdata && pdata->gpio_i2c && pdata->gpio_i2c_nr > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 		if (!sm501_gpio_isregistered(sm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 			dev_err(sm->dev, "no gpio available for i2c gpio.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 			sm501_register_gpio_i2c(sm, pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	ret = sm501_check_clocks(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 		dev_err(sm->dev, "M1X and M clocks sourced from different "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 					"PLLs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	/* always create a framebuffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	sm501_register_display(sm, &mem_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) static int sm501_plat_probe(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	struct sm501_devdata *sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	sm = kzalloc(sizeof(*sm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	if (!sm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 		goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	sm->dev = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	sm->pdev_id = dev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	sm->platdata = dev_get_platdata(&dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	ret = platform_get_irq(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 		goto err_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	sm->irq = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	if (!sm->io_res || !sm->mem_res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 		dev_err(&dev->dev, "failed to get IO resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 		ret = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 		goto err_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	sm->regs_claim = request_mem_region(sm->io_res->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 					    0x100, "sm501");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	if (!sm->regs_claim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		dev_err(&dev->dev, "cannot claim registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 		ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 		goto err_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	platform_set_drvdata(dev, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	sm->regs = ioremap(sm->io_res->start, resource_size(sm->io_res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 	if (!sm->regs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 		dev_err(&dev->dev, "cannot remap registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 		goto err_claim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	ret = sm501_init_dev(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 		goto err_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)  err_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	iounmap(sm->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)  err_claim:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	release_mem_region(sm->io_res->start, 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)  err_res:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 	kfree(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)  err1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) /* power management support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) static void sm501_set_power(struct sm501_devdata *sm, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 	struct sm501_platdata *pd = sm->platdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	if (!pd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	if (pd->get_power) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 		if (pd->get_power(sm->dev) == on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 			dev_dbg(sm->dev, "is already %d\n", on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	if (pd->set_power) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		dev_dbg(sm->dev, "setting power to %d\n", on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 		pd->set_power(sm->dev, on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 		sm501_mdelay(sm, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) static int sm501_plat_suspend(struct platform_device *pdev, pm_message_t state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	struct sm501_devdata *sm = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	sm->in_suspend = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	sm->pm_misc = smc501_readl(sm->regs + SM501_MISC_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	sm501_dump_regs(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	if (sm->platdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		if (sm->platdata->flags & SM501_FLAG_SUSPEND_OFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 			sm501_set_power(sm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) static int sm501_plat_resume(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	struct sm501_devdata *sm = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	sm501_set_power(sm, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	sm501_dump_regs(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	sm501_dump_gate(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	sm501_dump_clk(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	/* check to see if we are in the same state as when suspended */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	if (smc501_readl(sm->regs + SM501_MISC_CONTROL) != sm->pm_misc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 		dev_info(sm->dev, "SM501_MISC_CONTROL changed over sleep\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 		smc501_writel(sm->pm_misc, sm->regs + SM501_MISC_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 		/* our suspend causes the controller state to change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 		 * either by something attempting setup, power loss,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 		 * or an external reset event on power change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 		if (sm->platdata && sm->platdata->init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 			sm501_init_regs(sm, sm->platdata->init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	/* dump our state from resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	sm501_dump_regs(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	sm501_dump_clk(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	sm->in_suspend = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) #define sm501_plat_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) #define sm501_plat_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) /* Initialisation data for PCI devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) static struct sm501_initdata sm501_pci_initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	.gpio_high	= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 		.set	= 0x3F000000,		/* 24bit panel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 		.mask	= 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	.misc_timing	= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 		.set	= 0x010100,		/* SDRAM timing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		.mask	= 0x1F1F00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	.misc_control	= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 		.set	= SM501_MISC_PNL_24BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 		.mask	= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	.devices	= SM501_USE_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	/* Errata AB-3 says that 72MHz is the fastest available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	 * for 33MHZ PCI with proper bus-mastering operation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	.mclk		= 72 * MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	.m1xclk		= 144 * MHZ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) static struct sm501_platdata_fbsub sm501_pdata_fbsub = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	.flags		= (SM501FB_FLAG_USE_INIT_MODE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 			   SM501FB_FLAG_USE_HWCURSOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 			   SM501FB_FLAG_USE_HWACCEL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 			   SM501FB_FLAG_DISABLE_AT_EXIT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) static struct sm501_platdata_fb sm501_fb_pdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) 	.fb_route	= SM501_FB_OWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	.fb_crt		= &sm501_pdata_fbsub,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	.fb_pnl		= &sm501_pdata_fbsub,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) static struct sm501_platdata sm501_pci_platdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	.init		= &sm501_pci_initdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	.fb		= &sm501_fb_pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	.gpio_base	= -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) static int sm501_pci_probe(struct pci_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 				     const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 	struct sm501_devdata *sm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	sm = kzalloc(sizeof(*sm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	if (!sm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 		err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 		goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 	/* set a default set of platform data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) 	dev->dev.platform_data = sm->platdata = &sm501_pci_platdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	/* set a hopefully unique id for our child platform devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	sm->pdev_id = 32 + dev->devfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	pci_set_drvdata(dev, sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	err = pci_enable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 		dev_err(&dev->dev, "cannot enable device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 	sm->dev = &dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	sm->irq = dev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) #ifdef __BIG_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	/* if the system is big-endian, we most probably have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	 * translation in the IO layer making the PCI bus little endian
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	 * so make the framebuffer swapped pixels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	sm501_fb_pdata.flags |= SM501_FBPD_SWAP_FB_ENDIAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	/* check our resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	if (!(pci_resource_flags(dev, 0) & IORESOURCE_MEM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 		dev_err(&dev->dev, "region #0 is not memory?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 		goto err3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	if (!(pci_resource_flags(dev, 1) & IORESOURCE_MEM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 		dev_err(&dev->dev, "region #1 is not memory?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 		goto err3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	/* make our resources ready for sharing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	sm->io_res = &dev->resource[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	sm->mem_res = &dev->resource[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	sm->regs_claim = request_mem_region(sm->io_res->start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 					    0x100, "sm501");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 	if (!sm->regs_claim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 		dev_err(&dev->dev, "cannot claim registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 		err= -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 		goto err3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	sm->regs = pci_ioremap_bar(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) 	if (!sm->regs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 		dev_err(&dev->dev, "cannot remap registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 		err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 		goto err4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	sm501_init_dev(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)  err4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	release_mem_region(sm->io_res->start, 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)  err3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	pci_disable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)  err2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	kfree(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)  err1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) static void sm501_remove_sub(struct sm501_devdata *sm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 			     struct sm501_device *smdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 	list_del(&smdev->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	platform_device_unregister(&smdev->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) static void sm501_dev_remove(struct sm501_devdata *sm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	struct sm501_device *smdev, *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	list_for_each_entry_safe(smdev, tmp, &sm->devices, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 		sm501_remove_sub(sm, smdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	device_remove_file(sm->dev, &dev_attr_dbg_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 	sm501_gpio_remove(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) static void sm501_pci_remove(struct pci_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	struct sm501_devdata *sm = pci_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 	sm501_dev_remove(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	iounmap(sm->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	release_mem_region(sm->io_res->start, 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	pci_disable_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) static int sm501_plat_remove(struct platform_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	struct sm501_devdata *sm = platform_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	sm501_dev_remove(sm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	iounmap(sm->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	release_mem_region(sm->io_res->start, 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) static const struct pci_device_id sm501_pci_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 	{ 0x126f, 0x0501, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	{ 0, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) MODULE_DEVICE_TABLE(pci, sm501_pci_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) static struct pci_driver sm501_pci_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	.name		= "sm501",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	.id_table	= sm501_pci_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 	.probe		= sm501_pci_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 	.remove		= sm501_pci_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) MODULE_ALIAS("platform:sm501");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) static const struct of_device_id of_sm501_match_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	{ .compatible = "smi,sm501", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 	{ /* end */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) MODULE_DEVICE_TABLE(of, of_sm501_match_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) static struct platform_driver sm501_plat_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		.name	= "sm501",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 		.of_match_table = of_sm501_match_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	.probe		= sm501_plat_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	.remove		= sm501_plat_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 	.suspend	= sm501_plat_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	.resume		= sm501_plat_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) static int __init sm501_base_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	platform_driver_register(&sm501_plat_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	return pci_register_driver(&sm501_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) static void __exit sm501_base_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	platform_driver_unregister(&sm501_plat_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	pci_unregister_driver(&sm501_pci_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) module_init(sm501_base_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) module_exit(sm501_base_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) MODULE_DESCRIPTION("SM501 Core Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, Vincent Sanders");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) MODULE_LICENSE("GPL v2");