1 /* 2 * Support for OLPC XO-1 System Control Interrupts (SCI) 3 * 4 * Copyright (C) 2010 One Laptop per Child 5 * Copyright (C) 2006 Red Hat, Inc. 6 * Copyright (C) 2006 Advanced Micro Devices, Inc. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 */ 13 14 #include <linux/cs5535.h> 15 #include <linux/device.h> 16 #include <linux/gpio.h> 17 #include <linux/input.h> 18 #include <linux/interrupt.h> 19 #include <linux/platform_device.h> 20 #include <linux/pm.h> 21 #include <linux/mfd/core.h> 22 #include <linux/suspend.h> 23 #include <linux/workqueue.h> 24 25 #include <asm/io.h> 26 #include <asm/msr.h> 27 #include <asm/olpc.h> 28 29 #define DRV_NAME "olpc-xo1-sci" 30 #define PFX DRV_NAME ": " 31 32 static unsigned long acpi_base; 33 static struct input_dev *power_button_idev; 34 static struct input_dev *ebook_switch_idev; 35 36 static int sci_irq; 37 38 /* Report current ebook switch state through input layer */ 39 static void send_ebook_state(void) 40 { 41 unsigned char state; 42 43 if (olpc_ec_cmd(EC_READ_EB_MODE, NULL, 0, &state, 1)) { 44 pr_err(PFX "failed to get ebook state\n"); 45 return; 46 } 47 48 input_report_switch(ebook_switch_idev, SW_TABLET_MODE, state); 49 input_sync(ebook_switch_idev); 50 } 51 52 /* 53 * Process all items in the EC's SCI queue. 54 * 55 * This is handled in a workqueue because olpc_ec_cmd can be slow (and 56 * can even timeout). 57 * 58 * If propagate_events is false, the queue is drained without events being 59 * generated for the interrupts. 60 */ 61 static void process_sci_queue(bool propagate_events) 62 { 63 int r; 64 u16 data; 65 66 do { 67 r = olpc_ec_sci_query(&data); 68 if (r || !data) 69 break; 70 71 pr_debug(PFX "SCI 0x%x received\n", data); 72 73 if (data == EC_SCI_SRC_EBOOK && propagate_events) 74 send_ebook_state(); 75 } while (data); 76 77 if (r) 78 pr_err(PFX "Failed to clear SCI queue"); 79 } 80 81 static void process_sci_queue_work(struct work_struct *work) 82 { 83 process_sci_queue(true); 84 } 85 86 static DECLARE_WORK(sci_work, process_sci_queue_work); 87 88 static irqreturn_t xo1_sci_intr(int irq, void *dev_id) 89 { 90 struct platform_device *pdev = dev_id; 91 u32 sts; 92 u32 gpe; 93 94 sts = inl(acpi_base + CS5536_PM1_STS); 95 outl(sts | 0xffff, acpi_base + CS5536_PM1_STS); 96 97 gpe = inl(acpi_base + CS5536_PM_GPE0_STS); 98 outl(0xffffffff, acpi_base + CS5536_PM_GPE0_STS); 99 100 dev_dbg(&pdev->dev, "sts %x gpe %x\n", sts, gpe); 101 102 if (sts & CS5536_PWRBTN_FLAG && !(sts & CS5536_WAK_FLAG)) { 103 input_report_key(power_button_idev, KEY_POWER, 1); 104 input_sync(power_button_idev); 105 input_report_key(power_button_idev, KEY_POWER, 0); 106 input_sync(power_button_idev); 107 } 108 109 if (gpe & CS5536_GPIOM7_PME_FLAG) { /* EC GPIO */ 110 cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS); 111 schedule_work(&sci_work); 112 } 113 114 return IRQ_HANDLED; 115 } 116 117 static int xo1_sci_suspend(struct platform_device *pdev, pm_message_t state) 118 { 119 if (device_may_wakeup(&power_button_idev->dev)) 120 olpc_xo1_pm_wakeup_set(CS5536_PM_PWRBTN); 121 else 122 olpc_xo1_pm_wakeup_clear(CS5536_PM_PWRBTN); 123 124 if (device_may_wakeup(&ebook_switch_idev->dev)) 125 olpc_ec_wakeup_set(EC_SCI_SRC_EBOOK); 126 else 127 olpc_ec_wakeup_clear(EC_SCI_SRC_EBOOK); 128 129 return 0; 130 } 131 132 static int xo1_sci_resume(struct platform_device *pdev) 133 { 134 /* Enable all EC events */ 135 olpc_ec_mask_write(EC_SCI_SRC_ALL); 136 return 0; 137 } 138 139 static int __devinit setup_sci_interrupt(struct platform_device *pdev) 140 { 141 u32 lo, hi; 142 u32 sts; 143 int r; 144 145 rdmsr(0x51400020, lo, hi); 146 sci_irq = (lo >> 20) & 15; 147 148 if (sci_irq) { 149 dev_info(&pdev->dev, "SCI is mapped to IRQ %d\n", sci_irq); 150 } else { 151 /* Zero means masked */ 152 dev_info(&pdev->dev, "SCI unmapped. Mapping to IRQ 3\n"); 153 sci_irq = 3; 154 lo |= 0x00300000; 155 wrmsrl(0x51400020, lo); 156 } 157 158 /* Select level triggered in PIC */ 159 if (sci_irq < 8) { 160 lo = inb(CS5536_PIC_INT_SEL1); 161 lo |= 1 << sci_irq; 162 outb(lo, CS5536_PIC_INT_SEL1); 163 } else { 164 lo = inb(CS5536_PIC_INT_SEL2); 165 lo |= 1 << (sci_irq - 8); 166 outb(lo, CS5536_PIC_INT_SEL2); 167 } 168 169 /* Enable SCI from power button, and clear pending interrupts */ 170 sts = inl(acpi_base + CS5536_PM1_STS); 171 outl((CS5536_PM_PWRBTN << 16) | 0xffff, acpi_base + CS5536_PM1_STS); 172 173 r = request_irq(sci_irq, xo1_sci_intr, 0, DRV_NAME, pdev); 174 if (r) 175 dev_err(&pdev->dev, "can't request interrupt\n"); 176 177 return r; 178 } 179 180 static int __devinit setup_ec_sci(void) 181 { 182 int r; 183 184 r = gpio_request(OLPC_GPIO_ECSCI, "OLPC-ECSCI"); 185 if (r) 186 return r; 187 188 gpio_direction_input(OLPC_GPIO_ECSCI); 189 190 /* Clear pending EC SCI events */ 191 cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS); 192 cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_POSITIVE_EDGE_STS); 193 194 /* 195 * Enable EC SCI events, and map them to both a PME and the SCI 196 * interrupt. 197 * 198 * Ordinarily, in addition to functioning as GPIOs, Geode GPIOs can 199 * be mapped to regular interrupts *or* Geode-specific Power 200 * Management Events (PMEs) - events that bring the system out of 201 * suspend. In this case, we want both of those things - the system 202 * wakeup, *and* the ability to get an interrupt when an event occurs. 203 * 204 * To achieve this, we map the GPIO to a PME, and then we use one 205 * of the many generic knobs on the CS5535 PIC to additionally map the 206 * PME to the regular SCI interrupt line. 207 */ 208 cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_EVENTS_ENABLE); 209 210 /* Set the SCI to cause a PME event on group 7 */ 211 cs5535_gpio_setup_event(OLPC_GPIO_ECSCI, 7, 1); 212 213 /* And have group 7 also fire the SCI interrupt */ 214 cs5535_pic_unreqz_select_high(7, sci_irq); 215 216 return 0; 217 } 218 219 static void free_ec_sci(void) 220 { 221 gpio_free(OLPC_GPIO_ECSCI); 222 } 223 224 static int __devinit setup_power_button(struct platform_device *pdev) 225 { 226 int r; 227 228 power_button_idev = input_allocate_device(); 229 if (!power_button_idev) 230 return -ENOMEM; 231 232 power_button_idev->name = "Power Button"; 233 power_button_idev->phys = DRV_NAME "/input0"; 234 set_bit(EV_KEY, power_button_idev->evbit); 235 set_bit(KEY_POWER, power_button_idev->keybit); 236 237 power_button_idev->dev.parent = &pdev->dev; 238 device_init_wakeup(&power_button_idev->dev, 1); 239 240 r = input_register_device(power_button_idev); 241 if (r) { 242 dev_err(&pdev->dev, "failed to register power button: %d\n", r); 243 input_free_device(power_button_idev); 244 } 245 246 return r; 247 } 248 249 static void free_power_button(void) 250 { 251 input_unregister_device(power_button_idev); 252 input_free_device(power_button_idev); 253 } 254 255 static int __devinit setup_ebook_switch(struct platform_device *pdev) 256 { 257 int r; 258 259 ebook_switch_idev = input_allocate_device(); 260 if (!ebook_switch_idev) 261 return -ENOMEM; 262 263 ebook_switch_idev->name = "EBook Switch"; 264 ebook_switch_idev->phys = DRV_NAME "/input1"; 265 set_bit(EV_SW, ebook_switch_idev->evbit); 266 set_bit(SW_TABLET_MODE, ebook_switch_idev->swbit); 267 268 ebook_switch_idev->dev.parent = &pdev->dev; 269 device_set_wakeup_capable(&ebook_switch_idev->dev, true); 270 271 r = input_register_device(ebook_switch_idev); 272 if (r) { 273 dev_err(&pdev->dev, "failed to register ebook switch: %d\n", r); 274 input_free_device(ebook_switch_idev); 275 } 276 277 return r; 278 } 279 280 static void free_ebook_switch(void) 281 { 282 input_unregister_device(ebook_switch_idev); 283 input_free_device(ebook_switch_idev); 284 } 285 286 static int __devinit xo1_sci_probe(struct platform_device *pdev) 287 { 288 struct resource *res; 289 int r; 290 291 /* don't run on non-XOs */ 292 if (!machine_is_olpc()) 293 return -ENODEV; 294 295 r = mfd_cell_enable(pdev); 296 if (r) 297 return r; 298 299 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 300 if (!res) { 301 dev_err(&pdev->dev, "can't fetch device resource info\n"); 302 return -EIO; 303 } 304 acpi_base = res->start; 305 306 r = setup_power_button(pdev); 307 if (r) 308 return r; 309 310 r = setup_ebook_switch(pdev); 311 if (r) 312 goto err_ebook; 313 314 r = setup_ec_sci(); 315 if (r) 316 goto err_ecsci; 317 318 /* Enable PME generation for EC-generated events */ 319 outl(CS5536_GPIOM7_PME_EN, acpi_base + CS5536_PM_GPE0_EN); 320 321 /* Clear pending events */ 322 outl(0xffffffff, acpi_base + CS5536_PM_GPE0_STS); 323 process_sci_queue(false); 324 325 /* Initial sync */ 326 send_ebook_state(); 327 328 r = setup_sci_interrupt(pdev); 329 if (r) 330 goto err_sci; 331 332 /* Enable all EC events */ 333 olpc_ec_mask_write(EC_SCI_SRC_ALL); 334 335 return r; 336 337 err_sci: 338 free_ec_sci(); 339 err_ecsci: 340 free_ebook_switch(); 341 err_ebook: 342 free_power_button(); 343 return r; 344 } 345 346 static int __devexit xo1_sci_remove(struct platform_device *pdev) 347 { 348 mfd_cell_disable(pdev); 349 free_irq(sci_irq, pdev); 350 cancel_work_sync(&sci_work); 351 free_ec_sci(); 352 free_ebook_switch(); 353 free_power_button(); 354 acpi_base = 0; 355 return 0; 356 } 357 358 static struct platform_driver xo1_sci_driver = { 359 .driver = { 360 .name = "olpc-xo1-sci-acpi", 361 }, 362 .probe = xo1_sci_probe, 363 .remove = __devexit_p(xo1_sci_remove), 364 .suspend = xo1_sci_suspend, 365 .resume = xo1_sci_resume, 366 }; 367 368 static int __init xo1_sci_init(void) 369 { 370 return platform_driver_register(&xo1_sci_driver); 371 } 372 arch_initcall(xo1_sci_init); 373