From: kogiidena <kog...@eg...> - 2007-03-17 01:23:47
|
Hi Paul-san and All I made the patch of landisk. (1)The push_switch framework was used. (2)landisk_pwc.c was divided into psw.c and gio.c. (3)pata_platform was supported in USL-5P. (4)irq.c was rewritten. (5)io.c was replaced with io_generic.c. (6)The IO address of PCI was changed in relation to (5). (7)To avoid the build error, the RTC code was deleted from setup.c. The RS5C313 code of Iwamatsu-san can be used. (8)LED(heartbeat) code was deleted from setup.c. driver/leds is used. Please delete io.c rtc.c landisk_pwb.c in arch/sh/board/landisk. kogiidena ----------------------------------------------- diff -urpN OLD/arch/sh/boards/landisk/Makefile NEW/arch/sh/boards/landisk/Makefile --- OLD/arch/sh/boards/landisk/Makefile 2007-03-16 09:20:01.000000000 +0900 +++ NEW/arch/sh/boards/landisk/Makefile 2007-03-17 09:09:29.000000000 +0900 @@ -2,4 +2,4 @@ # Makefile for I-O DATA DEVICE, INC. "LANDISK Series" # -obj-y := setup.o io.o irq.o rtc.o landisk_pwb.o +obj-y := setup.o irq.o psw.o gio.o diff -urpN OLD/arch/sh/boards/landisk/gio.c NEW/arch/sh/boards/landisk/gio.c --- OLD/arch/sh/boards/landisk/gio.c 1970-01-01 09:00:00.000000000 +0900 +++ NEW/arch/sh/boards/landisk/gio.c 2007-03-17 09:09:29.000000000 +0900 @@ -0,0 +1,167 @@ +/* + * arch/sh/boards/landisk/gio.c - driver for landisk + * + * This driver will also support the I-O DATA Device, Inc. LANDISK Board. + * LANDISK and USL-5P Button, LED and GIO driver drive function. + * + * Copylight (C) 2006 kogiidena + * Copylight (C) 2002 Atom Create Engineering Co., Ltd. * + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + */ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kdev_t.h> +#include <linux/cdev.h> +#include <linux/fs.h> +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/landisk/gio.h> +#include <asm/landisk/iodata_landisk.h> + +#define DEVCOUNT 4 +#define GIO_MINOR 2 /* GIO minor no. */ + +static dev_t dev; +static struct cdev *cdev_p; +static int openCnt; + +static int gio_open(struct inode *inode, struct file *filp) +{ + int minor; + + minor = MINOR(inode->i_rdev); + if (minor < DEVCOUNT) { + if (openCnt > 0) { + return -EALREADY; + } else { + openCnt++; + return 0; + } + } + return -ENOENT; +} + +static int gio_close(struct inode *inode, struct file *filp) +{ + int minor; + + minor = MINOR(inode->i_rdev); + if (minor < DEVCOUNT) { + openCnt--; + } + return 0; +} + +static int gio_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + unsigned int data; + static unsigned int addr = 0; + + if (cmd & 0x01) { /* write */ + if (copy_from_user(&data, (int *)arg, sizeof(int))) { + return -EFAULT; + } + } + + switch (cmd) { + case GIODRV_IOCSGIOSETADDR: /* addres set */ + addr = data; + break; + + case GIODRV_IOCSGIODATA1: /* write byte */ + ctrl_outb((unsigned char)(0x0ff & data), addr); + break; + + case GIODRV_IOCSGIODATA2: /* write word */ + if (addr & 0x01) { + return -EFAULT; + } + ctrl_outw((unsigned short int)(0x0ffff & data), addr); + break; + + case GIODRV_IOCSGIODATA4: /* write long */ + if (addr & 0x03) { + return -EFAULT; + } + ctrl_outl(data, addr); + break; + + case GIODRV_IOCGGIODATA1: /* read byte */ + data = ctrl_inb(addr); + break; + + case GIODRV_IOCGGIODATA2: /* read word */ + if (addr & 0x01) { + return -EFAULT; + } + data = ctrl_inw(addr); + break; + + case GIODRV_IOCGGIODATA4: /* read long */ + if (addr & 0x03) { + return -EFAULT; + } + data = ctrl_inl(addr); + break; + default: + return -EFAULT; + break; + } + + if ((cmd & 0x01) == 0) { /* read */ + if (copy_to_user((int *)arg, &data, sizeof(int))) { + return -EFAULT; + } + } + return 0; +} + +static struct file_operations gio_fops = { + .owner = THIS_MODULE, + .open = gio_open, /* open */ + .release = gio_close, /* release */ + .ioctl = gio_ioctl, /* ioctl */ +}; + +static int __init gio_init(void) +{ + int error; + + printk(KERN_INFO "gio: driver initialized\n"); + + openCnt = 0; + + if ((error = alloc_chrdev_region(&dev, 0, DEVCOUNT, "gio")) < 0) { + printk(KERN_ERR + "gio: Couldn't alloc_chrdev_region, error=%d\n", + error); + return 1; + } + + cdev_p = cdev_alloc(); + cdev_p->ops = &gio_fops; + error = cdev_add(cdev_p, dev, DEVCOUNT); + if (error) { + printk(KERN_ERR + "gio: Couldn't cdev_add, error=%d\n", error); + return 1; + } + + return 0; +} + +static void __exit gio_exit(void) +{ + cdev_del(cdev_p); + unregister_chrdev_region(dev, DEVCOUNT); +} + +module_init(gio_init); +module_exit(gio_exit); + +MODULE_LICENSE("GPL"); diff -urpN OLD/arch/sh/boards/landisk/irq.c NEW/arch/sh/boards/landisk/irq.c --- OLD/arch/sh/boards/landisk/irq.c 2007-03-16 09:20:01.000000000 +0900 +++ NEW/arch/sh/boards/landisk/irq.c 2007-03-17 09:09:29.000000000 +0900 @@ -1,18 +1,16 @@ /* * arch/sh/boards/landisk/irq.c * + * I-O DATA Device, Inc. LANDISK Support + * + * Copyright (C) 2005-2007 kogiidena + * * Copyright (C) 2001 Ian da Silva, Jeremy Siegel * Based largely on io_se.c. * - * I/O routine for I-O Data Device, Inc. LANDISK. - * - * Initial version only to support LAN access; some - * placeholder code from io_landisk.c left in with the - * expectation of later SuperIO and PCMCIA access. - */ -/* - * modified by kogiidena - * 2005.03.03 + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. */ #include <linux/init.h> #include <linux/irq.h> @@ -20,71 +18,27 @@ #include <linux/io.h> #include <asm/landisk/iodata_landisk.h> -static void enable_landisk_irq(unsigned int irq); -static void disable_landisk_irq(unsigned int irq); - -/* shutdown is same as "disable" */ -#define shutdown_landisk_irq disable_landisk_irq - -static void ack_landisk_irq(unsigned int irq); -static void end_landisk_irq(unsigned int irq); - -static unsigned int startup_landisk_irq(unsigned int irq) -{ - enable_landisk_irq(irq); - return 0; /* never anything pending */ -} - static void disable_landisk_irq(unsigned int irq) { - unsigned char val; unsigned char mask = 0xff ^ (0x01 << (irq - 5)); - /* Set the priority in IPR to 0 */ - val = ctrl_inb(PA_IMASK); - val &= mask; - ctrl_outb(val, PA_IMASK); + ctrl_outb(ctrl_inb(PA_IMASK) & mask, PA_IMASK); } static void enable_landisk_irq(unsigned int irq) { - unsigned char val; unsigned char value = (0x01 << (irq - 5)); - /* Set priority in IPR back to original value */ - val = ctrl_inb(PA_IMASK); - val |= value; - ctrl_outb(val, PA_IMASK); -} - -static void ack_landisk_irq(unsigned int irq) -{ - disable_landisk_irq(irq); -} - -static void end_landisk_irq(unsigned int irq) -{ - if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) - enable_landisk_irq(irq); + ctrl_outb(ctrl_inb(PA_IMASK) | value, PA_IMASK); } -static struct hw_interrupt_type landisk_irq_type = { - .typename = "LANDISK IRQ", - .startup = startup_landisk_irq, - .shutdown = shutdown_landisk_irq, - .enable = enable_landisk_irq, - .disable = disable_landisk_irq, - .ack = ack_landisk_irq, - .end = end_landisk_irq +static struct irq_chip landisk_irq_chip __read_mostly = { + .name = "LANDISK", + .mask = disable_landisk_irq, + .unmask = enable_landisk_irq, + .mask_ack = disable_landisk_irq, }; -static void make_landisk_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - irq_desc[irq].chip = &landisk_irq_type; - disable_landisk_irq(irq); -} - /* * Initialize IRQ setting */ @@ -92,6 +46,11 @@ void __init init_landisk_IRQ(void) { int i; - for (i = 5; i < 14; i++) - make_landisk_irq(i); + for (i = 5; i < 14; i++) { + disable_irq_nosync(i); + set_irq_chip_and_handler_name(i, &landisk_irq_chip, + handle_level_irq, "level"); + enable_landisk_irq(i); + } + ctrl_outb(0x00, PA_PWRINT_CLR); } diff -urpN OLD/arch/sh/boards/landisk/psw.c NEW/arch/sh/boards/landisk/psw.c --- OLD/arch/sh/boards/landisk/psw.c 1970-01-01 09:00:00.000000000 +0900 +++ NEW/arch/sh/boards/landisk/psw.c 2007-03-17 09:09:29.000000000 +0900 @@ -0,0 +1,145 @@ +/* + * arch/sh/boards/landisk/psw.c + * + * push switch support for LANDISK and USL-5P + * + * Copyright (C) 2006 Paul Mundt + * Copyright (C) 2007 Paul Mundt + * Copyright (C) 2007 kogiidena + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +#include <linux/io.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/platform_device.h> +#include <asm/landisk/iodata_landisk.h> +#include <asm/push-switch.h> + +static irqreturn_t psw_irq_handler(int irq, void *arg) +{ + struct platform_device *pdev = arg; + struct push_switch *psw = platform_get_drvdata(pdev); + struct push_switch_platform_info *psw_info = pdev->dev.platform_data; + unsigned int sw_value; + int ret = 0; + + sw_value = (0x0ff & (~ctrl_inb(PA_STATUS))); + + /* Nothing to do if there's no state change */ + if (psw->state) { + ret = 1; + goto out; + } + + /* Figure out who raised it */ + if (sw_value & (1 << psw_info->bit)) { + psw->state = 1; + mod_timer(&psw->debounce, jiffies + 50); + ret = 1; + } + + out: + /* Clear the switch IRQs */ + ctrl_outb(0x00, PA_PWRINT_CLR); + + return IRQ_RETVAL(ret); +} + +static struct resource psw_power_resources[] = { + [0] = { + .start = IRQ_POWER, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource psw_usl5p_resources[] = { + [0] = { + .start = IRQ_BUTTON, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct push_switch_platform_info psw_power_platform_data = { + .name = "psw_power", + .bit = 4, + .irq_flags = IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct push_switch_platform_info psw1_platform_data = { + .name = "psw1", + .bit = 0, + .irq_flags = IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct push_switch_platform_info psw2_platform_data = { + .name = "psw2", + .bit = 2, + .irq_flags = IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct push_switch_platform_info psw3_platform_data = { + .name = "psw3", + .bit = 1, + .irq_flags = IRQF_SHARED, + .irq_handler = psw_irq_handler, +}; + +static struct platform_device psw_power_switch_device = { + .name = "push-switch", + .id = 0, + .num_resources = ARRAY_SIZE(psw_power_resources), + .resource = psw_power_resources, + .dev = { + .platform_data = &psw_power_platform_data, + }, +}; + +static struct platform_device psw1_switch_device = { + .name = "push-switch", + .id = 1, + .num_resources = ARRAY_SIZE(psw_usl5p_resources), + .resource = psw_usl5p_resources, + .dev = { + .platform_data = &psw1_platform_data, + }, +}; + +static struct platform_device psw2_switch_device = { + .name = "push-switch", + .id = 2, + .num_resources = ARRAY_SIZE(psw_usl5p_resources), + .resource = psw_usl5p_resources, + .dev = { + .platform_data = &psw2_platform_data, + }, +}; + +static struct platform_device psw3_switch_device = { + .name = "push-switch", + .id = 3, + .num_resources = ARRAY_SIZE(psw_usl5p_resources), + .resource = psw_usl5p_resources, + .dev = { + .platform_data = &psw3_platform_data, + }, +}; + +static struct platform_device *psw_devices[] = { + &psw_power_switch_device, + &psw1_switch_device, + &psw2_switch_device, + &psw3_switch_device, +}; + +static int __init psw_init(void) +{ + return platform_add_devices(psw_devices, ARRAY_SIZE(psw_devices)); +} + +module_init(psw_init); diff -urpN OLD/arch/sh/boards/landisk/setup.c NEW/arch/sh/boards/landisk/setup.c --- OLD/arch/sh/boards/landisk/setup.c 2007-03-16 09:20:01.000000000 +0900 +++ NEW/arch/sh/boards/landisk/setup.c 2007-03-17 09:09:29.000000000 +0900 @@ -1,144 +1,96 @@ /* * arch/sh/boards/landisk/setup.c * - * Copyright (C) 2000 Kazumoto Kojima - * Copyright (C) 2002 Paul Mundt - * * I-O DATA Device, Inc. LANDISK Support. * - * Modified for LANDISK by - * Atom Create Engineering Co., Ltd. 2002. - * - * modifed by kogiidena - * 2005.09.16 + * Copyright (C) 2000 Kazumoto Kojima + * Copyright (C) 2002 Paul Mundt + * Copylight (C) 2002 Atom Create Engineering Co., Ltd. + * Copyright (C) 2005-2007 kogiidena * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ #include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/pata_platform.h> #include <linux/pm.h> #include <linux/mm.h> #include <asm/machvec.h> -#include <asm/rtc.h> #include <asm/landisk/iodata_landisk.h> #include <asm/io.h> -void landisk_time_init(void); void init_landisk_IRQ(void); -int landisk_ledparam; -int landisk_buzzerparam; -int landisk_arch; - -/* cycle the led's in the clasic knightrider/sun pattern */ -static void heartbeat_landisk(void) -{ - static unsigned int cnt = 0, blink = 0x00, period = 25; - volatile u8 *p = (volatile u8 *)PA_LED; - char data; - - if ((landisk_ledparam & 0x080) == 0) - return; - - cnt += 1; - - if (cnt < period) - return; - - cnt = 0; - blink++; - - data = (blink & 0x01) ? (landisk_ledparam >> 16) : 0; - data |= (blink & 0x02) ? (landisk_ledparam >> 8) : 0; - data |= landisk_ledparam; - - /* buzzer */ - if (landisk_buzzerparam & 0x1) { - data |= 0x80; - } else { - data &= 0x7f; - } - *p = data; - - if (((landisk_ledparam & 0x007f7f00) == 0) && - (landisk_buzzerparam == 0)) - landisk_ledparam &= (~0x0080); - - landisk_buzzerparam >>= 1; -} - static void landisk_power_off(void) { ctrl_outb(0x01, PA_SHUTDOWN); } -static void check_usl5p(void) -{ - volatile u8 *p = (volatile u8 *)PA_LED; - u8 tmp1, tmp2; +static struct resource cf_ide_resources[3]; - tmp1 = *p; - *p = 0x40; - tmp2 = *p; - *p = tmp1; - - landisk_arch = (tmp2 == 0x40); - if (landisk_arch == 1) { - /* arch == usl-5p */ - landisk_ledparam = 0x00000380; - landisk_ledparam |= (tmp1 & 0x07c); - } else { - /* arch == landisk */ - landisk_ledparam = 0x02000180; - landisk_ledparam |= 0x04; - } -} +static struct pata_platform_info pata_info = { + .ioport_shift = 1, +}; + +static struct platform_device cf_ide_device = { + .name = "pata_platform", + .id = -1, + .num_resources = ARRAY_SIZE(cf_ide_resources), + .resource = cf_ide_resources, + .dev = { + .platform_data = &pata_info, + }, +}; -void *area5_io_base; -void *area6_io_base; +static struct platform_device landisk_led_device = { + .name = "landisk-led", + .id = -1 +}; + +static struct platform_device *landisk_devices[] __initdata = { + &cf_ide_device, + &landisk_led_device, +}; -static int __init landisk_cf_init(void) +static int __init landisk_devices_setup(void) { pgprot_t prot; - unsigned long paddrbase, psize; + unsigned long paddrbase; + void *cf_ide_base; /* open I/O area window */ paddrbase = virt_to_phys((void *)PA_AREA5_IO); - psize = PAGE_SIZE; prot = PAGE_KERNEL_PCC(1, _PAGE_PCC_IO16); - area5_io_base = p3_ioremap(paddrbase, psize, prot.pgprot); - if (!area5_io_base) { + cf_ide_base = p3_ioremap(paddrbase, PAGE_SIZE, prot.pgprot); + if (!cf_ide_base) { printk("allocate_cf_area : can't open CF I/O window!\n"); return -ENOMEM; } - paddrbase = virt_to_phys((void *)PA_AREA6_IO); - psize = PAGE_SIZE; - prot = PAGE_KERNEL_PCC(0, _PAGE_PCC_IO16); - area6_io_base = p3_ioremap(paddrbase, psize, prot.pgprot); - if (!area6_io_base) { - printk("allocate_cf_area : can't open HDD I/O window!\n"); - return -ENOMEM; - } - - printk(KERN_INFO "Allocate Area5/6 success.\n"); - - /* XXX : do we need attribute and common-memory area also? */ + /* IDE cmd address : 0x1f0-0x1f7 and 0x3f6 */ + cf_ide_resources[0].start = (unsigned long)cf_ide_base + 0x40; + cf_ide_resources[0].end = (unsigned long)cf_ide_base + 0x40 + 0x0f; + cf_ide_resources[0].flags = IORESOURCE_IO; + cf_ide_resources[1].start = (unsigned long)cf_ide_base + 0x2c; + cf_ide_resources[1].end = (unsigned long)cf_ide_base + 0x2c + 0x03; + cf_ide_resources[1].flags = IORESOURCE_IO; + cf_ide_resources[2].start = IRQ_FATA; + cf_ide_resources[2].flags = IORESOURCE_IRQ; - return 0; + return platform_add_devices(landisk_devices, + ARRAY_SIZE(landisk_devices)); } +__initcall(landisk_devices_setup); + static void __init landisk_setup(char **cmdline_p) { - device_initcall(landisk_cf_init); - - landisk_buzzerparam = 0; - check_usl5p(); + /* LED ON */ + ctrl_outb(ctrl_inb(PA_LED) | 0x03, PA_LED); printk(KERN_INFO "I-O DATA DEVICE, INC. \"LANDISK Series\" support.\n"); - - board_time_init = landisk_time_init; pm_power_off = landisk_power_off; } @@ -148,29 +100,6 @@ static void __init landisk_setup(char ** struct sh_machine_vector mv_landisk __initmv = { .mv_name = "LANDISK", .mv_setup = landisk_setup, - .mv_nr_irqs = 72, - .mv_inb = landisk_inb, - .mv_inw = landisk_inw, - .mv_inl = landisk_inl, - .mv_outb = landisk_outb, - .mv_outw = landisk_outw, - .mv_outl = landisk_outl, - .mv_inb_p = landisk_inb_p, - .mv_inw_p = landisk_inw, - .mv_inl_p = landisk_inl, - .mv_outb_p = landisk_outb_p, - .mv_outw_p = landisk_outw, - .mv_outl_p = landisk_outl, - .mv_insb = landisk_insb, - .mv_insw = landisk_insw, - .mv_insl = landisk_insl, - .mv_outsb = landisk_outsb, - .mv_outsw = landisk_outsw, - .mv_outsl = landisk_outsl, - .mv_ioport_map = landisk_ioport_map, .mv_init_irq = init_landisk_IRQ, -#ifdef CONFIG_HEARTBEAT - .mv_heartbeat = heartbeat_landisk, -#endif }; ALIAS_MV(landisk) diff -urpN OLD/arch/sh/drivers/pci/ops-landisk.c NEW/arch/sh/drivers/pci/ops-landisk.c --- OLD/arch/sh/drivers/pci/ops-landisk.c 2007-03-16 09:20:01.000000000 +0900 +++ NEW/arch/sh/drivers/pci/ops-landisk.c 2007-03-17 09:09:29.000000000 +0900 @@ -17,8 +17,8 @@ static struct resource sh7751_io_resource = { .name = "SH7751 IO", - .start = 0x4000, - .end = 0x4000 + SH7751_PCI_IO_SIZE - 1, + .start = SH7751_PCI_IO_BASE, + .end = SH7751_PCI_IO_BASE + SH7751_PCI_IO_SIZE - 1, .flags = IORESOURCE_IO }; |