)]}'
{
  "commit": "70aedd24d20e75198f5a0b11750faabbb56924e2",
  "tree": "8492641c61aa3af6f4dea421b8f628efe6fc92bd",
  "parents": [
    "b25c340c195447afb1860da580fe2a85a6b652c5"
  ],
  "author": {
    "name": "Thomas Gleixner",
    "email": "tglx@linutronix.de",
    "time": "Thu Aug 13 12:17:48 2009 +0200"
  },
  "committer": {
    "name": "Thomas Gleixner",
    "email": "tglx@linutronix.de",
    "time": "Mon Aug 17 10:54:05 2009 +0200"
  },
  "message": "genirq: Add buslock support\n\nSome interrupt chips are connected to a \"slow\" bus (i2c, spi ...). The\nbus access needs to sleep and therefor cannot be called in atomic\ncontexts.\n\nSome of the generic interrupt management functions like disable_irq(),\nenable_irq() ... call interrupt chip functions with the irq_desc-\u003elock\nheld and interrupts disabled. This does not work for such devices.\n\nProvide a separate synchronization mechanism for such interrupt\nchips. The irq_chip structure is extended by two optional functions\n(bus_lock and bus_sync_and_unlock).\n\nThe idea is to serialize the bus access for those operations in the\ncore code so that drivers which are behind that bus operated interrupt\ncontroller do not have to worry about it and just can use the normal\ninterfaces. To achieve this we add two function pointers to the\nirq_chip: bus_lock and bus_sync_unlock.\n\nbus_lock() is called to serialize access to the interrupt controller\nbus.\n\nNow the core code can issue chip-\u003emask/unmask ... commands without\nchanging the fast path code at all. The chip implementation merily\nstores that information in a chip private data structure and\nreturns. No bus interaction as these functions are called from atomic\ncontext.\n\nAfter that bus_sync_unlock() is called outside the atomic context. Now\nthe chip implementation issues the bus commands, waits for completion\nand unlocks the interrupt controller bus.\n\nThe irq_chip implementation as pseudo code:\n\nstruct irq_chip_data {\n       struct mutex   mutex;\n       unsigned int   irq_offset;\n       unsigned long  mask;\n       unsigned long  mask_status;\n}\n\nstatic void bus_lock(unsigned int irq)\n{\n        struct irq_chip_data *data \u003d get_irq_desc_chip_data(irq);\n\n        mutex_lock(\u0026data-\u003emutex);\n}\n\nstatic void mask(unsigned int irq)\n{\n        struct irq_chip_data *data \u003d get_irq_desc_chip_data(irq);\n\n        irq -\u003d data-\u003eirq_offset;\n        data-\u003emask |\u003d (1 \u003c\u003c irq);\n}\n\nstatic void unmask(unsigned int irq)\n{\n        struct irq_chip_data *data \u003d get_irq_desc_chip_data(irq);\n\n        irq -\u003d data-\u003eirq_offset;\n        data-\u003emask \u0026\u003d ~(1 \u003c\u003c irq);\n}\n\nstatic void bus_sync_unlock(unsigned int irq)\n{\n        struct irq_chip_data *data \u003d get_irq_desc_chip_data(irq);\n\n        if (data-\u003emask !\u003d data-\u003emask_status) {\n                do_bus_magic_to_set_mask(data-\u003emask);\n                data-\u003emask_status \u003d data-\u003emask;\n        }\n        mutex_unlock(\u0026data-\u003emutex);\n}\n\nThe device drivers can use request_threaded_irq, free_irq, disable_irq\nand enable_irq as usual with the only restriction that the calls need\nto come from non atomic context.\n\nSigned-off-by: Thomas Gleixner \u003ctglx@linutronix.de\u003e\nCc: Mark Brown \u003cbroonie@opensource.wolfsonmicro.com\u003e\nCc: Dmitry Torokhov \u003cdmitry.torokhov@gmail.com\u003e\nCc: Trilok Soni \u003csoni.trilok@gmail.com\u003e\nCc: Pavel Machek \u003cpavel@ucw.cz\u003e\nCc: Brian Swetland \u003cswetland@google.com\u003e\nCc: Joonyoung Shim \u003cjy0922.shim@samsung.com\u003e\nCc: m.szyprowski@samsung.com\nCc: t.fujak@samsung.com\nCc: kyungmin.park@samsung.com,\nCc: David Brownell \u003cdavid-b@pacbell.net\u003e\nCc: Daniel Ribeiro \u003cdrwyrm@gmail.com\u003e\nCc: arve@android.com\nCc: Barry Song \u003c21cnbao@gmail.com\u003e\n\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "5e7c6ee8c35c3ff8bb988692c8984ad940d9cb43",
      "old_mode": 33188,
      "old_path": "include/linux/irq.h",
      "new_id": "ce8171bc6fac48907f701bb9776de88b1fd609ff",
      "new_mode": 33188,
      "new_path": "include/linux/irq.h"
    },
    {
      "type": "modify",
      "old_id": "b08c0d24f2021b161b70bc95deb62ed589fc9714",
      "old_mode": 33188,
      "old_path": "kernel/irq/chip.c",
      "new_id": "f856330e684a0285010c3a94d74759c06e2a5670",
      "new_mode": 33188,
      "new_path": "kernel/irq/chip.c"
    },
    {
      "type": "modify",
      "old_id": "e70ed5592eb90e406c201e5d2881be679a5fc278",
      "old_mode": 33188,
      "old_path": "kernel/irq/internals.h",
      "new_id": "1b5d742c6a773943bc4679d35e2317c109540439",
      "new_mode": 33188,
      "new_path": "kernel/irq/internals.h"
    },
    {
      "type": "modify",
      "old_id": "d7f7b5fd2476436131d6df7724d22e7bbe94864b",
      "old_mode": 33188,
      "old_path": "kernel/irq/manage.c",
      "new_id": "0a3fd5b524c9a98e0e30491094f3f53b87ec25c5",
      "new_mode": 33188,
      "new_path": "kernel/irq/manage.c"
    }
  ]
}
